# Entity Enricher [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/TOT-Concept/mcp-server-entity-enricher  
**GitHub Stars:** 0  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/entity-enricher

## Description
Multi-LLM entity enrichment: schemas, single/batch enrichment, fusion, model benchmarks.

## Claude Desktop Quick Installation
Remote MCP endpoint (confidence: high). Install path detected from listing signals. Add as a URL/SSE server in your client:

```json
"mcpServers": {
  "entity-enricher": {
    "url": "https://img.shields.io/badge/MCP-remote%20server-blue)](https://modelcontextprotocol.io"
  }
}
```

## Documentation & README

# Entity Enricher MCP Server

[![MCP](https://img.shields.io/badge/MCP-remote%20server-blue)](https://modelcontextprotocol.io)
[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-ai.entityenricher%2Fenricher-blue)](https://registry.modelcontextprotocol.io)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Website](https://img.shields.io/badge/entityenricher.ai-docs-orange)](https://entityenricher.ai/docs/integrations/mcp)

A **hosted, remote [Model Context Protocol](https://modelcontextprotocol.io) server** for
[Entity Enricher](https://entityenricher.ai) — structured knowledge extraction with multiple
LLM providers. Connect Claude Desktop, Claude Code, Cursor, claude.ai or any MCP-compatible
client and, from inside a chat:

- **Author JSON schemas** — generate a sample entity, turn it into a schema, refine it in natural language.
- **Enrich entities** — single or batch (up to 100), against your schemas, with any of your configured models.
- **Enrich multilingually** — schemas with localized text fields get per-language values in every language you request, in one pass.
- **Fuse multi-model results** — conflicts detected field-by-field, resolved by voting or LLM arbitration.
- **Benchmark models on your own data** — saved scenarios, gold references, auto-scored quality / cost / speed.
- **Ground enrichments in documents** — upload PDFs, images or audio and attach them to any flow.
- **Land it all in your own database** — as real, migrated relational tables, synced by a client you run.

No install, no local process: the server runs at `https://entityenricher.ai/api/mcp/`
(streamable HTTP). This repository holds the public documentation and ready-to-use client
configs; the server implementation lives in the Entity Enricher platform. (The one optional
local binary is the database sync client below — and only if you want the rows in a database of
your own.)

### Enrichments become a real database — yours

The enrichment is the easy half. What you normally end up building yourself — the tables to
hold the results, the DDL, the migration when the shape changes, and a loader that keeps it
consistent — is what a **database sync** does for you, and a chat is a good place to drive it:

- **A designed schema, not a JSON dump.** `create_database_sync` connects a database to a saved
  schema, and Entity Enricher derives the relational model from it: a table per entity type,
  `PRIMARY KEY`s, real `FOREIGN KEY`s, child tables for the parts an entity owns, junction
  tables for entities it merely references (one row many parents point at, not a copy per
  parent), typed columns, and indexes on what a list screen actually filters and sorts on. An
  LLM pass proposes each column's SQL contract — ask your client to read it back and fix what
  it got wrong (`classify_database_model`, `update_schema`) before anything ships.
- **Migrations you don't write.** `publish_schema` turns the working copy into the contract:
  the change is diffed against what each database has actually shipped and travels down the
  same feed as the data — additive DDL applied silently, riskier transforms (a re-key, a type
  change, a renamed column) held for your confirmation. No hand-written `ALTER`, no drift.
- **Synced by an open-source client you run.** `create_database_credential` issues the pairing
  token for [`ee-database`](https://github.com/TOT-Concept/ee-database) — an MIT-licensed Go
  binary that lives next to *your* PostgreSQL, MySQL or SQLite. It connects **outward** over
  WSS and **your connection string never leaves the machine**: Entity Enricher never holds a
  credential to your database. It bootstraps from a `.sql` snapshot, applies each leased batch
  transactionally, acknowledges it, and halts loudly on a failing delta rather than skipping
  it. Releases are **Sigstore-signed** and the installer verifies that signature against the
  publishing workflow's identity before the binary is ever executable.

```
  your schema ──┬──▶ relational model   tables, PK/FK, child + junction tables, indexes
                ├──▶ migrations         schema edits, diffed and shipped as DDL
                └──▶ rows               every enrichment, merged into current state
                             │
                             │  one ordered feed, leased and acknowledged
                             ▼
                    ee-database  ──  MIT-licensed, Sigstore-signed, outbound WSS only
                             │       (your DSN never leaves your machine)
                             ▼
              your PostgreSQL · MySQL · SQLite
```

A client that can run commands (Claude Code) carries the whole loop, install included; any
other client walks you through it and you paste one line into a terminal. No replica at all?
`list_entity_states` browses the same merged rows server-side, and `fetch_database_deltas` /
`ack_database_deltas` let a client apply the feed itself. Walkthrough:
[Database sync recipe](examples/recipes/database-sync.md).

Listed on the [official MCP Registry](https://registry.modelcontextprotocol.io) as
**`ai.entityenricher/enricher`** (see [server.json](server.json)).

## Quickstart

### Option 1 — OAuth (recommended)

For claude.ai, Claude Code, Cursor, and any MCP client that implements the standard OAuth
flow. **No API key to create or paste** — the client discovers the authorization server
automatically, your browser opens the Entity Enricher consent screen, and the connection acts
on your behalf with your own role. Revoke it anytime under **Settings → API Keys → Connected
Apps**.

<details open>
<summary><strong>Claude Code</strong></summary>

```bash
claude mcp add --transport http entity-enricher https://entityenricher.ai/api/mcp/
```

Then run `/mcp` in a session and pick **Authenticate** — your browser opens the consent page.
More options (project `.mcp.json`, API-key fallback): [examples/claude-code/](examples/claude-code/)
</details>

<details>
<summary><strong>claude.ai</strong></summary>

**Settings → Connectors → Add custom connector** with URL
`https://entityenricher.ai/api/mcp/`, then click **Authorize** on the consent screen.
Walkthrough: [examples/claude-ai-remote.md](examples/claude-ai-remote.md)
</details>

<details>
<summary><strong>Cursor / other OAuth-capable clients</strong></summary>

Register the URL with no headers and the client prompts you to sign in:
[examples/cursor/mcp.json](examples/cursor/mcp.json)
</details>

### Option 2 — API key (static JSON configuration)

For clients configured via a JSON file rather than an interactive sign-in (Claude Desktop,
Continue, Zed) — and for headless/CI use.

1. In the [Entity Enricher web UI](https://entityenricher.ai): **Settings → API Keys → New
   organization access key**. Pick a role — operator (read-mostly), editor (create/edit
   schemas), or owner (full control, required for benchmarks). Copy the `ent_…` value; it's
   only shown once.
2. For **Claude Desktop**, edit `~/Library/Application Support/Claude/claude_desktop_config.json`
   (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

   ```json
   {
     "mcpServers": {
       "entity-enricher": {
         "url": "https://entityenricher.ai/api/mcp/",
         "headers": { "X-API-Key": "ent_your_key_here" }
       }
     }
   }
   ```

   Restart Claude Desktop. Full file: [examples/claude-desktop/](examples/claude-desktop/)

### Try it

> List my Entity Enricher schemas, then enrich "Sanofi" against the pharmaceutical company
> schema in English and French.

Claude discovers the tools automatically, confirms the model and schema choice with you, and
returns the structured result inline.

## Examples & recipes

Client configs and copy-paste chat walkthroughs live in [examples/](examples/):

| Recipe | What it covers |
|---|---|
| [Schema from sample](examples/recipes/schema-from-sample.md) | generate a sample → schema → refine → first enrichment |
| [Database sync](examples/recipes/database-sync.md) | schema → designed tables → publish → pair `ee-database` → migrations |
| [Batch enrichment](examples/recipes/batch-enrichment.md) | entity lists, external APIs, async polling, partial-failure retry |
| [Model benchmark](examples/recipes/model-benchmark.md) | scenarios, gold references, auto-scored model comparison |

Per-client setup and examples: [Claude Code](examples/claude-code/) · [claude.ai](examples/claude-ai-remote.md) · [Claude Desktop](examples/claude-desktop/) · [Cursor](examples/cursor/mcp.json)

## Tools

<!-- TOOL_TABLE_START — generated by backend/scripts/generate_mcp_tool_table.py; do not edit by hand -->
**41 tools**, spanning the full schema-authoring and enrichment surface:

| Category | Tool | Description |
|---|---|---|
| Discovery | `list_models` | List the LLM models, languages, strategies, and (when the org has a plan with limits) the operational profile_limits available to the caller. |
| Schemas | `generate_sample` | Generate a realistic sample entity JSON from an entity-type description — the entry point of the schema-authoring loop. |
| Schemas | `list_schemas` | List saved JSON schemas in your organization, pinned ones first. |
| Schemas | `get_schema` | Fetch the full content of a saved schema by ID, including all properties, key fields, expertise domains, and validation rules. |
| Schemas | `create_schema_from_sample` | Generate and auto-save a JSON schema whose paths and types strictly follow an approved sample. |
| Schemas | `save_schema` | Persist a schema you authored directly (no LLM call, no cost) as a new saved schema. |
| Schemas | `update_schema` | Update a saved schema without an LLM call: rename, replace the schema_content, change tags, pin/unpin, or toggle non-determinism analysis. |
| Schemas | `publish_schema` | Publish a linked schema's working copy as its contract (publish model): enrichment and the linked database syncs follow the published content only, so structural edits (new… |
| Schemas | `delete_schema` | Soft-delete a saved schema by ID (restorable server-side shortly after; permanent deletion stays in the web UI). |
| Schemas | `analyze_sample_determinism` | Flag properties in a sample entity whose enriched value would DIFFER across models or reruns (non-deterministic names: temporal / ambiguous / subjective / multi-valued). |
| Schemas | `analyze_schema_determinism` | Analyze a saved schema and write a `non_determinism` flag onto each property whose enriched value is likely to vary across models/runs (badge in the editor). |
| Enrichment & fusion | `start_batch_enrichment` | Start an asynchronous batch enrichment against a JSON schema and return {job_id, total} immediately. |
| Enrichment & fusion | `fetch_entities` | Fetch a JSON array of entities from an external REST API (GET), server-side — the input step before start_batch_enrichment. |
| Enrichment & fusion | `enrich_entity` | Run a multi-model enrichment of a single entity against a JSON schema, returning the fused/best structured result. |
| Enrichment & fusion | `retry_expertises` | Re-run only the FAILED expertise domains of an existing multi-expertise enrichment record, merging the recovered values back into the record — no re-payment for the domains that… |
| Enrichment & fusion | `merge_records` | Merge 2+ enrichment records of the same entity into one fused result — the manual / re-run counterpart of the automatic fusion that follows a 2+ model enrich_entity or batch run. |
| Job control | `get_job_status` | Poll the status of an asynchronous LLM job — the middle step of every start → poll → fetch flow (start_batch_enrichment, generate_sample, run_benchmark, retry_expertises). |
| Job control | `cancel_job` | Cancel a pending, running, or paused LLM job started by start_batch_enrichment, generate_sample, run_benchmark, or retry_expertises. |
| Job control | `answer_job_question` | Answer the clarification questions of a paused job and resume it — the reply half of the interactive loop used by generate_sample's document-grounded planner (get_job_status… |
| Records & stats | `list_records` | List past enrichment records in your organization, most recent first. |
| Records & stats | `get_record` | Fetch a single enrichment record by ID, including the full structured output, validation errors, prompts/responses, and metrics. |
| Records & stats | `get_stats` | Aggregated statistics over your organization's enrichment records: totals, success rate, token usage, and cost summary. |
| Benchmarks | `list_benchmark_scenarios` | List the organization's benchmark scenarios (saved, reusable enrichment tests: schema + entity + strategy + scoring config). |
| Benchmarks | `get_benchmark_scenario` | Fetch one benchmark scenario with its per-model results (quality / cost / speed scores; results whose config_hash differs from the scenario's are stale — re-run those models). |
| Benchmarks | `create_benchmark_scenario` | Create a benchmark scenario — a reusable model test. |
| Benchmarks | `update_benchmark_scenario` | Update a benchmark scenario. |
| Benchmarks | `set_benchmark_reference` | Save a scenario's gold reference — the expected output each model result is scored against, and the gate between create_benchmark_scenario and run_benchmark. |
| Benchmarks | `delete_benchmark_scenario` | Delete a benchmark scenario and its results. |
| Benchmarks | `run_benchmark` | Launch a benchmark run — the final step of the benchmark lifecycle: execute the scenario's task (enrichment / sample generation / schema generation) with each selected model… |
| Attachments | `upload_attachment` | Upload a file (base64-encoded) so it can be used as source material in LLM flows. |
| Attachments | `delete_attachment` | Permanently remove an attachment from the server by id. |
| Database Sync | `list_database_syncs` | List the database syncs registered on a saved schema, with pending delta counts. |
| Database Sync | `list_entity_states` | Browse the current entity state of a schema — the deduplicated, non-null-wins merged rows the entity layer holds (and every linked database mirrors), NOT the per-run records of… |
| Database Sync | `create_database_sync` | Connect a database to a saved schema — the opt-in that turns enrichments into relational SQL deltas the user applies to their own PostgreSQL/MySQL/SQLite with the ee-database CLI… |
| Database Sync | `assign_sync_host` | Assign (or clear) the sync host that provisions a database sync in managed ee-database mode: the assigned host claims the credential, creates the physical database if missing and… |
| Database Sync | `classify_database_model` | Re-run the database-model classification pass on a saved schema: an LLM proposes each property's SQL contract — database_key (identity), indexed (list-screen search/filter/sort… |
| Database Sync | `delete_database_sync` | Delete a database sync and its queued deltas. |
| Database Sync | `create_database_credential` | (Re)issue the sync-client credential of a database sync — the pairing step of the ee-database CLI workflow. |
| Database Sync | `fetch_database_deltas` | Fetch the next FIFO window of SQL deltas for a database sync. |
| Database Sync | `ack_database_deltas` | Acknowledge applied database deltas up to an id: releases the lease and, per the database's options, purges delivered copies and fully-delivered entity state. |
| Database Sync | `sync_records_to_database` | Push already-stored enrichment output into the entity layer, so it reaches the schema's database sync. |
<!-- TOOL_TABLE_END -->

Tool behaviour is identical to the REST endpoints they wrap — same validation, billing and plan
limits as the web app. Write tools require the **editor** role; benchmark tools require
**owner** plus a plan that includes Model Benchmarks.

### Resources

Resources let the client *browse* data without a tool call — both render as Markdown.

| Resource | URI template |
|---|---|
| Saved schema | `enricher://schemas/{schema_id}` |
| Enrichment record | `enricher://records/{record_id}` |

## The async job pattern

MCP tools can't stream, so long-running work is split into **start → poll → fetch**:

1. A start tool (`start_batch_enrichment`, `generate_sample`, `run_benchmark`,
   `retry_expertises`) returns a `job_id` immediately.
2. `get_job_status(job_id)` polls progress; paused jobs carry clarification questions that
   `answer_job_question` resolves; `cancel_job` aborts.
3. Persisted outputs are fetched with `list_records(job_id=…)` (or the feature's own read
   tool, e.g. `get_benchmark_scenario`).

Jobs are held in a bounded in-memory manager — an unknown `job_id` means the job finished long
ago; go straight to the records.

## Interactive classification resume

The feature that only an interactive client unlocks. With a classification model enabled, a
pre-flight check verifies the entity matches the schema type. On a mismatch the tool returns a
**non-error** response instead of failing:

```json
{
  "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": "..."
}
```

Claude surfaces the reasoning, asks you to confirm, and retries with
`force_after_classification_warning=true`. Workflow connectors (n8n, Make) have to auto-cancel
here — a chat can just ask.

## Error codes

Errors are structured dicts with an `error_code` field the client can pattern-match on:

| `error_code` | When |
|---|---|
| `invalid_request` | Malformed UUID, mutually exclusive args, body validation failure. |
| `prompt_limit_reached` | Daily/weekly/monthly prompt quota exhausted (HTTP 402), with period + usage details. |
| `insufficient_credits` | Credit balance too low to start the job (HTTP 402), with balance + purchase URL. |
| `model_limit_exceeded` / `language_limit_exceeded` | More models/languages requested than the plan allows (HTTP 402). |
| `concurrent_job_limit_reached` | Too many active jobs for the org — wait or upgrade. |
| `classification_warning` | ⚡ Non-error: pre-flight classifier rejected the entity (see above). |
| `benchmarks_not_in_plan` | Benchmark tools need the owner role + a plan with Model Benchmarks (HTTP 403). |
| `enrichment_timeout` / `schema_generation_timeout` | Job exceeded its timeout — try fewer models. |
| `schema_generation_failed` | Upstream LLM error (HTTP 502). |
| `cancelled` | Job cancelled mid-run (HTTP 499). |
| `not_found` | Schema or record ID doesn't exist in your org. |

## Authentication details

- **OAuth 2.1 (recommended)** — any MCP client implementing the standard auth spec (claude.ai,
  Claude Code, Cursor, MCP Inspector) discovers it automatically: standard discovery via
  `/.well-known/oauth-protected-resource`, dynamic client registration, PKCE, browser consent.
  No key to create or paste. Tokens are audience-bound and instantly revocable under
  **Settings → API Keys → Connected Apps**.
- **X-API-Key** — for clients configured via a static JSON file: `ent_…` organization access
  keys, created in Settings → API Keys. The role attached to the key (operator / editor /
  owner) gates which tools succeed.

## Links

- [Entity Enricher](https://entityenricher.ai) — the platform.
- [MCP server docs](https://entityenricher.ai/docs/integrations/mcp) — the always-current web version of this guide.
- [REST API reference](https://entityenricher.ai/docs/api) — the endpoints these tools wrap.
- [Model Context Protocol](https://modelcontextprotocol.io) — the open spec.

## About this repository

This repo contains the public documentation and client examples for the Entity Enricher MCP
server. The server itself is embedded in the Entity Enricher platform and maintained in the
main (private) monorepo; this repo is synced from it as a git subtree. Issues and discussions
are welcome here.

Licensed under the [MIT License](LICENSE).

