Skip to content

Latest commit

 

History

History
76 lines (65 loc) · 4.31 KB

File metadata and controls

76 lines (65 loc) · 4.31 KB

Protocol

ThreadKeeper implements MCP protocol version 2025-11-25 over stdio, authenticated loopback Streamable HTTP, and explicitly launched native-TLS OAuth Streamable HTTP. Stdio messages are newline-delimited JSON-RPC 2.0 and cannot contain embedded newlines. If a client requests an unsupported version, initialization returns the server's supported version for the client to accept or disconnect.

Supported methods are initialize, notifications/initialized, ping, tools/list, tools/call, resources/list, and resources/read. Calls other than ping and initialize are rejected until the initialized notification. Notifications never receive responses. Unknown methods, invalid envelopes, null IDs, unknown tools, invalid arguments, and pre-initialization calls have stable structured failures.

Tool validation has two layers: committed JSON Schema 2020-12 contracts and domain checks for cross-field/time/state invariants. Business failures are MCP tool results with isError: true; envelope and dispatch failures are JSON-RPC errors. Every successful tool returns both concise text and structuredContent. Discovery descriptions and MCP annotations identify read-only versus mutating, inherent idempotency, destructive capability, and open-world access.

Core resources are strictly limited to threadkeeper://today, threadkeeper://inbox, threadkeeper://memory/recent, and threadkeeper://system/status; optional V2A profiles also advertise threadkeeper://system/modules. Subscriptions, batching, and MCP tasks are not advertised. Streamable HTTP uses the official Go SDK for stateful MCP sessions, GET/SSE, POST, DELETE, cancellation, and version negotiation while delegating every tool call to the same validation/invocation/audit path as stdio.

threadkeeper http serve exposes exactly /mcp, /health/live, and /health/ready on an explicit loopback IP. /mcp requires the distinct bearer credential created by threadkeeper http init. Host, Origin, forwarded-header, content type, header/body, request-rate, concurrency, connection, idle-session, and shutdown boundaries are enforced; permissive CORS is never emitted.

threadkeeper remote serve exposes OAuth-protected /mcp plus separate /sync/changes, /sync/mutations, and /sync/snapshot APIs. Public RFC 9728 metadata is at /.well-known/oauth-protected-resource; live/readiness remain content-free. JWT issuer, signature, expiry, audience, exact resource, scopes, registered client/device, dormancy, and hash revocation are checked before an owner database is selected. Tool scope, module, namespace, and quota policy run before repository access.

The sync mutation envelope contains entityType, entityId, expectedVersion, toolName, arguments, a stable idempotencyKey, and an optional resolvesConflictId on the deliberate retry that resolves a conflict. The server derives the canonical target from the tool and arguments and rejects an envelope whose entity type or ID does not match, so a caller cannot bypass the expected-version check. The wrapper key is client-bound and authoritative; replay works even for tools whose public schema has no idempotency field. Conflicts return HTTP 409 with VERSION_CONFLICT, current version, and conflict ID. A stale cursor returns FULL_RESYNC_REQUIRED; the client then requests the export-scoped snapshot. The snapshot body and its X-ThreadKeeper-Change-Cursor response header come from one consistent read transaction; the client resumes /sync/changes after that cursor. Change entries contain safe metadata and tombstones, never raw entity content. Memory change records retain their authorization namespace, including deletion tombstones, and are filtered by current scope, module, and namespace grants.

The separate /admin/metrics route requires exact administrative scope and returns aggregate content-free operational counters. Administrative scope is not a wildcard for tools, resources, or snapshots.

Compatibility checks live in protocol and executable integration tests. Use the official Inspector with the built binary:

npx @modelcontextprotocol/inspector ./threadkeeper serve --time-zone UTC

Authenticated HTTP Inspector commands are documented in Setup, usage, and use cases. Remote topology and authorization are documented in Remote deployment.