Skip to main content
Glama

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-mcp

No 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-mcp

This 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: 0

Use 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 openai

Credentials 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.py

The 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 tools
langextract_extractC
Read-only

Extract structured entities from literal text and return grounded spans.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
examplesYes
max_workersNo
grounded_onlyNo
visualizationNo
max_char_bufferNo
extraction_passesNo
prompt_descriptionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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_statusA
Read-onlyIdempotent

Return safe server configuration, limits, and provider mode without probing providers.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_visualizeB
Read-onlyIdempotent

Render an annotated-document payload as escaped interactive HTML without file access.

ParametersJSON Schema
NameRequiredDescriptionDefault
annotated_documentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 3 tool updatesv0.1.0
    • First observedlangextract_extract
    • First observedlangextract_status
    • First observedlangextract_visualize

TDQS

A3.5/5.0

Scored across 3 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers