DEV Community

OpenRegistry
OpenRegistry

Posted on

How I built an MCP server for 27 government registries in a week

I built an MCP server for 27 government registries, and the first thing I learned was that the hardest part is not the transport layer. It is all the tiny differences in company identifiers, search behavior, and what each registry actually returns on a bad query.

This week I wired the server so Claude Desktop can ask one question and get back a source-linked result instead of a scraped summary. The useful bit is not that it "works". It is that each registry keeps its own quirks, and the server normalizes just enough to make the response usable without hiding the original source.

example shape:

  • registry: UK Companies House
  • lookup: exact name match plus fallback fuzzy search
  • result: company number, status, incorporation date, registered office, officers, filing links

The early version failed in predictable ways. UK and Ireland both accept names that look similar but point to different legal entities. Germany and Cyprus can return records in forms that are technically valid but not readable unless you keep the original language in the payload. Taiwan and Norway were easier on the data side, but they still disagreed on how much structure you get back from a simple company search.

So I changed the server design in three ways.

First, I stopped pretending every registry should look the same. The response object now keeps a source block and a normalized block side by side. That means Claude can answer in plain language while still preserving the exact registry fields. It also means I can debug where a mismatch started, which matters more than polished output.

Second, I treated rate limits as product behavior, not an error path. Some registries are fine for interactive lookups but awkward for polling. Others are generous until you ask for too many related records. The server now marks which endpoints are safe for one-off human questions and which ones are better for follow-up detail.

Third, I made the connector useful for non-developers as well. A lot of people do not want an API. They want to ask: is this company real, who is the director, what filings changed, and is the ownership trail consistent. Once the MCP layer is in place, the question stays simple even if the underlying registry is not.

That design choice changed the demo too. Instead of showing a wall of data, I now show a short conversation and a source trail.

User: check whether this company is actually active and who runs it

Claude: I found the company record, the current status is active, and the officer list includes two directors. The filing history shows the most recent confirmation statement was filed on time.

User: can you show the original source

Claude: yes, here are the registry links and the exact fields I used.

The most useful test was asking the server to compare registries against each other on the same kind of question. When the answer was inconsistent, the bug was usually in my normalization layer, not in the registry itself. That is a good sign, because it means the source data stayed honest and the adapter layer became the place where the work happened.

If you are building something similar, the Monday-morning checklist is short: keep source and normalized data separate, assume identifiers are messy, and design for human questions before you optimize for bulk extraction.

One more thing surprised me. The server became more useful when I stopped trying to answer every question with a single record lookup. A good company workflow often needs a second step: confirm the current entity, then inspect officers, then check filings, then follow any cross-jurisdiction links. That sequence is boring to implement and very easy to get wrong if you flatten everything too early. The MCP layer makes it possible to preserve that sequence without forcing the user to think about each registry’s quirks.

You can try the connector here: https://openregistry.sophymarine.com

Top comments (0)