Model Context Protocol (MCP) server

Neotoma exposes 30 MCP actions covering storage, retrieval, relationships, schema management, corrections, and lifecycle. MCP is the primary interface for agent workflows because it keeps deterministic state operations explicit: retrieve before reasoning, store with provenance, and create typed relationships.

Transport modes

  • stdio - local process, recommended for Cursor / Claude Code / Codex. The MCP client launches the Neotoma process directly.
  • HTTP (SSE) - remote or tunnel access via http://localhost:3080/mcp (dev) or http://localhost:3180/mcp (prod). Use with --tunnel for HTTPS via ngrok or Cloudflare.
  • WebSocket - bridge mode for clients that require WebSocket transport.

Client configuration

Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "neotoma-dev": {
      "command": "/absolute/path/to/neotoma/scripts/run_neotoma_mcp_stdio.sh"
    },
    "neotoma": {
      "command": "/absolute/path/to/neotoma/scripts/run_neotoma_mcp_stdio_prod.sh"
    }
  }
}

Claude Code (claude_desktop_config.json) and Windsurf (mcp_config.json) use the same structure. Run neotoma mcp check to scan for config files and auto-install missing entries. Add --user-level to include user-level paths.

HTTP / tunnel (remote access):

{
  "mcpServers": {
    "neotoma": {
      "url": "http://localhost:3080/mcp"
    }
  }
}

Authentication

All MCP actions operate under an authenticated user context. Authentication is handled via OAuth (recommended) or Bearer token. The user_id parameter is optional and inferred from the auth context. Run neotoma auth login for OAuth setup, or set NEOTOMA_BEARER_TOKEN for token-based auth.

Common action patterns

# 1) Retrieve target entities before writing
retrieve_entity_by_identifier(identifier="Ana Rivera", entity_type="contact")

# 2) Store conversation + message + extracted entities in one call
store_structured(
  entities=[
    { entity_type: "conversation", title: "Project sync" },
    { entity_type: "conversation_message", role: "user", sender_kind: "user", content: "...", turn_key: "conv:1" }
  ],
  relationships=[{ relationship_type: "PART_OF", source_index: 1, target_index: 0 }],
  idempotency_key="conversation-conv-1-1711900000000"
)

# 3) Link entities explicitly
create_relationship(
  relationship_type="REFERS_TO",
  source_entity_id="<message_id>",
  target_entity_id="<task_id>"
)

# 4) Store a file with entities in one combined call
store(
  entities=[...],
  file_path="/path/to/invoice.pdf",
  idempotency_key="store-invoice-1711900000000"
)

# 5) Parse a file without storing (agent-side extraction)
parse_file(file_path="/path/to/document.pdf")

Schema management workflow

Schemas evolve automatically. Fields not in the current schema are stored in raw_fragments. High-confidence fields are auto-promoted. Manual workflow:

  1. list_entity_types(keyword="invoice") - discover existing schemas
  2. analyze_schema_candidates(entity_type="invoice") - see what fields are candidates
  3. update_schema_incremental(entity_type="invoice", new_fields=[...]) - promote fields
ActionDescriptionParameters
get_authenticated_userGet or authenticate the current user.
retrieve_entitiesQuery entities with filters.filters, limit?, search?
retrieve_entity_snapshotGet an entity snapshot with provenance.entity_id, at?
list_observationsList observations for an entity or get field provenance.entity_id
retrieve_field_provenanceList observations for an entity or get field provenance.entity_id, field
list_relationshipsList relationships for an entity.entity_id
retrieve_entity_by_identifierSearch for an entity by identifier or semantic.identifier, entity_type?
retrieve_related_entitiesRetrieve related entities or the graph neighborhood.entity_id, relationship_types?, depth?
retrieve_graph_neighborhoodRetrieve related entities or the graph neighborhood.node_id, node_type
merge_entitiesMerge two entities.source_entity_id, target_entity_id
delete_entityDelete or restore an entity.entity_id
restore_entityDelete or restore an entity.entity_id
get_relationship_snapshotList relationships, get one by ID, or get a snapshot.relationship_key
create_relationshipCreate, delete, or restore a relationship.relationship_type, source_entity_id, target_entity_id
delete_relationshipCreate, delete, or restore a relationship.relationship_key
restore_relationshipCreate, delete, or restore a relationship.relationship_key
list_timeline_eventsList timeline events or get one by ID.type?, from?, to?
list_entity_typesList schema types or get a schema by entity type.keyword?
analyze_schema_candidatesAnalyze schema candidates, get recommendations, update incrementally, or register a schema.entity_type, entity_id?
get_schema_recommendationsAnalyze schema candidates, get recommendations, update incrementally, or register a schema.entity_type
update_schema_incrementalAnalyze schema candidates, get recommendations, update incrementally, or register a schema.entity_type, new_fields
register_schemaAnalyze schema candidates, get recommendations, update incrementally, or register a schema.schema
storeStore structured entities.entities, file_path?, idempotency_key?
store_structuredStore structured entities.entities, idempotency_key?, relationships?
store_unstructuredStore an unstructured file.file_path or file_content, mime_type
correctSubmit a correction or reinterpret a source.entity_id, field, value
health_check_snapshotsGet server stats, server info, or run health check snapshots.
retrieve_file_urlGet a signed file URL (internal).path
parse_fileParse a file into agent-readable text without storing.file_path or file_content+mime_type
npm_check_updateCheck for a newer npm package version.packageName?

Relationship types

Supported relationship types for create_relationship: PART_OF, CORRECTS, REFERS_TO, SETTLES, DUPLICATE_OF, DEPENDS_ON, SUPERSEDES, EMBEDS. Use EMBEDS when a container (blog post, document) embeds an asset (image, attachment): source = container, target = asset.

What the server exposes at its root

A running Neotoma binds a handful of unauthenticated discovery and health endpoints at the host root alongside the MCP transport itself. These exist so agents, proxies, and operators can identify and probe the deployment without credentials.

  • GET / - root landing. Content-negotiated: browsers get an HTML page with identity, harness-connect snippets (pre-filled with the actual host URL), and an index of neotoma.io documentation; send Accept: application/json for the same content as JSON, or Accept: text/markdown for a Markdown document. Default (no HTML/Markdown) is JSON. The content adapts to deployment mode: sandbox, personal tunnel, prod, or local.
  • GET /robots.txt - mirrors the deployment mode. Sandbox and local instances disallow crawling; personal and prod allow it and can link an external sitemap via NEOTOMA_PUBLIC_DOCS_URL.
  • GET /.well-known/mcp/server-card.json - MCP server card (name, version, capabilities).
  • GET /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource - OAuth discovery documents.
  • GET /server-info - runtime details (version, git sha, build timestamp).
  • GET /health - liveness probe.
  • GET /favicon.ico - site icon for browser tabs.
  • In sandbox mode: GET /sandbox/terms (acceptable-use JSON), POST /sandbox/report, and GET /sandbox/report/status.

See Connect a remote Neotoma for per-harness snippets, and Hosted Neotoma for the mode comparison.

Entity types

Common types agents can set directly: contact, person, company, task, invoice, transaction, receipt, note, contract, event, conversation, agent_message. Codebase types: feature_unit, release, agent_decision, agent_session, validation_result, codebase_entity, architectural_decision. Use list_entity_types to discover all available types or store with any descriptive type and the server infers the schema.

Continue with REST API reference, CLI reference, agent instructions, and schema management.