Docket Docs
Developer GuideArchitecture

MCP Servers

Model Context Protocol integration for Claude, Cursor, Windsurf, and other MCP clients.

MCP Servers

Docket will expose two Model Context Protocol (MCP) servers — one for the data plane and one for the control plane. This mirrors our HTTP architecture: users interact with data, operators interact with configuration.

Status: Planned for post-v0.2.0. Track progress on the roadmap.

Why MCP?

MCP lets Claude Desktop, Cursor, Windsurf, and any MCP-compatible client interact with Docket as a native tool. Instead of writing HTTP calls, users can:

  • Ask Claude "What did I photograph last week?" and Docket answers via the MCP data plane.
  • Tell Cursor "Ingest this PDF into my second brain" and the file is processed automatically.
  • Ask Windsurf "Show me the health of my adapters" and the MCP control plane returns live status.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    MCP CLIENTS                              │
│   (Claude Desktop, Cursor, Windsurf, VS Code, etc.)         │
└─────────────────────────┬───────────────────────────────────┘
                          │ stdio / SSE (MCP transport)

          ┌───────────────┴───────────────┐
          │                               │
          ▼                               ▼
┌─────────────────────┐       ┌─────────────────────┐
│  MCP Data Plane     │       │  MCP Control Plane  │
│  (mcp-data)         │       │  (mcp-control)      │
│                     │       │                     │
│  Tools exposed:     │       │  Tools exposed:     │
│  · docket_query     │       │  · docket_health    │
│  · docket_ingest    │       │  · docket_config    │
│  · docket_get       │       │  · docket_plugin_add│
│  · docket_create    │       │  · docket_plugin_rm │
│  · docket_update    │       │  · docket_rbac_list │
│  · docket_delete    │       │  · docket_rbac_set  │
│  · docket_relate    │       │                     │
│                     │       │  Resources exposed: │
│  Resources exposed: │       │  · config://current │
│  · memory://{id}    │       │  · plugin://list    │
│  · search://{q}     │       │  · metrics://prom   │
└─────────┬───────────┘       └─────────┬───────────┘
          │                             │
          │ wraps HTTP API              │ wraps HTTP API
          │                             │
          ▼                             ▼
┌─────────────────────────────────────────────────────────────┐
│                     DOCKET HTTP API                         │
│                                                             │
│   Data Plane (Port 3000)      Control Plane (Port 3001)     │
│   · POST /query               · GET  /admin/health          │
│   · POST /ingest              · POST /admin/plugins         │
│   · GET  /memories/:id        · GET  /admin/rbac/policies   │
│   · ...                       · ...                         │
└─────────────────────────────────────────────────────────────┘

MCP Data Plane (mcp-data)

For end users who want to query and manage their memories.

Tools

ToolPurposeMaps to
docket_queryNatural language searchPOST /query
docket_ingestIngest text or file pathPOST /ingest
docket_getRetrieve a memory by IDGET /memories/:id
docket_createCreate a memory directlyPOST /memories
docket_updateUpdate a memoryPATCH /memories/:id
docket_deleteDelete a memoryDELETE /memories/:id
docket_relateCreate a relation between memoriesPOST /memories/:id/relations

Resources

ResourcePurpose
memory://{id}Full memory record
search://{query}Search results for a query string

Example prompt flow

User: "What did I photograph last week?"

Claude → calls docket_query({
  question: "What did I photograph last week?",
  temporal: { dateFrom: "2026-05-03" }
})

Docket → returns {
  answer: "You photographed a red bicycle on a trail.",
  sources: [{ id: "mem_abc123", score: 0.94 }]
}

Claude → reads memory://mem_abc123 for details
Claude → responds to user with answer + source link

MCP Control Plane (mcp-control)

For operators and developers who manage the Docket instance.

Tools

ToolPurposeMaps to
docket_healthAggregated adapter healthGET /admin/health
docket_configView or reload runtime configGET/POST /admin/config
docket_plugin_addOnboard a new adapterPOST /admin/plugins
docket_plugin_rmDeregister an adapterDELETE /admin/plugins/:name
docket_rbac_listList access policiesGET /admin/rbac/policies
docket_rbac_setCreate or update a policyPOST /admin/rbac/policies

Resources

ResourcePurpose
config://currentResolved YAML config snapshot
plugin://listAll registered adapters with metadata
metrics://promPrometheus-compatible metrics text

Example prompt flow

User: "Register the Groq LLM adapter with my API key."

Claude → calls docket_plugin_add({
  packageName: "docket-llm-groq",
  config: { apiKey: "gsk_...", model: "llama3-70b-8192" }
})

Docket → validates package, initializes adapter, returns metadata
Claude → confirms: "Groq adapter registered. Capabilities: chat."

Why two MCP servers?

Same reasoning as our HTTP separation:

ConcernMCP Data PlaneMCP Control Plane
AudienceEnd usersOperators / developers
PermissionsRead/write own memoriesAdmin-only config changes
RiskLeaking a memoryInjecting a malicious adapter
DeploymentExposed to usersInternal / behind VPN

Most users only need mcp-data. Only admins who install plugins or debug adapters need mcp-control.

Implementation approach

MCP servers are thin wrappers around the existing HTTP API:

┌─────────────────────────────┐
│  MCP Request (JSON-RPC)     │
│  {                          │
│    "tool": "docket_query",  │
│    "args": { ... }          │
│  }                          │
└───────────┬─────────────────┘


┌─────────────────────────────┐
│  MCP Server Handler         │
│  · validate args            │
│  · map to HTTP call         │
│  · forward to Docket        │
└───────────┬─────────────────┘
            │ HTTP

┌─────────────────────────────┐
│  Docket Data/Control Plane  │
│  · process request          │
│  · return JSON              │
└───────────┬─────────────────┘


┌─────────────────────────────┐
│  MCP Response               │
│  { content: [{ text }] }    │
└─────────────────────────────┘

This means:

  • No new business logic in the MCP layer.
  • HTTP API is the source of truth — MCP just translates JSON-RPC to HTTP.
  • Easy to test — mock the HTTP client, test the MCP handlers in isolation.
  • Easy to add new tools — expose a new HTTP endpoint, add one mapping line in MCP.

Configuration

Users configure MCP servers in their client settings:

{
  "mcpServers": {
    "docket-data": {
      "command": "npx",
      "args": ["-y", "docket-mcp-data", "--baseUrl", "http://localhost:3000"]
    },
    "docket-control": {
      "command": "npx",
      "args": ["-y", "docket-mcp-control", "--baseUrl", "http://localhost:3001"]
    }
  }
}

Or via environment variables:

export DOCKET_DATA_URL=http://localhost:3000
export DOCKET_CONTROL_URL=http://localhost:3001
npx docket-mcp-data

Backlog placement

This work is scheduled for post-v0.2.0 after the core HTTP API and plugin ecosystem are stable. The dependency order is:

  1. ✅ HTTP data plane routes (/ingest, /query, /memories)
  2. ✅ HTTP control plane routes (/admin/*)
  3. 🔄 Plugin ecosystem stable (/admin/plugins)
  4. MCP wrappers (this page)

Once the HTTP contract is solid, adding MCP is roughly one day of work per plane — mostly argument mapping and client boilerplate.

On this page