Scope playground MCP surface to playground sources
Problem
Refactor the shared AI/MCP surface to accept an injected context for adapter registry, dashboard directory, base dir, and inspect cache path
Context
- The playground currently calls the shared MCP tool implementations through
dispatch_tool_call, but passes scope piecemeal as keyword args. - The MCP stdio server in
dataface/ai/mcp/server.pybuilds its own global/default view of dashboards and schema resources instead of accepting an injected source boundary. - The playground has a source boundary already in
get_adapter_registry(), but that boundary is not enforced uniformly across resources, schema context, and future MCP server usage. - Recent debugging showed schema-context/resource helpers could drift from the playground registry and fall back to cwd/defaults, which is exactly the leakage risk we want to remove.
Possible Solutions
- Recommended: Introduce a shared
DatafaceAIContextobject carryingadapter_registry,dashboards_directory,default_base_dir, andinspect_cache_path; make tool dispatch, schema context, and MCP server/resource handlers consume that object. This centralizes scoping and lets the playground create its own isolated context without adding another process. - Add a playground-only MCP server process with separate config. This could isolate runtime behavior, but it does not solve the core problem unless the server also accepts injected scope; otherwise it still risks default/global fallback paths.
- Keep the current structure and patch each helper separately. This is low-effort short term, but it preserves duplication and makes future regressions likely because scope remains implicit.
Plan
- Add a shared AI/MCP context type and helper constructors.
- Refactor
dispatch_tool_call, schema-context access, and MCP server/resource handlers to use the context object instead of loose kwargs/defaults. - Build a playground-scoped context from the playground adapter registry and examples directories; route chat/resource usage through it.
- Add tests proving scoped dispatch/resource behavior and keep the task worksheet updated.
Implementation Progress
- Started task and confirmed the current seam:
dispatch_tool_call,get_schema_context, andcreate_serverare the shared boundaries that need explicit scope injection. - Task creation via
just plan ...hit a local wrapper issue (sh: use: command not foundafter successful create), so CLI fallbacks are being used directly for task status and validation. - Added
dataface.ai.context.DatafaceAIContextas the shared scope object for adapter registry, dashboards directory, default base dir, and inspect cache path. - Refactored
dataface.ai.tools.dispatch_tool_call()to accept the shared context and apply it uniformly to render/query/catalog/search/review dispatch. - Refactored
dataface.ai.mcp.server.create_server()to accept an optional context and routed resource/tool handling through scoped helpers so MCP resources can be limited to a caller-specific boundary. - Added
get_playground_ai_context()and switched the playground AI/service prompt wiring to use that scoped context instead of passing loose directory/registry kwargs. - Verified the scoped resource path with the real playground context:
dataface://schema/contextnow returns playground example tables through the shared MCP layer. - Validation:
uv run pytest tests/core/test_mcp.py tests/core/test_ai_tools.py apps/playground/tests/test_mcp_tool_wiring.py apps/playground/tests/test_routes.py tests/ai/test_schema_context.py -q- Result: 82 passed
Review Feedback
-
Self-review only. No additional issues found after the focused test pass and runtime schema-context check.
-
[x] Review cleared