Skip to content

Infineon/datasheetindex

Repository files navigation

Infineon logo

datasheetindex

Agent-first parameter extraction from technical datasheets.

What it does

datasheetindex is meant to be handed to an external agent in two parts:

  1. Enriched ToC JSON - Hierarchical section tree with page ranges, table hints, pre-computed breadcrumbs, boilerplate flags (revision history, disclaimers, etc.), and a preamble (pages 1-2 raw text) for agent orientation
  2. Page-matched text file - Full document text with --- PAGE N --- markers aligned to the JSON, with column-aware reading order for two-column layouts

All page numbers are 1-indexed across the JSON, the text file markers, and inspect_page(page=...).

The library also exposes create_datasheet_tools_server(), which packages artifact-building, ToC/text access, text search, text-to-coordinate grounding (locate_text), and inspect_page as the MCP/tool-server surface the agent can mount. The server starts without a bound PDF; the agent loads one at runtime by calling the build_datasheet tool with a pdf_source.

Philosophy

The library doesn't extract parameters. The agent does. All intelligence lives in the agent; the library provides the best possible starting context and the right tools for edge cases.

Supported products

datasheetindex is product-agnostic: it works with any PDF datasheet, including the full Infineon product portfolio (for example microcontrollers, power, sensors, and connectivity devices). It has no dependency on a specific product line or family.

Links

Setup

uv sync
uv run pre-commit install

Optional integrations:

# LLM fallback / summaries (`create_llm_client`, `--model`, and automatic
# low-quality ToC fallback when credentials are available)
uv sync --extra llm

# Local MCP server testing (`datasheetindex-mcp-server`)
uv sync --extra mcp

# MCP server handoff to a consuming agent (`create_datasheet_tools_server`)
uv pip install claude-agent-sdk

For LLM-backed ToC fallback and summaries, configure LITELLM_BASE_URL and LITELLM_MASTER_KEY (see .env.example).

claude-agent-sdk is only required for the SDK-flavored handoff (create_datasheet_tools_server). The tool logic itself is framework-neutral -- non-SDK hosts get it via create_datasheet_tool_defs() with no SDK import (see "Realize the tools without the Claude Agent SDK"). The mcp extra is only required if you want to run a local stdio/HTTP MCP server from this repository.

Development

uv run pytest              # run tests
uv run ruff check src/     # lint
uv run ruff format src/    # format
uv run ty check            # type check

The pre-commit pytest hook runs the fast subset only: uv run pytest -q -m "not integration and not real_pdf". Run uv run pytest for the full suite, including real-PDF and integration tests.

Input sources

DatasheetIndex and DatasheetTools accept either:

  • a local PDF file path, or
  • an http(s) URL pointing to a PDF datasheet.

Hand the MCP server to an agent

from datasheetindex import create_datasheet_tools_server

# The server starts WITHOUT a bound PDF and takes no arguments. The agent loads a
# document at runtime by calling the build_datasheet tool with a pdf_source (local
# path or URL) before using any other tool.
datasheet_tools_server = create_datasheet_tools_server()

# Pass datasheet_tools_server into your agent runtime's MCP server configuration.
# The exact wiring depends on the host agent framework; this server object is the
# concrete handoff point from datasheetindex to the agent.
agent = SomeAgentRuntime(
    mcp_servers={"datasheet-tools": datasheet_tools_server},
    system_prompt="...tell the agent to call build_datasheet first...",
)

Realize the tools without the Claude Agent SDK

Hosts that are not on the Claude Agent SDK (pydantic-ai, plain function-calling agents, custom MCP servers) can get the same tools as framework-neutral definitions -- no claude-agent-sdk import required -- via create_datasheet_tool_defs():

from datasheetindex import create_datasheet_tool_defs

# One call == one session. build_datasheet binds the document; the other tools
# read it. Each def is a frozen dataclass: name, description, input_schema
# (JSON Schema), and an async handler.
tool_defs = create_datasheet_tool_defs()

for d in tool_defs:
    register_with_your_host(
        name=d.name,
        description=d.description,
        input_schema=d.input_schema,
        # async (args: dict) -> {"content": [...], "is_error": bool}
        handler=d.handler,
    )

create_datasheet_tools_server() is a thin adapter over this factory -- it wraps each def with the SDK @tool decorator -- so the two surfaces expose identical tool names, descriptions, and schemas.

If you want direct Python access instead of an MCP server, use DatasheetTools to build artifacts, search text, and call inspect_page() on the bound instance.

from datasheetindex import DatasheetTools

with DatasheetTools("datasheet.pdf") as tools:
    artifacts = tools.build_datasheet(output_dir="output")
    toc = artifacts.json_data["toc"]  # enriched ToC tree (with breadcrumbs)

    # Search one term, or several in a single call. Each match carries the
    # breadcrumb of the section that contains its page; list searches also tag
    # each match with the `pattern` that produced it.
    matches = tools.search_text("supply voltage")
    matches = tools.search_text(["V_DS max", "junction temperature"])

    # Read a page range; the text opens with a "=== Pages X-Y of N ===" header.
    section_text = tools.get_section_text(12, 13)

    image = tools.inspect_page(
        page=12,
        region={"top": 0.15, "bottom": 0.55, "left": 0.05, "right": 0.95},
    )

    # Map a located string to its bounding box(es) - returned as percentages
    # (to crop inspect_page) and PDF points (to annotate the PDF). Matching is
    # hybrid: verbatim search with a normalized fallback for dash/case/spacing
    # variation. A string occurring multiple times yields multiple results.
    hits = tools.locate_text("supply voltage", page=12)
    if hits:
        tight = tools.inspect_page(page=12, region=hits[0]["region"]["pct"])

The optional region crop uses percentages from 0.0 to 1.0.

Run a local MCP server

You can run the local MCP server directly from the repository. It exposes these tools for the bound PDF source:

  • build_datasheet - build and save the .json / .txt artifacts, and return the manifest: source info, total pages, ToC quality, and the full enriched ToC
  • get_section_text - return extracted text for a page range from the latest build, opening with a === Pages X-Y of N === position header
  • search_text - find page-aware text snippets in the latest build (pass a single pattern or a list of patterns), even when labels wrap across lines or table values interrupt the phrase; each hit carries the section breadcrumb
  • inspect_page - render a page image when visual confirmation is needed
  • locate_text - map a string to its bounding-box coordinates (percentages + PDF points) on a page, for highlighting or to crop inspect_page precisely
  • extract_table_markdown - re-extract a page as layout-aware Markdown tables

Build once, then use get_section_text, search_text, inspect_page, locate_text, and extract_table_markdown together. search_text prefers exact matches, then falls back to whitespace-normalized and ordered-token matching for line-wrapped table rows.

The server takes no PDF argument; it starts unbound and the client loads a document at runtime by calling build_datasheet with a pdf_source.

# stdio transport (for Claude Code or another MCP client)
uv run --extra mcp datasheetindex-mcp-server

# then call build_datasheet(pdf_source="datasheet.pdf", output_dir="output")
# from the MCP client

You can also expose it over HTTP:

# streamable HTTP transport (useful with MCP Inspector)
uv run --extra mcp datasheetindex-mcp-server \
  --transport streamable-http --port 8000

With streamable-http, the default MCP endpoint is http://127.0.0.1:8000/mcp.

Every tool returns its result as a single JSON string in a TextContent block (except inspect_page, which returns an image); read it with json.loads(result.content[0].text). This matches the SDK tool surface exactly.

This local server is for direct MCP testing. If you need an in-process SDK server object inside another Python runtime, use create_datasheet_tools_server() instead; it exposes the same tool surface, with the document loaded at runtime via the build_datasheet tool.

Python API

from datasheetindex import DatasheetIndex, build_batch

artifacts = DatasheetIndex("datasheet.pdf").build(output_dir="output")

batch_result = build_batch(
    ["part-a.pdf", "part-b.pdf"],
    output_dir="batch-output",
)

In batch mode, output filenames are suffixed as needed to keep them unique when multiple inputs would otherwise resolve to the same stem.

CLI

# Local file
datasheetindex build path/to/datasheet.pdf --output-dir output

# Remote URL
datasheetindex build https://example.com/datasheet.pdf --output-dir output

# With explicit LLM model for ToC fallback and summaries
datasheetindex build datasheet.pdf --model gpt-4.1 --include-summaries

By default, datasheetindex first uses native PDF ToC extraction. If ToC quality is low, it automatically attempts LLM fallback with the default model (gpt-4.1) when LLM credentials are available. Pass --model to choose the LLM model explicitly; --include-summaries requires --model.

Project structure

src/datasheetindex/
    core/
        structure.py       # ToC extraction + enriched tree JSON
        textfile.py        # PDF -> page-matched text file (column-aware)
        _textmatch.py      # Shared dash/token normalization + matcher
        locate.py          # locate_text: text -> bounding-box coordinates
        preamble.py        # Pages 1-2 raw text extraction
        quality.py         # ToC quality assessment
        annotations.py     # Footnote and cross-reference enrichment
        boilerplate.py     # Title-pattern boilerplate classification
    tools/
        vision.py          # inspect_page (page -> image)
        bound.py           # DatasheetTools (document-bound tool logic)
        defs.py            # create_datasheet_tool_defs (framework-neutral defs)
        registry.py        # Claude Agent SDK adapter (re-exports DatasheetTools)
    mcp_server.py          # Local stdio/HTTP MCP server entry point
    llm/
        client.py          # LLM client factory
        toc_fallback.py    # LLM-based ToC generation fallback
        summarizer.py      # Optional section summaries
    cli.py                 # CLI entry point
    index.py               # Main DatasheetIndex class
    models.py              # Data models

License

Licensed under the MIT License.

Copyright (c) 2026 Infineon Technologies AG

About

Agent-first pre-processor and toolbox for technical datasheets

Resources

License

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages