Skip to main content

Module server

Module server 

Source
Expand description

Axum-based MCP daemon.

Endpoints:

  • POST /session — unauthenticated; mints { session_id, token, cwd }.
  • POST /mcp — authenticated JSON-RPC 2.0. Returns either plain JSON or an SSE stream depending on the method.
  • GET /health — simple liveness probe.

Session auth headers (required on POST /mcp):

  • Authorization: Bearer <token>
  • X-Construct-Session: <session_id>

POST /mcp dispatch:

  • initialize → plain JSON response with server info + capabilities.
  • tools/list → plain JSON response listing all advertised tools.
  • tools/call → SSE stream. First emits zero or more notifications/progress events (forwarded from the tool’s execute_with_progress), then one terminal JSON-RPC response event, then event: done.

Structs§

AppState
McpServerHandle
Handle returned by serve_on so tests can learn the bound port and shut the server down.

Functions§

build_router
Build the Axum router. Exposed for tests.
cleanup_discovery_file
Remove the MCP discovery file on shutdown. Safe to call when the file doesn’t exist.
default_state
Build an AppState with Construct’s baseline tool registry (no Config).
discovery_path
Absolute path of the MCP discovery file (~/.construct/mcp.json).
run_daemon
Legacy blocking entry point retained for tests that want to boot the MCP server with only a workspace directory (no gateway AppState).
serve_on
Bind to addr (use 127.0.0.1:0 for ephemeral) and serve the router. Returns once the server is listening. Writes no discovery file.
state_from_config
Build an AppState using a loaded Config so integrations with creds (Notion, Jira, Composio, Google Workspace, etc.) and the skills meta-tools get registered alongside the baseline.
state_from_runtime
Build an AppState using a loaded Config plus the gateway’s live RuntimeHandles. This is the full-registry entry point used by the in-process daemon boot.
state_with_tools
Extend an existing AppState with additional tools (used by tests).
write_discovery_file
Write the MCP discovery file atomically (tempfile + rename) so external readers never observe a half-written JSON document. Payload shape is {url, pid, started_at} — frozen by contract, do not change.