Neotoma
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| resources | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| retrieve_file_urlC | Retrieve a signed URL for accessing a file |
| retrieve_entity_snapshotB | Retrieve the current snapshot of an entity with provenance information. Supports historical snapshots via 'at' parameter. |
| list_observationsC | List all observations for a given entity |
| retrieve_field_provenanceC | Retrieve the provenance chain for a specific field in an entity snapshot |
| create_relationshipA | Create a typed relationship between two entities. relationship_type: PART_OF, CORRECTS, REFERS_TO, SETTLES, DUPLICATE_OF, DEPENDS_ON, SUPERSEDES, or EMBEDS. Use EMBEDS when a container entity (e.g. blog post, document) embeds an asset entity (e.g. image, attachment): source_entity_id = container, target_entity_id = asset. For images/files stored in Neotoma: store the file via store (get source_id), create an image/media entity with source_id, then create_relationship(EMBEDS, post_entity_id, image_entity_id). Optional metadata: caption, order. |
| create_relationshipsC | Create multiple typed relationships between existing entities in one batch |
| list_relationshipsA | List relationships for an entity, or discover the relationship type(s) between two specific entities. Filter by entity_id (with direction), or by source_entity_id and/or target_entity_id, and optionally relationship_type. To discover the type before delete_relationship, pass both source_entity_id and target_entity_id: each returned relationship carries its relationship_type. Soft-deleted relationships are excluded by default, so a deleted edge will not be re-offered for deletion; pass include_deleted: true to include them for audit. Paginated via limit/offset. |
| query_contacts_at_companyA | Answer "who do we have connected at company X": resolve company_name to the canonical company entity (exact-normalized match first, then a conservative fuzzy pass — the same resolution order used when a contact's organization field auto-links to a company at store time) and return every contact linked to it via a live works_at edge. Read-only: never creates a company entity — when no company matches, returns company: null and an empty contacts list. Optional owner_user_id scopes the search to a specific partner's network (must equal the authenticated user's id today; no cross-tenant admission yet); omit to search the authenticated user's own graph. |
| get_relationship_snapshotB | Get the current snapshot of a specific relationship with provenance |
| retrieve_entitiesA | Use this when you need filtered entity lists (by type, pagination, and optional published/date filters) or lexical/semantic retrieval via |
| list_timeline_eventsB | Query timeline events with filters (type, date range, source). Returns chronological events derived from date fields in sources. |
| retrieve_entity_by_identifierA | Retrieve entity by identifier (name, email, etc.) across entity types or specific type. Falls back to semantic search when keyword match returns no results. A literal entity_id (ent_) short-circuits to a direct primary-key lookup; if no entity has that id, the response carries a hint pointing to retrieve_entity_snapshot. |
| identify_entity_by_signalsA | Resolve an entity from a multi-signal bundle (name, email, company, domain, phone, and open-ended string props). Returns best_match with identity_score, resolution_band (high/medium/low/unresolved), ranked candidates, and matched_signals. Use when you have partial or combined identity information and want a single-call resolution with confidence scoring. |
| retrieve_related_entitiesB | Retrieve entities connected to a given entity via relationships. Supports n-hop traversal. |
| retrieve_graph_neighborhoodB | Retrieve complete graph neighborhood around a node (entity or source): related entities, relationships, sources, and events. |
| storeA | Unified storing for structured, file-backed, or combined payloads in one request. Choose path by source: file- or resource-sourced (attachment/file to preserve) → use file_content+mime_type or file_path; conversation- or tool-sourced (chat or other MCP) → use entities. You may send both entities and file input in the same call. File bytes create a content-addressed sources row (SHA-256 dedup per user); the response includes |
| parse_fileA | Parse local or base64-encoded files into agent-readable text and first-page PDF images without storing anything. Use before store when you need to extract entities from a file. |
| correctB | Create high-priority correction observation to override AI-extracted fields. Corrections always win in snapshot computation. |
| merge_entitiesB | Merge duplicate entities. Rewrites observations from source entity to target entity and marks source as merged. |
| split_entityA | R5 inverse of merge_entities. Re-points a predicate-selected subset of an entity's observations onto a new or pre-existing entity to repair over-merges (typically the pre-v1.2 heuristic name_key:title collapse on session-scoped types). Schema-agnostic predicate — supply any of observed_at_gte, source_id_in, or observation_field_equals. Observation content is never modified; only entity_id FK is re-bound. Idempotent via (user_id, idempotency_key) — reuse with a different predicate returns ERR_IDEMPOTENCY_MISMATCH. Typed relationships remain bound to the source; rebuild them with create_relationship. |
| list_potential_duplicatesA | List candidate duplicate entity pairs for an entity_type. Read-only fuzzy post-hoc detector; never auto-merges. Per-schema thresholds and fields come from the schema's duplicate_detection_threshold and duplicate_detection_fields; callers may override threshold per call. Confirm pairs with the user, then hand off to merge_entities. |
| delete_entityA | Delete an entity. Creates a deletion observation so the entity is excluded from snapshots and queries. Immutable and reversible for audit; use for user-initiated or GDPR-style removal from active use. |
| delete_relationshipA | Delete a relationship. Requires the exact relationship_type between the two entities; if unknown, call list_relationships with source_entity_id and target_entity_id first to discover it. Creates a deletion observation so the relationship is excluded from snapshots and queries. Immutable and reversible for audit. Returns 404 with a discovery hint when no live relationship matches the supplied triple. |
| restore_entityA | Restore a deleted entity. Creates a restoration observation (priority 1001) that overrides the deletion. Entity becomes visible in snapshots and queries again. Immutable restoration for audit. |
| restore_relationshipA | Restore a deleted relationship. Creates a restoration observation (priority 1001) that overrides the deletion. Relationship becomes visible in snapshots and queries again. Immutable restoration for audit. |
| get_entity_type_countsA | Return canonical entity counts by entity_type for the authenticated user. Uses the same dashboard stats aggregation behind GET /stats and sorts results by count descending, then entity_type ascending. Use this when the user asks for counts by type, histograms, or sorted totals. This returns row counts, unlike list_entity_types where field_count is schema field width. |
| list_entity_typesA | List available entity types. Without keyword: returns a short summary (entity_type, schema_version, field_count) for all types. field_count here means schema field width, not stored entity row count. With keyword: returns full schema (field_names, field_summary) for matching types; pass summary: true to get summary only. Uses hybrid search when keyword is provided: keyword matching first, then vector semantic search. Use before storing structured data to determine the correct entity_type. |
| describe_entity_typeA | Return the full active schema for one entity_type: field_names, per-field type/required/description (field_summary), required_fields, schema_version, and the raw schema_definition. Call this before store when you know the entity_type but not its declared field shape, so the first store lands with zero unknown_fields and zero required_fields_missing warnings. Repair workflow: when a prior store or correct returned unknown_fields_count > 0 (or unknown_field: true), call describe_entity_type to see the declared fields, then re-store or correct the value into a declared field that fits; only add a new field (update_schema_incremental / register_schema, per the response hint) when no declared field fits. Read-only; no persistence side effects. Errors with InvalidParams when the entity_type has no active schema (use list_entity_types to discover types, or register_schema to create one). |
| analyze_schema_candidatesB | Analyze raw_fragments to identify fields that should be promoted to schema fields. Returns recommendations with confidence scores based on frequency and type consistency. |
| audit_undeclared_fragmentsA | Report the accumulated undeclared raw_fragments awaiting schema declaration — fields stored on observations but excluded from the entity snapshot because no active schema declares them. Read-only; declares nothing. Returns, per entity_type, the undeclared fragment_keys with occurrence and affected-entity counts and a schema_missing flag (true when the type has stranded fragments but no active schema), plus total_entity_types / total_undeclared_fields rollups, in deterministic order (occurrences desc, affected desc, key asc; types by total occurrences desc). Optional entity_type scopes the audit to one type. The aggregate counterpart to the per-store unknown_fields signal: use it to triage the backlog before drafting update_schema_incremental / register_schema work. |
| get_schema_recommendationsB | Get schema update recommendations for an entity type from raw_fragments analysis, agent suggestions, or inference. |
| update_schema_incrementalA | Incrementally update a schema by adding fields (fields_to_add — minor version bump), removing fields (fields_to_remove — major version bump; observation data preserved, snapshot-excluded until re-added), or changing the identity rule (canonical_name_fields — major version bump). Creates a new schema version and activates it immediately, so all new data stored after this call uses the updated schema. Optionally migrates existing raw_fragments to observations for historical data backfill. canonical_name_fields re-keys how the type derives canonical_name / identity. Rules are ordered precedence with fallback — the first rule whose fields are all present wins, e.g. [{composite:["linkedin_url"]},"email","name"] keys on linkedin_url, else email, else name. Reach for it when same-name-different-entity collisions appear (e.g. a bulk import collapses distinct people who share a name because identity resolves on name alone). The existing reducer_config is preserved automatically, so this is the safe way to re-key without a full register_schema re-supply. Applies to NEW writes only — it does not retroactively re-key existing entities, so it will not by itself merge existing duplicates. Omit to keep the current rule; pass [] to clear it (succeeds only if the schema also declares identity_opt_out). The response echoes the resolved canonical_name_fields; call describe_entity_type first to see the current rule before replacing it. |
| register_schemaB | Register a new schema or schema version. Supports both global and user-specific schemas. |
| create_interpretationC | Create an interpretation row for an existing source from agent-extracted flat entities. Observations produced by this tool are linked to both source_id and interpretation_id. Use |
| list_interpretationsC | List interpretation runs for the authenticated user, optionally filtered by source_id. |
| get_authenticated_userA | Get the authenticated user ID for the current MCP session. Returns the user_id that is automatically used for all authenticated actions. |
| get_session_identityA | Resolve the current session's attribution: trust tier, AAuth / clientInfo fields, active anonymous-write policy, and whether the session is eligible for trusted writes. Safe to call as a preflight health check; does not write any rows. |
| health_check_snapshotsA | Check for stale entity snapshots (snapshots with observation_count=0 but observations exist). Returns health status and count of stale snapshots. |
| list_recent_changesA | List the most recently changed records across core Neotoma tables (entities, sources, observations, interpretations, relationships, timeline_events) for the authenticated user. Returns items ordered by latest activity_at. |
| submit_entityA | Generic submission for entity types with an active submission_config. Creates the primary row plus optional conversation thread and guest_access_token; use submit_issue for GitHub-backed issues. |
| add_entity_messageA | Append a follow-up conversation_message to the thread for a submitted root entity (entity_id). |
| get_entity_submission_statusA | JSON entity snapshot for a submitted entity_id; optional guest_access_token for token-scoped read-back. |
| list_entity_submissionsC | List recent entities of a given entity_type for the authenticated user. |
| sync_entity_submissionsA | Sync external mirrors for submissions (issue → GitHub sync; other types may no-op until providers are added). |
| submit_issueA | Submit an issue to the configured operator Neotoma instance; returns guest_access_token when accepted so callers can use token-scoped get_issue_status / add_issue_message read-back. No prior identity is required: a remote caller with no Bearer token, no AAuth signature and no guest token may submit whenever the operator instance's issue guest access policy permits guest writes — the token is an OUTPUT of the submit, not a precondition for it, so first contact needs no credential. Anonymity covers submission only; use the returned guest_access_token for add_issue_message and get_issue_status. Callers must provide at least one of reporter_git_sha or reporter_app_version. Deprecated alias: visibility 'advisory' is accepted as 'private' for one minor release and returns _deprecation: "visibility 'advisory' is deprecated; use 'private' instead." |
| add_issue_messageA | Append a message to an issue thread. Provide entity_id or issue_number (issue_number is an integer). Pass guest_access_token when the local issue snapshot does not already carry the operator token. If remote append fails after local/GitHub side effects, inspect remote_submission_error instead of retrying blindly. |
| get_issue_statusA | Return issue status and thread messages. Provide entity_id or issue_number (issue_number is an integer). Pass guest_access_token when token-scoped remote read-through is needed. |
| sync_issuesA | Bidirectional sync between local Neotoma and the configured GitHub repo. Push leg (default on): local public issues with no github_number are sanitized (PII stripped) and created on GitHub, then updated locally with the returned number/url. Pull leg: GitHub issues and their messages are pulled into local entities. Supports filtering by state, labels, and since date. |
| subscribeA | Create a substrate event subscription (webhook with HMAC delivery, or SSE via GET /events/stream). Requires at least one filter among entity_types, entity_ids, or event_types. Optional sync_peer_id skips webhook delivery when the substrate event carries the same source_peer_id (cross-instance loop prevention). |
| unsubscribeC | Deactivate a subscription by subscription_id. |
| list_subscriptionsA | List the current user's active subscriptions (webhook secrets omitted). |
| get_subscription_statusA | Return one subscription snapshot by subscription_id (webhook secret omitted). |
| add_peerC | Register a Neotoma peer (peer_config) for bidirectional sync: peer_url, entity_types allowlist, shared_secret for POST /sync/webhook verification. |
| remove_peerC | Deactivate a peer by peer_id. |
| list_peersA | List peer_config rows for the current user (secrets redacted). |
| get_peer_statusB | Fetch peer_config by peer_id plus remote_health (/health probe, semver compat vs this server). |
| sync_peerC | Bounded outbound peer sync: POST signed /sync/webhook for observations (requires NEOTOMA_PUBLIC_BASE_URL, NEOTOMA_LOCAL_PEER_ID, peer sync_target_user_id). Optional limit. |
| resolve_sync_conflictD | Stub; use correct on the entity for manual resolution today. |
| neotoma_turn_summaryA | FU-2026-05-002. Compute the per-turn Neotoma status line (msg N/M, stored K, retrieved L) plus an optional ui:// widget URI for ext-apps clients. Call at the end of every turn after the closing assistant store completes. Pass the assistant message's conversation_id and turn_key; the server resolves stored/retrieved/issue entities, turn ordinal, and total message count. Agents emit the returned status_line in the user-visible reply; ext-apps clients additionally render widget_uri inline when present. |
| npm_check_updateA | Check if a newer npm version is available. Returns updateAvailable, message, suggestedCommand, and when include_release_notes is true optional release_url, release_notes_excerpt, breaking_changes_excerpt, enrichment_error. When include_capability_delta is true, adds new_tools (tools added since currentVersion), removed_tools (tools removed since currentVersion), capability_delta_recommendation (upgrade guidance string), and capability_delta_note (present ONLY when delta computation degraded — e.g. unparseable versions or missing manifest — its absence signals no degradation). Call at session start to encourage user to upgrade. |
| publish_rendered_pageA | Turn a rendered_page into a ready-to-share guest URL in one call. Pass an existing rendered_page entity_id, or inline {title, html_body, custom_css} to create one. Mints a guest_access_token scoped to that page and returns the absolute …/entities//html?access_token= URL plus ttl_seconds. html_body is injected verbatim into a server template — no html/head/body wrappers. Each call mints a fresh token (tokens are hash-only at rest). |
| manage_bundlesA | Inspect and manage Neotoma bundles (the deliverable unit shipping schemas, record-type docs, and skills). action=list returns all bundles with type/version/enabled/always_active/provides count; action=info (with bundle) returns full manifest detail; action=install/enable/disable (with bundle) toggle persisted enable state. Default-install bundles (core, infrastructure, core_workflows) are always active and cannot be disabled. Disabling a schema bundle stops its types from auto-creating under guided/locked while preserving existing data. Returns structured JSON. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| All Entities | All entities regardless of type (0 total) |
| All Relationships | All relationships regardless of type (0 total) |
| Sources | All sources (0 total) |
| Timeline Widget | Embedded timeline widget for timeline event tool results. |
| Turn Summary Widget | Inline per-turn status card for neotoma_turn_summary results. |
| Entity Types | All available entity types (79 types) |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/markmhendrickson/neotoma'
If you have feedback or need assistance with the MCP directory API, please join our Discord server