MemoryNode MCP server
MemoryNode exposes two MCP surfaces:
- Hosted MCP — Streamable HTTP JSON-RPC served by the
memorynode-apiWorker atPOST /v1/mcpandPOST /mcp. Handler: apps/api/src/mcpHosted.ts. Tool registry: packages/mcp-core/. - stdio MCP — local binary
memorynode-mcp(@memorynodeai/mcp-server). Source: packages/mcp-server/src/index.ts. Server name in the MCP init handshake:memorynode-mcp; version matches the npm package version inpackages/mcp-server/package.json.
Both surfaces call the MemoryNode REST API; the hosted surface can short-circuit search and list_memories through hostedDirectSearch / hostedDirectListMemories to avoid HTTP hops.
Current product focus emphasizes workflow outcomes for SaaS personalization, AI companions, and creator tools. Hosted MCP tools remain broadly available, but connector/admin-adjacent and billing-management operations are not part of the default activation journey.
When to use REST vs MCP
| Use | Choose |
|---|---|
| Your app backend (Node, Python, edge Worker) | REST or @memorynodeai/sdk |
| Editors and agents (Cursor, Claude Desktop) | Hosted MCP URL or stdio memorynode-mcp |
| Production chat with strict schemas and retries | REST/SDK (transport: "rest" or default hybrid with REST fallback) |
MCP tools call the same API underneath; quotas and rate limits match REST.
1. Hosted MCP
1.1 Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/mcp, /mcp | JSON-RPC request (initialize / tools/list / tools/call) |
GET | /v1/mcp, /mcp | Browser landing or SSE subscription |
DELETE | /v1/mcp, /mcp | Close session |
Authentication uses the same API key as REST (Authorization: Bearer <key> or x-api-key). CORS is permissive for MCP paths; non-MCP routes still enforce ALLOWED_ORIGINS.
1.2 Session and cache TTLs
Constants live in apps/api/src/mcpHosted.ts:
- Session transport cache: in-memory
Map,MAX_SESSIONS = 2000,SESSION_TTL_MS = 60 60 1000(1 hour). LRU eviction drops the oldest 100 sessions when the cap is hit. - Session metadata registry:
MCP_SESSION_DODurable Object stores session TTL/touch metadata (workspace_id, key hash, defaults) as the source of truth for lifecycle checks. - Response cache (apps/api/src/mcpCache.ts):
maxSize: 400, per-tool TTL —recall: 15_000 ms,context: 8_000 ms.
1.3 Internal subrequest secret
When hosted MCP fans out to REST it sets x-internal-mcp: 1 and x-internal-secret: <MCP_INTERNAL_SECRET>. Only those subrequests skip duplicate edge rate limits. MCP_INTERNAL_SECRET must be set in every deployment that uses hosted MCP.
1.4 REST origin
resolveRestApiOrigin resolves the REST base:
MEMORYNODE_REST_ORIGINif set.- Else if the request hit
mcp.memorynode.ai, usehttps://api.memorynode.ai. - Else the request origin.
1.5 Tool catalog
Registered by registerAllHostedTools in packages/mcp-core/src/registry/registerAllTools.ts. Manifest version is exported as TOOL_MANIFEST_VERSION; policy version as MCP_POLICY_VERSION.
2.3.1 Policy version negotiation
The set of policy versions the server is prepared to speak is exported as SUPPORTED_MCP_POLICY_VERSIONS (newest-first) from @memorynodeai/shared. Clients may send x-mcp-policy-version as a single value or a comma-separated list on any hosted MCP request. The server picks the newest entry in SUPPORTED_MCP_POLICY_VERSIONS that also appears in the client list and stamps the result on the response header x-mcp-policy-version.
When no overlap exists the server falls back to the newest server-supported version (preserving the previous lock-step behaviour) and emits the warn-level event mcp_policy_version_negotiated with fell_back: true. Successful negotiations against an explicit client list emit the same event at info level. Together these events power the mcp_policy_version_compat dashboard and let us decide when to add a new supported version (or retire an old one — requires 30 days of zero traffic).
The negotiated value is purely a wire contract marker. Payload-level policy_version fields stamped inside tool results still use the server's newest version: those fields are a breadcrumb for forensic logs, not a contract marker.
| Tool | Group | Purpose |
|---|---|---|
recall | search | Hybrid vector + keyword search (bounded top_k ≤ 10). |
search | search | Alias of recall. |
memory_search | search | Lower-level search call (bounded). |
context | profile | Prompt-ready context pack. |
context_pack | profile | Alias of context. |
memory_context | profile | Same as context with extended schema. |
memory_insert | profile | Write a memory via profile engine. |
identity_get | profile | Return resolved scope identity. |
whoAmI / whoami | profile | Report session workspace + scope. |
memory | memory | Conversational memory multiplexer. |
memory_save | memory | Persist a memory. |
memory_forget | memory | Stage a forget request. |
memory_forget_confirm | memory | Confirm staged forget. |
memory_get | memory (p1 hosted) | Fetch by id. |
memory_list | memory (p1 hosted) | Paginated list. |
memory_delete | memory (p1 hosted) | Delete by id. |
memory_conversation_save | memory (p1 hosted) | Persist a conversation. |
ingest_dispatch | memory (p1 hosted) | Discriminated ingest (text / conversation / import). |
connector_settings_get | connectors | Available for all active plans. |
connector_settings_update | connectors | Same plan gate. |
usage_today | billing | Current-day usage snapshot. |
audit_log_list | billing | Available for all active plans. |
billing_get | billing | Current workspace_entitlements. |
billing_checkout_create | billing | Initiate PayU checkout. |
Every tool call flows through McpPolicyEngine (packages/shared/src/mcpPolicy.ts) which emits mcp_policy_before, mcp_policy_after, and mcp_tool_execution logs with policy version and session scope.
1.6 Rate limits and quotas
Every MCP call goes through the same rateLimit / rateLimitWorkspace pipeline as REST and consumes the per-route RPM defined by getRouteRateLimitMax. Quotas for search, context, memory, and ingest tools debit through reserve_usage_if_within_cap + commit_usage_reservation just like REST.
1.7 Errors
Hosted MCP returns JSON-RPC errors whose .data carries the same {code, message} envelope used by REST (see docs/external/API_USAGE.md §3). Non-RPC-level failures (auth, rate limit) return HTTP error responses before reaching JSON-RPC.
2. stdio MCP
2.1 Install and run
npm install -g @memorynodeai/mcp-server
memorynode-mcp
Configure your MCP-speaking client (Claude Desktop, Cursor, etc.) to launch the binary with the env vars below. Source: packages/mcp-server/src/index.ts.
2.2 Environment
| Variable | Required | Purpose |
|---|---|---|
MEMORYNODE_API_KEY | yes | Bearer key for REST calls. |
MEMORYNODE_BASE_URL | yes | REST API base URL (e.g. https://api.memorynode.ai, no trailing slash). The process exits if unset. |
MEMORYNODE_USER_ID | no | Default owner id for tool calls. |
MEMORYNODE_NAMESPACE | no | Default namespace. |
MEMORYNODE_TIMEOUT_MS | no | Per-request timeout. |
2.3 Tools
| Tool | Purpose |
|---|---|
recall | Hybrid search. |
context | Prompt-ready context pack. |
memory | Conversational memory multiplexer. |
whoAmI | Current scope / workspace. |
The stdio binary is a strict, documented subset of the hosted canonical catalog. The single source of truth for stdio tool names is STDIO_SUBSET_TOOL_NAMES in packages/mcp-core/src/adapters/stdio.ts; the stdio server gates registerTool through assertStdioToolNameAllowed. Billing, connector settings, and admin-adjacent tools remain hosted-only.
The legacy stdio aliases memory_search, memory_context, and memory_insert were removed from the stdio binary. The hosted Streamable MCP may still expose them as phased aliases via MCP_DEPRECATION_PHASE — prefer recall, context, and memory / memory_save in new configs.
3. Upstream constraints
top_kcapped at 10 forrecall/search.containerTagcapped at 128 chars; sanitized to[-a-zA-Z0-9_.:].- Policy engine may deny unsafe repetition (
loopConfidence) or forbidden scopes; hosted MCP returns the denial reason in the tool result. - All hosted MCP responses include
x-request-idheader for log correlation.