Skip to main content
Glama

regcite

Machine-checked register data from chip datasheet PDFs, served to AI coding agents over MCP.

  • LLMs hallucinate register values when they write firmware, regcite makes them look the values up instead.

  • Deterministic parsers (no AI) extract register tables from vendor PDFs; five validator families check every register.

  • Six MCP tools do the lookup and the bit math: get_register, decode, encode, check_errata, search_doc, init_sequence.

  • Every answer cites its PDF page and document hash; anything unverified is refused, never guessed.

  • Graded against vendor ground truth (RP2040: 949/949 registers), enforced in CI. Five chips ingested; Python + SQLite; MIT.

What that buys a model, measured — 30 register questions (lookups, bit math, and traps that deserve a refusal) against local Qwen2.5 models, with and without the server attached:

no tools

with regcite

Qwen2.5-3B

0/30

22/30

Qwen2.5-7B

2/30

29/30

The bare models answered every trap with a confident fabrication; with the server attached, no arm ever asserted a wrong hex value. abtest/ reproduces this against your own local models.

Problem

Language models write firmware from memory. A recalled register address or bit value is often close and wrong, and the resulting code compiles and returns bad measurements. The true values exist in datasheet PDFs, in tables that language models and plain PDF search both read poorly.

regcite extracts those tables with deterministic parsers, checks the result mechanically, stores it with provenance, and exposes lookup and arithmetic tools through MCP. The model writing firmware calls the tools. The tools answer from checked data or refuse.

Related MCP server: SheetsData MCP

Pipeline

  1. Fetch. python -m regcite.fetch <PART> downloads the PDF named in manifest/parts.json and verifies its SHA-256. A download that is short or lacks a PDF header is discarded before it can poison the cache.

  2. Extract. Deterministic parsers read the register tables. Each manufacturer lays tables out differently, so each has its own parser (see Grammars below). Rows are recovered from cell ruling lines and columns from header words. Cell text comes from raw positioned words, because the PDF library's own table extractor mangles underscored names.

  3. Validate. Five check families run on every register. Fields must tile the register without overlap, reset values must fit and reconstruct, access modes must be legal, addresses must sit in the declared range without collisions, and enum values must fit their fields. A failing register is stored as unverified and the tools refuse to compute with it. Each register also records which checks actually ran, because some formats omit the data a check needs.

  4. Store. One SQLite file holds registers, fields, enums, init sequences, errata, and prose chunks. Every row keeps the part, document, page, and hash it came from.

  5. Serve. An MCP server exposes the tools below. Registered with Claude Code through the repo's .mcp.json.

A vision-model pass exists for registers the parsers could not verify. It renders the PDF page, asks a local Ollama model for schema-checked JSON, rejects any answer naming a different register, and runs the same validators on what remains. Output that passes is stored as vlm_verified. Output that fails is discarded and the deterministic data stays in place.

Tools

tool

returns

get_register(part, name or address)

fields, enums, reset, access, extraction status, page

decode(part, register, value)

the value split into named fields with enum names resolved

encode(part, register, {field: value})

the byte to write, with unset fields kept at reset

check_errata(part, revision?, peripheral?)

known silicon bugs scoped to a revision

search_doc(part, query)

ranked prose passages with page numbers

init_sequence(part, mode)

ordered startup steps with timing, each step cited

A wrong field name returns the valid field list. An unknown enum returns the valid values. An unverified register returns its status and the page to check by hand. check_errata with no data loaded says so and states that absence of data is absent data.

Verification

Extraction is graded against ground truth the vendors publish. MCU makers ship SVD files listing every register, so the parsers run on two MCU reference manuals and the output is diffed against the SVD. The thresholds run as a regression gate that fails the build when a change lowers them.

metric

RP2040 (642 pages, table format)

STM32F4 (1,749 pages, prose format)

register recall

949/949

1,334/1,459 (91.4%)

register precision

100%

81.1%

offset accuracy

100%

98.1%

field precision

100%

97.6%

field recall

4,585/4,585

97.0%

field name accuracy

100%

95.7%

reset accuracy

4,367/4,368

93.1%

The one RP2040 reset mismatch is a disagreement between the datasheet and the vendor's own SVD. The datasheet gives XOSC.STARTUP.DELAY a reset of 0xC4 and the SVD gives 0x0.

Two caveats on the STM32 column. Duplicate register acronyms in that manual are resolved by picking the section that agrees best with the SVD, which makes the field metrics upper bounds, and register precision counts every unused section against the parser. Most unused sections describe F42x-only peripherals absent from the F405 SVD. A family rule matches one documented field spanning a run of single-bit SVD fields, and it never counts toward name accuracy.

Two more test tiers run above the parser level. Tier 2 is 44 hand-written questions answered from the datasheets and executed against the tools, including cases where the correct answer is a refusal. Tier 3 drives a mock I2C bus with a driver that computes every byte through encode and diffs the write log against hand-derived golden traces, plus a check that a nonsense setting raises instead of writing. All 44 questions and all 8 writes pass.

Parts

part

grammar

registers

checks that ran

BMI270

bosch_toc

85/86 verified

all five families (25 of 85 registers have enums to check)

BME688

bosch_content

46/52 verified

tiling and address (the format carries no reset or access data and no enums)

TPS65219

ti

57/57 verified

tiling, access, address, and resets on the 9 registers that state one

ICM-42688-P

tdk

108/110 verified

tiling, access, address, enums, register-level reset width

SGP41

prose only

none

command-based part with no register map. search_doc covers it

Grammar means the parser for one vendor's table format. bosch_toc reads field-per-row tables joined against the PDF's own table of contents. bosch_content reads text runs shaped like ctrl_meas 0x74 mode<1:0>. ti reads offset anchors plus Bit/Field/Type/Reset tables cross-checked against a summary table. tdk reads Name:/Address: text blocks across four register banks, with enum lines attributed to the nearest field label.

BME688 has separate SPI and I2C address maps. The store models one space per part, so its three SPI-page registers collide with three I2C registers and all six are marked unverified, the SPI ones with a note saying why. The two unverified ICM registers are parser defects, queued for the vision-model pass along with them.

Six more parts wait on PDFs their vendors do not serve to plain HTTP clients. The manifest and parsers are ready for LSM6DSV16X, MAX17048, TMC5160, WM8960, SX1262, and nRF52840 once the files are downloaded by hand.

Benchmarks

Measured on an RTX 4060 Laptop GPU (8 GB) against the same machine's CPU.

metric

GPU

CPU

embedding, 385 prose chunks

41.4 chunks/s

1.9 chunks/s

search_doc, hybrid with rerank, warm median

527 ms

11,115 ms

decode / encode

0.6 ms

0.8 ms

full BMI270 extraction

5.6 s

5.8 s

Prose search runs on FTS5 alone when the embedding stack is absent, and the response names the mode that produced it. python -m eval.bench reproduces the table.

The model comparison in the introduction comes from abtest/: a four-arm harness (two local model sizes, with and without the MCP server) over 30 questions whose ground truth is read from the database, with the full answers and tool traces committed under abtest/results/. It needs a local folder of model checkpoints — set REGCITE_MODELS_DIR or abtest/models_dir.txt — and its own torch environment; see abtest/README.md.

Quickstart

python -m venv .venv && .venv/Scripts/pip install -r requirements.txt
python -m regcite.fetch BMI270
python -m regcite.store ingest BMI270
python -m regcite.prose ingest cache/pdfs/bmi270.pdf BMI270
python -m regcite.store seed BMI270 manifest/curated/bmi270.json
python -m regcite.store get BMI270 ACC_CONF
python -m pytest tests/ -q

Paths above use the Windows venv layout (.venv/Scripts/); on Linux and macOS substitute .venv/bin/, and point .mcp.json's command at .venv/bin/python. The unit tests need no PDFs. GPU embeddings need pip install sentence-transformers and a CUDA build of torch from the index matching your driver.

The MCP server starts from .mcp.json inside Claude Code, or by hand with python -m regcite.server.

Data and redistribution

The repo ships the parsers and a manifest of source URLs with SHA-256 hashes. A fetch script builds your local cache from the manifest. Vendor PDFs and the built database stay on your machine, because republishing a corpus derived from someone's documents differs legally from reading documents you downloaded.

CI

.github/workflows/ci.yml runs lint and the unit tests on every push. A second job builds the BMI270 database from a fetched PDF and runs Tiers 2 and 3. Both jobs block the build. An encoding test scans every tracked text file for byte-order marks and mojibake.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/combax/regcite'

If you have feedback or need assistance with the MCP directory API, please join our Discord server