6 Commits
Author SHA1 Message Date
7adc935632 refactor(mcp): use discover_and_filter in main.py; add per-service manifests
- main.py: drops the hard-coded McpService class and MCP_SERVICES list.
  Lifespan now calls discover_and_filter() which does import + env
  filtering. Unset MCP_SERVICES reproduces today's behavior exactly.
- spark_executor/service.py: new file exporting SERVICE = McpService(
  name='spark_executor', app=spark_executor.app, mount_path='/spark-executor-mcp').
- files_mcp/service.py: new file exporting SERVICE = McpService(
  name='files', app=files_mcp.app, mount_path='/files-mcp').

The McpService dataclass itself moved to common/mcp_service.py in the
prior commit. 327 existing tests pass unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-30 11:13:23 +00:00
ClaudeandClaude Fable 5 c17a33152f feat(files-mcp): mount at /files-mcp via MCP_SERVICES registry
- main.py: import files_app, append McpService entry to MCP_SERVICES.
  Lifespan already iterates the list, so no edit to the lifespan function.
- tests/conftest.py: autouse fixture rebinds files_mcp.core.path_guard._ROOT
  to a per-test tmp_path so the sandbox is fresh for every test.
- files_mcp/__init__.py: drop the try/except around the server import now
  that server.py exists, restoring fail-fast on a missing/corrupt server
  module in production. The _init_root() try/except stays, since pytest
  collection can import the package before FILES_MCP_ROOT is set.

Verified via uv run pytest: 327 tests pass, no regressions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-30 18:15:45 +08:00
Claude a1710ec4db refactor(main): count MCP tools at INFO, per-tool details at DEBUG
Production log noise: every container start was emitting 14 INFO lines
listing every tool name and full description, which is dev-time
debugging info that doesn't belong in INFO.

Now:
  - INFO: one line per service with the count
    'MCP service \042spark_executor\042: 14 tool(s) registered'
  - DEBUG: per-tool name + description, prefixed with the service name
    so multi-service deploys are grep-friendly
    '  spark_executor._prepare_submit_job_prepare_submit_job_post  -  ...'

Operators can flip SPARK_EXECUTOR_LOG_LEVEL=INFO for production (no
per-tool spam) or DEBUG for dev (full inventory).

146/146 still pass. Live verified: at INFO level only the count line
shows; at DEBUG level both the count and per-tool lines show.
2026-06-25 13:05:55 +08:00
Claude 15e9a75bc7 refactor: make lifespan extensible for additional MCP services
The lifespan was hardcoded to mount just one MCP service
(spark_executor_app at /spark-executor-mcp). To add a second MCP
service, you'd have to edit the lifespan function body — error-prone
and not obvious where to add a new entry.

Refactor:
  - New McpService dataclass (name, app, mount_path)
  - MCP_SERVICES list at module top — adding a new service is one append
  - Lifespan iterates MCP_SERVICES; the per-service mount + tool-list
    logic is now a helper (_log_mcp_tools)
  - Tool-list log now prefixes the service name:
      'MCP tools registered (spark_executor, 14):'
    instead of just '(14):', so multi-service startups are unambiguous

116/116 still pass. Live verified: gunicorn 2-worker startup logs
each service with its tool list and the source app version.

Future services just need a McpService entry — no lifespan edit. The
MCP_SERVICES list has a docstring example showing the one-liner.
2026-06-25 12:33:14 +08:00
Claude ff9dea0ba7 feat: log MCP tool list + descriptions on startup
main.py lifespan now enumerates every MCP tool with its description at
startup so operators can see at a glance what the server exposes.

The auto-generated '### Responses:' suffix that fastapi-mcp appends to
each tool description is truncated before logging to keep the startup
log scannable.

Docstrings added to all 12 route handlers in server.py so the MCP tool
descriptions are meaningful (without them, fastapi-mcp would emit empty
descriptions). Each route now carries a summary + description used by
the auto-generated OpenAPI schema.
2026-06-24 17:50:30 +08:00
tao.chen b56d7c80dd init 2026-06-24 11:19:17 +08:00