Entity Enricher ships an embedded Model Context Protocol server at /api/mcp — list your schemas, enrich an entity, inspect the result, and resolve a classification warning all from inside one Claude chat. No workflow editor required.
Different shape, different use case. The n8n and Make connectors wrap the API for workflow automation: triggers, scheduled runs, multi-step pipelines, persistent state. MCP wraps it for interactive chat: ad-hoc questions, exploratory enrichments, follow-up clarifications. Workflows are batch-shaped, chats are conversation-shaped — the surface differs and so does the UX.
The killer feature only MCP unlocks: interactive classification resume. When the pre-flight classifier rejects your entity (e.g. you asked to enrich "Titan" against a Planet schema, but Titan is a moon), n8n/Make have to auto-cancel because they're non-interactive. MCP surfaces the warning to Claude, Claude asks you to confirm, and on "yes" the tool re-runs without the classifier. No mid-pipeline failure, no re-running from scratch.
For claude.ai, Claude Code, Cursor, and any MCP client that supports the standard OAuth flow. No API key to create or paste — the client discovers the authorization server automatically.
https://entityenricher.ai/api/mcp/.For clients configured via a JSON file rather than an interactive sign-in (Claude Desktop, Continue, Zed).
ent_… value — it's only shown once.For Claude Desktop, edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"entityenricher": {
"url": "https://entityenricher.ai/api/mcp/",
"headers": { "X-API-Key": "ent_your_key_here" }
}
}
}Restart Claude Desktop. The same snippet works for Claude Code, Cursor, Continue, and Zed — any MCP-compatible client.
In a new chat: "List my Entity Enricher schemas, then enrich Sanofi against the pharmaceutical company schema using Claude Sonnet." Claude discovers the tools automatically, picks the right one, prompts you to confirm the model and schema choice, and streams the result inline.
54 tools cover the full enrichment, schema-authoring, database-sync and semantic-ID vocabulary surface. Behaviour is identical to the REST endpoints they wrap (same validation, billing, plan limits) — when the web UI gets a fix, MCP gets it too. Long-running work (batch enrichment, sample generation, benchmark runs) is asynchronous: the start tool returns a job_id, Claude polls get_job_status, and fetches the persisted outputs from your records once the job completes.
| Category | Tool | Description |
|---|---|---|
| Discovery | list_models | List model keys, nominal capabilities, auto-selected defaults, and your plan's profile_limits. Prefer auto selection: availability does not guarantee every provider quota or combined media/tool mode. |
| Schemas | list_schemas | List saved JSON schemas in your org, pinned first. |
| Schemas | get_schema | Fetch the full content of a schema by UUID. |
| Schemas | generate_sample | Generate 1..N editable sample contracts in one job (the first defines the field set; the rest are fast same-field instance variants) in knowledge mode (no attachments, optional web search) or source mode (attachments are authoritative and the planner may ask questions). Review consequential edits with the user before creating a schema. |
| Schemas | create_schema_from_sample | Generate and auto-save a schema from entity_samples (1..N samples of one entity type — union of fields, nullable where missing, real observed examples), a sample_record_id, or edited data plus its record-linked attachments. Semantic IDs are opt-in; suggestions are reviewed, never auto-applied. |
| Schemas | save_schema | Persist a schema Claude authored directly — no LLM call, no cost, validated server-side. |
| Schemas | update_schema | Rename, replace content, retag, pin, or toggle the ambiguity check on a saved schema without an LLM call. |
| Schemas | get_schema_part | Read a part of a schema without the full document: the named-type index, a $defs/$enums definition, an object subtree, or a single property card with its relations and flags. |
| Schemas | update_schema_property | Edit one property by path — rename, type or $ref, description, examples, flags — or remove it, with server-side validation; no full-content round-trip. |
| Schemas | add_schema_property | Add a scalar, nested object, or $ref property to the root, a nested object, or a $defs type. |
| Schemas | move_schema_property | Move one property into another container — the root, a nested object, or a $defs type — keeping its flags and expertise. |
| Schemas | publish_schema | Publish a linked schema's working copy as the contract enrichment and its database syncs run against. Structural edits only take effect here — and a freshly linked sync ships nothing until its schema's first publish. validate_only=true previews the migration diff. |
| Schemas | analyze_sample | Analyze sample JSON for property names that admit more than one reading in the context of their parent — or none at all — and for related items mixing entity facts with per-parent facts. Stateless report with the competing interpretations and suggested renames; nothing modified. |
| Schemas | analyze_schema | Run the ambiguity and identity-scoping checks on a saved schema and write per-property annotations — a rewritten description per ambiguous name, since a live schema cannot be renamed. Incremental by default, force=true re-analyzes all. |
| Schemas | delete_schema | Soft-delete a saved schema by UUID. |
| Enrichment | enrich_entity | Multi-model enrichment with optional auto-fusion. Accepts an optional attachment_ids list. Classification mismatches return a non-error response so Claude can ask the user to confirm and retry. |
| Enrichment | start_batch_enrichment | Enrich any number of entities asynchronously — no fixed batch-size cap, bounded by your plan's live usage quota — full pipeline per entity with automatic fusion. Returns a job_id; results land in your records. |
| Enrichment | fetch_entities | Fetch a JSON array of entities from an external REST API server-side (bearer / api_key / basic auth) — pairs with batch enrichment. |
| Enrichment | retry_expertises | Re-run only the failed expertise domains of a record, merging recovered values back — no re-payment for what already succeeded. |
| Enrichment | merge_records | Merge 2+ existing records into one fused result — rule-based or with an LLM arbitration model. |
| Jobs | get_job_status | Poll asynchronous jobs for progress, results, failures, and clarification questions. After an explicit-model compatibility failure, retry once with auto selection instead of cycling models. |
| Jobs | cancel_job | Cancel a pending, running, or paused job. |
| Jobs | answer_job_question | Answer a paused job's clarification questions and resume it — the interactive half of generate_sample. |
| Benchmarks | list_benchmark_scenarios | List your saved benchmark scenarios (reusable enrichment tests). |
| Benchmarks | get_benchmark_scenario | One scenario with its per-model scored results (quality / cost / speed). |
| Benchmarks | create_benchmark_scenario | Create a scenario: schema + fixed entity + strategy + scoring judge. Owner role + a plan with benchmarks required. |
| Benchmarks | update_benchmark_scenario | Update a scenario's test definition or scoring config; existing results are flagged stale. |
| Benchmarks | set_benchmark_reference | Save the gold reference output and mark it verified — required before a run. |
| Benchmarks | delete_benchmark_scenario | Delete a scenario and its results. |
| Benchmarks | run_benchmark | Run a scenario on an explicit model list, every active model of selected providers, or all active models — each result auto-scored against the reference. |
| Records | list_records | Page through enrichment, sample/schema generation, schema edit, playground, classification, arbitration, and ambiguity-analysis records, with success, model, job, and search filters. |
| Records | get_record | Full structured output + validation errors for one record. |
| Records | get_stats | Aggregated org statistics: totals, success rate, tokens, cost. |
| Attachments | upload_attachment | Upload a base64 file and return its attachment ID plus required model capability. Passing the ID to generate_sample activates source mode. |
| Attachments | delete_attachment | Delete an attachment by ID — a handy post-enrichment cleanup step. |
| Database Sync | list_database_syncs | List the database syncs registered on a saved schema, with pending delta counts and each sync's options. |
| Database Sync | create_database_sync | Connect a database to a saved schema, turning its enrichments into relational SQL deltas for your own PostgreSQL. The schema is linked unpublished and the database model is classified in the background — review it, then publish_schema starts the feed. |
| Database Sync | classify_database_model | Re-run the database-model classification after editing a linked schema: an LLM proposes each new or changed property's key, SQL type, index and ownership. The first pass runs by itself when the database is connected. |
| Database Sync | delete_database_sync | Delete a database sync and its queued deltas — your replica's tables are never touched. Optional teardown flags also drop the entity state and database model of schemas left with no database. |
| Database Sync | create_database_credential | (Re)issue the sync-client credential of a database sync — the pairing step of the ee-database workflow, returned with the install and pair commands. |
| Database Sync | fetch_database_deltas | Fetch the next FIFO window of SQL deltas for a database sync — claim=true leases it for acknowledged delivery, claim=false is a replayable read. |
| Database Sync | ack_database_deltas | Acknowledge applied deltas up to an id: releases the lease and applies the sync's purge options. |
| Database Sync | assign_sync_host | Assign (or clear) the sync host that provisions a database sync in managed mode — the host claims the credential, creates the physical database if missing and starts syncing, with no manual pairing. |
| Database Sync | list_entity_states | Browse a schema's current entity state — the deduplicated, last-write-wins rows the entity layer holds and every linked database mirrors, not the per-run records of list_records. |
| Database Sync | sync_records_to_database | Inject stored enrichment outputs into a schema's database sync — re-validated against the published contract, then passed through the admission gate. |
| Semantic IDs | list_semantic_concepts | Browse the org's concept vocabulary with its type facets — or, with view="duplicates", the concept pairs just below the resolution threshold. |
| Semantic IDs | get_semantic_concept | One concept in full: surface forms, identity source keys, linked records, and its nearest neighbors with similarities (only defined within its own concept-type and embedding-model slice). |
| Semantic IDs | probe_semantic_concept | Dry-run the resolution ladder for a text — what an enrichment would do with it — without creating anything. Probe before adding. |
| Semantic IDs | add_semantic_concept | Add a concept at usage 0, or with alias_of a new surface form of an existing one. Refused with the incumbent when the text is already covered at the threshold. |
| Semantic IDs | update_concept_alias | Remove a concept's surface form, or promote one to canonical. The last surface form is refused — deleting the concept is the delete flow's job. |
| Semantic IDs | import_semantic_concepts | Resolve up to 1000 identity texts through the enrichment ladder: a per-row report by default, minting the misses with mint=true (owner). |
| Semantic IDs | merge_semantic_concepts | Fold one concept into another. impact_only=true (default) reports the blast radius; the merge itself (owner) repoints aliases and entities and converges every linked database. |
| Semantic IDs | delete_semantic_concepts | Delete concepts by id, whole types, or unused-only. impact_only=true (default) reports counts and affected schemas/databases first; deleting self-heals but breaks convergence with stored ids. |
| Semantic IDs | migrate_semantic_embeddings | Status, collision preview, start, or cancel of the org's embedding-model migration — the only way to move existing concepts between embedding models. |
Omit attachment_ids. The model designs a reusable sample from its knowledge, and enable_web_search=true can ground external facts.
Pass attachment_ids. The planner treats the files as authoritative: it transcribes document values or describes only attributes visible in a photo. Fields and extra instructions cannot add unrelated external facts.
Whatever you pass as extra instructions is either honoured, or reported back as not honoured. Where a deterministic rule had to undo something you asked for — a shape the generator cannot emit, say — the finished job carries a warnings list saying so. Relay those to the user: a silently ignored instruction is how a sample ends up quietly wrong.
For a hybrid request such as identifying a car from a photo and researching its public appearances, call generate_sample twice: first in source mode with web search off, then without attachments using the confirmed identity and web search on. Combine the results in the conversation; Entity Enricher keeps separate records so source observations and researched facts retain distinct provenance.
Keep model=auto unless you explicitly need a model. Auto selection applies the task, attachment, and web-search requirements; an available model key can still encounter provider-specific quota or combined-tool restrictions.
Before schema generation, the client reviews entity scope, keys, types, cardinality, missing representative fields, and nested relationships. Consequential edits are grouped for your approval; factual values and structure are never changed silently.
For relational tables, master data, knowledge graphs, or reusable nested entities, the client asks whether to generate semantic IDs. They require an organization embedding model and add embedding cost, so they remain disabled by default.
Pass entity_data for a new or edited sample, or sample_record_id to reuse stored JSON and its linked attachments. Passing both uses the edited JSON while retaining the attachments. Explicit attachment_ids, including an empty list, overrides inheritance.
After generation, the client checks sample conformance, keys, annotations, expertise, relationships, and semantic-ID coverage. Structural suggestions require editing the sample and regenerating; annotation-only edits still require your approval. Nothing is auto-applied.
Resources let Claude browse data without burning a tool call — the LLM client treats them like files. Both resource types render as Markdown for cheap inline display.
| URI template | Description |
|---|---|
| enricher://schemas/{schema_id} | A saved schema rendered as Markdown — metadata header + the GeneratedJsonSchema as a fenced JSON block. |
| enricher://records/{record_id} | A past enrichment record rendered as Markdown — metadata + structured output + validation errors. |
When you ask enrich_entity to use a classification model and the entity doesn't match the schema type, the tool returns anon-error response with structured details. Claude reads it, surfaces the reasoning to you, and (on your confirmation) retries with force_after_classification_warning=true — which drops the classifier on the retry.
{
"success": false,
"error_code": "classification_warning",
"message": "Pre-flight classification rejected the entity. ...",
"classification": {
"status": "mismatch",
"reasoning": "Titan is a moon of Saturn, not a planet.",
"confidence": 0.97
},
"job_id": "..."
}n8n and Make auto-cancel on this state because they can't ask the user mid-pipeline. MCP can, and that single difference is why the connector exists.
The same interactivity powers a second flow: when generate_sample runs with source documents, its planner may pause with structural clarification questions. Claude relays them to you and resumes the job with answer_job_question — round after round, until the sample is generated.
Tool errors are projected into structured dicts with an error_code field so Claude can pattern-match instead of parsing free text. The HTTP layer maps cleanly: 402 → quota or credit error, 422 → classification warning, 504 → timeout, 502 → upstream LLM failure.
| error_code | When |
|---|---|
| invalid_request | Malformed UUID, mutually exclusive args (schema_id + target_schema), or request body validation failed. |
| prompt_limit_reached | Daily / weekly / monthly prompt quota exhausted (HTTP 402). Body includes period, limit, used, needed. |
| insufficient_credits | Org has billing enabled but credit balance is too low to start the job (HTTP 402). Body includes balance and a purchase URL. |
| model_limit_exceeded | Asked for more models than the plan allows (HTTP 402). Echoes limit + requested. |
| language_limit_exceeded | Asked for more languages than the plan allows (HTTP 402). |
| concurrent_job_limit_reached | Too many active enrichment jobs for this org. Wait or upgrade plan. |
| classification_warning | ⚡ Non-error: pre-flight classifier rejected the entity. Response carries the classification context so Claude can ask the user to confirm and retry with force_after_classification_warning=true. |
| benchmarks_not_in_plan | Benchmark tools require the owner role and a plan that includes Model Benchmarks (HTTP 403). |
| ambiguity_check_disabled | analyze_schema was called on a schema whose ambiguity check is toggled off (HTTP 400). Re-enable it via update_schema with ambiguity_check_enabled=true first. |
| enrichment_timeout | Job exceeded timeout_seconds. Suggest fewer models or splitting the entity. |
| schema_generation_timeout | Schema generation exceeded timeout_seconds. |
| schema_generation_failed | Upstream LLM error during schema generation (HTTP 502). |
| model_output_invalid | The model returned output that does not match the schema (HTTP 502). Body names the model, the offending property path, and retryable: true — call the tool again, or pick a stronger model. |
| cancelled | Job was cancelled mid-run (HTTP 499). |
| not_found | Schema or record ID does not exist in your org. |
| http_error | Catch-all for HTTP errors without a structured detail body. |
get_stats covers chat-side summaries; the full dashboards stay in the app.