<!--
  Full-page Markdown export (rendered HTML → GFM).
  Source: https://neotoma.io/bn/mcp
  Generated: 2026-04-26T19:09:37.888Z
-->
# 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

| Action | Description | Parameters |
| --- | --- | --- |
| get\_authenticated\_user | Get or authenticate the current user. | — |
| retrieve\_entities | Query entities with filters. | filters, limit?, search? |
| retrieve\_entity\_snapshot | Get an entity snapshot with provenance. | entity\_id, at? |
| list\_observations | List observations for an entity or get field provenance. | entity\_id |
| retrieve\_field\_provenance | List observations for an entity or get field provenance. | entity\_id, field |
| list\_relationships | List relationships for an entity. | entity\_id |
| retrieve\_entity\_by\_identifier | Search for an entity by identifier or semantic. | identifier, entity\_type? |
| retrieve\_related\_entities | Retrieve related entities or the graph neighborhood. | entity\_id, relationship\_types?, depth? |
| retrieve\_graph\_neighborhood | Retrieve related entities or the graph neighborhood. | node\_id, node\_type |
| merge\_entities | Merge two entities. | source\_entity\_id, target\_entity\_id |
| delete\_entity | Delete or restore an entity. | entity\_id |
| restore\_entity | Delete or restore an entity. | entity\_id |
| get\_relationship\_snapshot | List relationships, get one by ID, or get a snapshot. | relationship\_key |
| create\_relationship | Create, delete, or restore a relationship. | relationship\_type, source\_entity\_id, target\_entity\_id |
| delete\_relationship | Create, delete, or restore a relationship. | relationship\_key |
| restore\_relationship | Create, delete, or restore a relationship. | relationship\_key |
| list\_timeline\_events | List timeline events or get one by ID. | type?, from?, to? |
| list\_entity\_types | List schema types or get a schema by entity type. | keyword? |
| analyze\_schema\_candidates | Analyze schema candidates, get recommendations, update incrementally, or register a schema. | entity\_type, entity\_id? |
| get\_schema\_recommendations | Analyze schema candidates, get recommendations, update incrementally, or register a schema. | entity\_type |
| update\_schema\_incremental | Analyze schema candidates, get recommendations, update incrementally, or register a schema. | entity\_type, new\_fields |
| register\_schema | Analyze schema candidates, get recommendations, update incrementally, or register a schema. | schema |
| store | Store structured entities. | entities, file\_path?, idempotency\_key? |
| store\_structured | Store structured entities. | entities, idempotency\_key?, relationships? |
| store\_unstructured | Store an unstructured file. | file\_path or file\_content, mime\_type |
| correct | Submit a correction or reinterpret a source. | entity\_id, field, value |
| health\_check\_snapshots | Get server stats, server info, or run health check snapshots. | — |
| retrieve\_file\_url | Get a signed file URL (internal). | path |
| parse\_file | Parse a file into agent-readable text without storing. | file\_path or file\_content+mime\_type |
| npm\_check\_update | Check for a newer npm package version. | packageName? |

Scroll right

◆

## 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](/docs) 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](/connect) for per-harness snippets, and [Hosted Neotoma](/hosted) 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](/api), [CLI reference](/cli), [agent instructions](/agent-instructions), and [schema management](/schema-management).