langextract-mcp
Exposes Google LangExtract for model-assisted extraction from text with grounded source spans, and can optionally use Google Gemini as an inference provider.
Supports Ollama as an optional local inference provider for extraction, using its default local endpoint without requiring a URL or credentials.
Supports OpenAI as an optional inference provider for extraction, using the OpenAI API and requiring an OPENAI_API_KEY.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@langextract-mcpextract all dates and names from this note: Dr. Lee met Ana on 2024-03-05 in Berlin."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
langextract-mcp
langextract-mcp is an independent, standalone stdio MCP server that exposes Google LangExtract through three bounded tools:
langextract_extract: model-assisted extraction from literal text, with source spans.langextract_visualize: return escaped interactive HTML for an annotated payload.langextract_status: safe configuration and limit report.
This is an independent wrapper. It is not affiliated with or supported by Google. It is not published to PyPI.
The server does not read caller files, fetch caller URLs, accept model URLs, accept credentials, or write output files. langextract_extract wraps text in a langextract.core.data.Document iterable and passes fetch_urls=False, including on LangExtract versions where URL-shaped strings could otherwise be significant.
Install and run from a clone
Requirements: Python 3.11+ and uv.
git clone https://github.com/CuriosityQuantified/langextract-mcp.git
cd /absolute/path/to/langextract-mcp
uv sync --frozen --all-groups
uv run --frozen langextract-mcpNo MCP client registration occurs automatically. For an MCP client that uses mcpServers, add a server entry manually:
{
"mcpServers": {
"langextract": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/langextract-mcp",
"run",
"--frozen",
"langextract-mcp"
]
}
}
}Related MCP server: Contract Information Extractor
Optional Git-installed launch
After the v0.1.0 tag exists, an MCP client can launch the tagged source directly with uvx:
uvx --from git+https://github.com/CuriosityQuantified/langextract-mcp@v0.1.0 langextract-mcpThis command installs from Git, not PyPI. It requires network access and does not replace a clone when you need the frozen repository lockfile for reproducible development or checks.
Hermes configuration
Add this to the appropriate Hermes profile, replacing the example path with your clone's absolute path:
mcp_servers:
langextract:
command: uv
args: ["--directory", "/absolute/path/to/langextract-mcp", "run", "--frozen", "langextract-mcp"]
timeout: 180
sampling:
enabled: true
max_tokens_cap: 1024
timeout: 120
max_tool_rounds: 0Use an absolute path to uv if your MCP host does not inherit your shell's PATH. Reload the MCP connection or start a fresh host session after configuration.
Inference providers
The default (LANGEXTRACT_MCP_PROVIDER=sampling) uses the MCP host's sampling capability. The host must implement MCP sampling (sampling/createMessage); this server asks for a single text response, no tools, no included context, and at most 1,024 generated tokens. This is the preferred mode because the server does not need a new API key.
An operator may instead set LANGEXTRACT_MCP_PROVIDER to gemini, openai, or ollama, and optionally LANGEXTRACT_MCP_MODEL. OpenAI mode requires the optional extra and a locked install:
uv sync --frozen --all-groups --extra openaiCredentials remain server environment only: LANGEXTRACT_API_KEY for Gemini and OPENAI_API_KEY for OpenAI. Ollama uses its default local endpoint; the tool never receives a URL or provider kwargs. Network providers can disclose submitted text to the configured provider and can charge for tokens. Extraction passes multiply inference cost; smaller character buffers can cause more calls. Direct provider calls use one worker, disable retries where supported, and set a 120-second request timeout. Direct inference checks cancellation and a 100-request/120-second budget before each new request. An already-blocking SDK request may still run until its request timeout; cancellation prevents later requests rather than forcibly terminating the SDK.
This project deliberately does not load .env files; set environment variables in the host process.
Grounding and visualization
grounded_only=true is the default. It removes model outputs LangExtract could not align to source text. A retained span may have match_exact, match_greater, match_lesser, or match_fuzzy; exact_match is computed by direct character comparison of extraction_text and source_substring. Every returned span includes source_substring, the literal substring at the reported character interval. Missing interval/status/substrings means the model output was not grounded and appears only when grounded_only=false.
Visualization accepts payload JSON, not paths. The wrapper bounds the payload before rendering and re-encodes the released renderer's embedded JSON with script-safe escaping; visible text, classes, and attributes are HTML-escaped. Treat returned HTML as display content, not trusted executable application code.
Extraction quality depends on the host model and examples. An empty extraction list is not proof that no relevant entities exist. Models may repeat few-shot examples; grounded_only removes outputs without a source span, not every possible semantic mistake. Review the actual source substring and exact_match flag for important uses.
Calling the extraction tool
{
"text": "Grace Hopper visited London.",
"prompt_description": "Extract people and cities using exact source text, in order of appearance.",
"examples": [{
"text": "Ada Lovelace visited Paris.",
"extractions": [
{"extraction_class": "person", "extraction_text": "Ada Lovelace"},
{"extraction_class": "city", "extraction_text": "Paris"}
]
}],
"visualization": true
}Pass the returned annotated document to langextract_visualize as annotated_document to render it separately. The HTML is returned as text; saving it is the client's choice, not a server-side file operation.
Checks
uv sync --frozen --all-groups --all-extras
uv run --frozen ruff check .
uv run --frozen ruff format --check .
uv run --frozen pytest
uv run --frozen python -m build --no-isolation
uv venv --clear .wheel-venv
uv pip install --python .wheel-venv/bin/python dist/*.whl
.wheel-venv/bin/python -c "import langextract_mcp.server"For a real local-host smoke test, set LX_SAMPLING_COMMAND to a command that reads the LangExtract prompt on stdin and emits a real JSON extraction envelope, then run:
uv run --frozen python example/real_sampling_smoke.pyThe smoke script is not a product provider and does not claim fixture output is live inference.
License
Apache-2.0. The repository release must include the LICENSE file.
Available Tools
3 toolslangextract_extractCRead-only
Extract structured entities from literal text and return grounded spans.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| examples | Yes | ||
| max_workers | No | ||
| grounded_only | No | ||
| visualization | No | ||
| max_char_buffer | No | ||
| extraction_passes | No | ||
| prompt_description | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=false, destructiveHint=false, covering the safety profile. The description adds the concept of grounding ('grounded spans'), which maps to the grounded_only flag, but does not disclose that extraction is LLM-driven, explain latency/cost, or define what grounding means.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. It is well-structured, though arguably terse for a tool of this complexity; conciseness itself is not the issue so much as the missing content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 8 parameters, 3 required, nested Example/ExampleExtraction structures, and LLM-based extraction semantics, one sentence is inadequate. The role of prompt_description and examples (the mechanism that makes extraction work) is never described, leaving the agent unable to call it correctly without inspecting the raw schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 8 parameters, so the description carries the full burden. It only loosely hints at the 'text' input ('literal text') and the 'grounded_only' flag ('grounded spans'); prompt_description, examples, max_workers, max_char_buffer, extraction_passes, and visualization receive no explanation anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Extract), resource (structured entities from literal text), and output (grounded spans). It clearly distinguishes this core extraction tool from siblings langextract_status and langextract_visualize by function, though it does not name those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of prerequisites (e.g. that a prompt_description and examples are required), and no routing to langextract_visualize for rendering results. The agent must infer usage entirely from the schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
langextract_statusARead-onlyIdempotent
Return safe server configuration, limits, and provider mode without probing providers.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false, and destructiveHint=false, so the safety profile is well covered. The description adds useful behavioral context by specifying that it returns 'safe server configuration, limits, and provider mode' and explicitly avoids probing providers, though it does not detail authentication or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the return value and appends the important non-probing constraint. Every phrase earns its place, with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that this is a simple zero-parameter status tool with rich annotations and an output schema, the description provides sufficient information about what is returned and the non-probing behavior. It is nearly complete, though it could be slightly improved by noting the intended usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the description has no parameters to explain. Per the scoring rule, a zero-parameter tool sets a baseline of 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Return') and resource ('safe server configuration, limits, and provider mode'), making its purpose clear. It does not explicitly name or distinguish itself from the sibling tools (langextract_extract and langextract_visualize), so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'without probing providers' implies this tool is the safe, read-only alternative for checking status without side effects, but there is no explicit when-to-use or when-not-to-use guidance relative to the sibling tools. Usage is only implied for status checks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
langextract_visualizeBRead-onlyIdempotent
Render an annotated-document payload as escaped interactive HTML without file access.
| Name | Required | Description | Default |
|---|---|---|---|
| annotated_document | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world behavior, so the bar is low. The description adds useful context by specifying 'escaped' HTML and 'without file access', clarifying that no filesystem writes occur and that output is sanitized. However, it does not describe error handling or other behavioral traits beyond those brief hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. Every element ('Render', the payload, the HTML output, and the no-file-access constraint) earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and annotations cover the safety profile. However, for a tool whose only input is a moderately complex nested payload, the description omits how to construct that payload or its relationship to langextract_extract, leaving an agent to rely solely on the schema structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it only restates the parameter as 'annotated-document payload' without explaining the required document_id, text, or extractions fields, or how they relate to the visualization. This adds little beyond the schema and parameter name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Render'), a specific resource ('annotated-document payload'), and a clear output ('escaped interactive HTML'). It is easily distinguished from siblings like langextract_extract and langextract_status, though it does not explicitly name or contrast them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives, no prerequisites, and no mention of when not to use it. The implied usage is only that it visualizes a payload, which is minimal context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
langextract_extract - First observed
langextract_status - First observed
langextract_visualize
TDQS
Scored across 3 tools
The three tools serve clearly distinct purposes: extraction, server status, and visualization. There is no overlap in functionality, and an agent can easily select the right tool based on the task.
All tools share the consistent 'langextract_' prefix followed by a single word. However, 'extract' and 'visualize' are verbs while 'status' is a noun, a minor deviation from a pure verb_noun pattern.
Three tools is well within the typical 3-15 range and each tool has a clear, non-redundant role. The server is focused and does not appear to have unnecessary or missing tools for its scope.
The core extraction, status, and visualization operations are covered, providing a complete basic workflow. Minor gaps exist, such as batch extraction, schema listing, or configuration updates, but agents can work around them.
Maintenance
Related MCP Connectors
Verified extraction: source-backed JSON from PDFs/URLs; honest null + signed receipt.
Turn messy text into strict JSON schemas agents can trust (invoice, receipt, contact, resume).
Enable language models to perform advanced AI-powered web scraping with enterprise-grade reliabili…
Sentiment, toxicity, entity extraction, PII, translation, summary, QA, fraud scoring, safety audit.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables offline local LLM analysis of text data via MCP, taking raw text and an instruction to return analysis results without cloud calls.1MIT
- FlicenseNot gradedqualityDmaintenanceEnables extracting explicitly stated contract metadata, clauses, and obligations from user-supplied contract text without storing or modifying the data.-
- AlicenseNot gradedqualityCmaintenanceEnables agents to extract article text from public URLs or HTML, verify results against acceptance contracts, and fall back across extractors while ranking future attempts using local observed outcomes.MIT
- AlicenseNot gradedqualityAmaintenanceEnables an orchestrating LLM to delegate bounded text tasks and extract structured findings to a Gemini model through validated MCP tools, while keeping the bridge local and security-conscious.Apache 2.0