Skip to content

Add MCP server endpoint at /mcp with JWT auth#75

Draft
zer0stars wants to merge 2 commits intomainfrom
feat/mcp-server
Draft

Add MCP server endpoint at /mcp with JWT auth#75
zer0stars wants to merge 2 commits intomainfrom
feat/mcp-server

Conversation

@zer0stars
Copy link
Copy Markdown
Member

Summary

  • Expose an MCP (Model Context Protocol) Streamable HTTP endpoint at /mcp so LLM agents can query fetch-api's GraphQL surface via the standard MCP transport.
  • /mcp reuses the same middleware chain as /query (PanicRecovery → Logger → RequestTimeout → CheckJWT → AddClaimHandler), so authorization + DID scoping are identical.
  • Five read queries are annotated with @mcpTool and surfaced via server-garage's mcpgen codegen: fetch_get_latest_index, fetch_list_indexes, fetch_get_latest_cloud_event, fetch_list_cloud_events, fetch_list_available_event_types.

Why draft

Depends on server-garage v0.1.0 (DIMO-Network/server-garage#31). Once that tag lands, this PR needs:

  • drop the replace github.com/DIMO-Network/server-garage => /Users/zer0stars/workspace/server-garage from go.mod
  • pin github.com/DIMO-Network/server-garage v0.1.0
  • go mod tidy

Notable changes

  • schema/mcp.graphqls — new: defines @mcpTool / @mcpExample / @mcpHide directives.
  • schema/base.graphqls — annotate read queries with @mcpTool.
  • internal/graph/mcp_tools_gen.go — generated by mcpgen; exports MCPTools + CondensedSchema.
  • internal/graph/resolver.go//go:generate runs mcpgen.
  • internal/app/app.go — builds MCPHandler using mcpserver.New(…, NewGQLGenExecutor(es), …) with the same auth chain; shares the gqlgen ExecutableSchema with /query.
  • cmd/fetch-api/main.gomux.Handle("/mcp", application.MCPHandler).
  • internal/graph/base.resolvers.go — implement new Raweventid resolver stub emitted after gqlgen bump (non-pointer Go field, nullable schema field).
  • gqlgen.ymlmcpTool / mcpExample marked skip_runtime.

Test plan

  • go build ./...
  • go test ./...
  • After SG v0.1.0 pin: go mod tidy clean; CI green (generate/lint/tests/install-tools)
  • Local smoke: POST /mcp tools/list returns 5 tools; tools/call fetch_get_latest_index with a valid vehicle JWT returns a CloudEventIndex; unauthenticated request returns 401
  • Post-deploy: hit https://fetch-api.dev.dimo.zone/mcp with tools/list

Expose an MCP (Model Context Protocol) Streamable HTTP endpoint that
lets LLM agents query fetch-api's GraphQL surface via the standard
MCP transport. Shares the same JWT + claim-injection middleware chain
as /query.

- schema/mcp.graphqls: @mcptool / @mcpExample / @mcpHide directives
- schema/base.graphqls: annotate the 5 read queries with @mcptool
- internal/graph/mcp_tools_gen.go: generated via server-garage mcpgen
- internal/app/app.go: build MCPHandler alongside GraphQL handler,
  share gqlgen.ExecutableSchema between the two
- cmd/fetch-api/main.go: mount /mcp on the HTTP mux
- go.mod: pull in modelcontextprotocol/go-sdk v1.4.1; bump gqlgen to
  match server-garage
gqlgen 0.17.89 auto-maps cloudevent.CloudEventHeader.RawEventID
(json:"raweventid") to the schema's nullable raweventid field, so
the custom CloudEventHeaderResolver stub is no longer needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant