ARES Explorer

ARES Explorer

MCP server that turns the Czech business register (ARES) into an interactive force-directed graph of company management and ownership ties, allowing users to explore and expand the graph live within Claude.

Category
Visit Server

README

ARES Explorer πŸ‡¨πŸ‡Ώ β€” MCP App

What is this? An MCP App that turns the Czech business register (ARES) into an interactive relationship graph. Ask Claude about a company and a force-directed graph of its management and ownership ties renders right in the chat β€” then click any company node to expand it live and watch the network grow. Built with the MCP Apps SDK, a serverless MCP endpoint (mcp-handler on Vercel), and D3.

status license mcp


How to use it in Claude

This is not a website you click on β€” it's an MCP App connector. You don't open it in a browser; you add it to Claude as a custom connector and then talk to it in chat.

Connector endpoint:

https://ares-explorer-mcp.vercel.app/api/mcp

Mind the /api/mcp path β€” that exact path is the MCP endpoint (Streamable HTTP). Opening the URL in a browser shows nothing useful; it's an MCP server, not a web page. The bare domain or any other path won't work as a connector.

Connect it (one-time):

  1. In Claude on web or desktop, go to Connectors (now under the Customize section β€” it used to live under Settings).
  2. Click Add custom connector.
  3. Paste https://ares-explorer-mcp.vercel.app/api/mcp and confirm.

Requires a paid Claude plan (Pro / Max / Team). Custom connectors are not available on the free plan.

Harmless sign-in warning. While adding the connector, Claude may show an OAuth / sign-in message such as "Couldn't register with sign-in service." It's safe to ignore β€” just dismiss it. The server is public and needs no login, and the tools load regardless.

Try it. Once connected, ask in chat:

  • β€žUkaΕΎ graf vazeb firmy s IČO 24130222." (Show the relationship graph for the company with IČO 24130222.) β€” then click company nodes and the graph grows live.
  • β€žVykresli vlastnickou strukturu firmy s IČO 27604977." (Draw the ownership structure of the company with IČO 27604977.)
  • β€žNajdi firmu Seznam.cz a ukaΕΎ jejΓ­ vazby." (Find the company Seznam.cz and show its ties.)

What it is

ARES Explorer is an MCP App that takes the open data of the Czech ARES register and builds an interactive graph of a company's ties β€” its statutory body, members/owners, and connected companies β€” rendering it directly inside Claude. It isn't just a static picture: company nodes are clickable and the graph grows live as the app calls back to the server (the "bidirectional loop" of MCP Apps).

Type something like β€žUkaΕΎ mi vazby firmy s IČO 24130222." (Show me the relationships of the company with IČO 24130222.) and you get a canvas where you can explore the ownership and personnel structure by clicking.

Why it's interesting

  • An MCP App, not just a tool. Most MCP servers return text. Here a full UI runs in a sandbox and initiates further tool calls on its own based on what the user does. Click a node β†’ app.callServerTool("expand-node") β†’ new data is merged into the graph.
  • Real open data. No mocks β€” the server talks live to the public ARES REST API.
  • Tolerant parser. The VR (veΕ™ejnΓ½ rejstΕ™Γ­k, public register) JSON is deeply nested and varies by legal form. The parser therefore walks the record recursively and pulls out anything that looks like a person (jmeno + prijmeni) or a connected company (ico + obchodniJmeno), inferring the role (jednatel, společnΓ­k, …) from context. Resilient to schema changes.

What it looks like

ARES Explorer β€” the force-directed graph with a company's inspector panel open

The expanded graph (55 nodes · 59 ties). The inspector lists the statutory-body members (člen statutÑrního orgÑnu) of the selected company, Corporate Consulting a.s., each with a deep link out to ARES.

ARES Explorer β€” a person node selected, showing date of birth and ties

Click a person node for its detail: René Sommer, born 1966, sits on the supervisory board (člen dozorčí rady) of Kofola ČeskoSlovensko a.s.

  • Companies = amber rounded square, people = teal circle (distinguished by both shape and color).
  • A node with + can be expanded. The side inspector shows detail, ties, and a link out to ARES.
  • The toolbar lets you paste any IČO to attach another company to the graph.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ MCP host (Claude) ────────────────────────────┐
β”‚                                                                            β”‚
β”‚   company-graph(ico)                       sandboxed iframe (ui://)        β”‚
β”‚        β”‚  tool result (GraphData)        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚        β–Ό  ───────────────────────────▢   β”‚  D3 force graph              β”‚  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                         β”‚  node click ───┐             β”‚  β”‚
β”‚   β”‚  /api/mcp   β”‚ ◀── expand-node(ico) ───│  β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ callServerToolβ”‚
β”‚   β”‚ (serverless)β”‚ ──── GraphData ────────▢│  merge β†’ graph grows         β”‚  β”‚
β”‚   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚        β”‚ fetch                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β–Ό
   ARES REST API  (ares.gov.cz)
   β€’ /ekonomicke-subjekty/{ico}      β†’ base record
   β€’ /ekonomicke-subjekty-vr/{ico}   β†’ public register (ties)
   β€’ /ekonomicke-subjekty/vyhledat   β†’ search by name

Server tools

Tool UI? What it does
ares-search no Najde firmy podle nÑzvu, vrÑtí IČO.
company-graph yes OtevΕ™e interaktivnΓ­ graf vazeb (IČO nebo nΓ‘zev).
expand-node no VrΓ‘tΓ­ podgraf jednΓ© firmy β€” volΓ‘ appka pΕ™i rozkliknutΓ­ uzlu.

Tool titles and descriptions are intentionally kept in Czech β€” the app and its data are Czech, so this is how they read to both the user and the model.

The data contract (src/types.ts) is shared by the server and the UI, keeping both sides in sync. The UI never talks to ARES itself β€” it only renders GraphData and asks the server to expand nodes.


Architecture decision: from Express to serverless

The first version ran as a long-lived Express process exposing the MCP server over Streamable HTTP. It was rewritten as a single Vercel serverless function via mcp-handler's createMcpHandler (app/api/mcp/route.ts). Streamable HTTP is the recommended MCP transport, so a stateless request/response function maps onto it cleanly β€” there's no socket to keep alive, and the platform autoscales with load. Vercel's Fluid compute keeps instances warm and reuses them across invocations, avoiding the cold-start lag of sleeping free-tier processes while still scaling down when idle. The one build artifact the function depends on β€” the app's UI HTML β€” is inlined into the bundle at build time, so there's no runtime filesystem dependency in the serverless environment.


Tech stack

  • TypeScript (server and UI), strict mode
  • @modelcontextprotocol/ext-apps β€” MCP Apps SDK (server helpers + client App class)
  • @modelcontextprotocol/sdk β€” MCP server + Streamable HTTP transport
  • mcp-handler + Next.js 15 App Router β€” MCP over a single serverless function (app/api/mcp/route.ts), no long-lived process. Next.js is used purely as the routing + build wrapper for that one handler β€” no pages, no next/* imports in code. react / react-dom are pulled in only as Next's required peers, not used by the app (the UI is plain D3 in inlined HTML)
  • zod β€” tool input validation
  • D3 (force-directed graph, zoom/pan, drag)
  • Vite + vite-plugin-singlefile β€” the UI is bundled into one HTML file that the build inlines directly into the serverless function (no external origins β†’ simple CSP)

Local development

You need Node.js 20+.

npm install        # .npmrc sets legacy-peer-deps (see "Deploy to Vercel")
npm run dev        # vite build β†’ inline UI into the function β†’ next dev

The MCP endpoint then runs at http://localhost:3000/api/mcp (Streamable HTTP, POST). As with production, the /api/mcp path is the endpoint β€” http://localhost:3000 on its own serves nothing useful (this is an API-only Next.js app).

Other scripts:

npm run build      # production build: vite + inline + next build
npm run typecheck  # tsc --noEmit
npm test           # unit tests for the ties parser (no network)

The inlined-HTML step

The route handler imports the UI from a build-generated, gitignored module β€” app/api/mcp/route.ts does import { ARES_EXPLORER_HTML } from "./ares-explorer-html", and that file (app/api/mcp/ares-explorer-html.ts) only exists after the build emits it. Both npm run dev and npm run build regenerate it for you: they bundle the UI with Vite into dist/ares-explorer.html, then scripts/inline-html.mjs embeds it as a string into the module. The serverless function therefore has no runtime filesystem dependency β€” the HTML is part of the bundle.

Always start the dev server with npm run dev, not a bare next dev. The npm script runs build:app + inline first; running next dev directly on a clean checkout skips those steps and Next will fail to compile on the missing ./ares-explorer-html import. If you ever hit that, run npm run dev (or just npm run build once) to generate the module.

Testing the server without Claude β€” MCP Inspector

To exercise the endpoint without wiring it into Claude, point the MCP Inspector at your local server:

npx @modelcontextprotocol/inspector

Connect it to http://localhost:3000/api/mcp (transport: Streamable HTTP) and you can drive the protocol directly β€” initialize, tools/list, resources/list β€” and call the tools, getting their results back as JSON. This is the fastest way to confirm the server is up and the tools are wired correctly.

The Inspector only shows raw JSON β€” company-graph returns GraphData, not the rendered graph. The interactive D3 UI only paints inside an MCP host (Claude), so for the full visual experience use the tunnel flow below.

Testing the full UI in Claude β€” via a tunnel

Because the graph renders only inside the MCP host's sandbox, to see the real UI you need to expose your local server over a public URL and add it to Claude as a second custom connector. A quick tunnel:

cloudflared tunnel --url http://localhost:3000

This prints a public https://<random>.trycloudflare.com URL. Add https://<random>.trycloudflare.com/api/mcp as an additional custom connector in Claude (same steps as How to use it in Claude, just your tunnel URL) β€” keep the production connector too β€” and you can dogfood your local changes with the full clickable graph before opening a PR.

cloudflared is installed separately (e.g. brew install cloudflared); there's intentionally no npm script for it, since tunnelling is an ad-hoc debugging step, not part of the build.

For host-free local debugging you can also drive the app with basic-host from the ext-apps repo.

Recommended workflow

  1. Iterate locally with npm run dev + the MCP Inspector for fast JSON-level checks.
  2. Verify the real UI in Claude through the cloudflared tunnel once the behaviour looks right.
  3. Open a PR β€” only then does it go through CI and review. Production is reached strictly via merge to main, as described in Who can deploy, and how: PR β†’ CI (typecheck + tests + build) β†’ maintainer review β†’ merge to main β†’ production deploy. Nothing ships any other way.

Deploy to Vercel

The project is an API-only Next.js app β€” the only route is the MCP endpoint app/api/mcp/route.ts, which serves Streamable HTTP via mcp-handler. No long-lived process, no state between requests.

Via the dashboard: import the repo at vercel.com/new. The framework (Next.js) and build are detected automatically from vercel.json; nothing needs to be configured by hand. After deploy, the endpoint lives at https://<project>.vercel.app/api/mcp.

Via the CLI:

npm i -g vercel
vercel          # preview deploy
vercel --prod   # production deploy

What's wired up for deployment:

  • vercel.json β€” framework: nextjs, buildCommand: npm run build (runs vite build β†’ inline HTML β†’ next build), and maxDuration: 60 s for the /api/mcp function.
  • .npmrc with legacy-peer-deps=true β€” mcp-handler@1.1.0 pins its @modelcontextprotocol/sdk peer to exactly 1.26.0, whereas ext-apps requires ^1.29.0. The APIs in use (McpServer + Streamable HTTP transport) are stable across those versions, so we stay on 1.29.x. Vercel reads this file at install time too, so the same resolution applies in CI.
  • Inlined HTML β€” the app's UI is embedded straight into the function at build time (see above), so the serverless environment never needs to read dist/ from disk.

After deploying, add https://<project>.vercel.app/api/mcp as a custom connector in Claude (see How to use it in Claude).

Who can deploy, and how (contribution process)

Production deploys are gated β€” they don't happen on a whim, and not everyone can trigger one.

  • main is protected. No direct pushes for contributors. Every change lands through a pull request that must pass CI (.github/workflows/ci.yml β†’ typecheck + tests + build) and get a maintainer's approving review before it can merge.
  • Production = a merge to main. Vercel deploys main to production. Since only reviewed, CI-green PRs (or the maintainer's own pushes) reach main, nothing ships to production without the maintainer's sign-off.
  • Fork previews are not automatic. Vercel's Git fork protection is on, so a PR from a fork won't build a preview until a maintainer authorizes it β€” outside code never builds in this project unprompted.
  • CLI production deploys (vercel --prod) are restricted to the maintainer via Vercel team membership. This is the one path that bypasses GitHub, so team access is kept tight on purpose.

So a new contributor's flow is: fork β†’ branch β†’ open a PR β†’ CI runs β†’ maintainer reviews and approves β†’ maintainer merges β†’ production deploys. No task gets to production any other way.


Project structure

ares-explorer-mcp/
β”œβ”€β”€ app/
β”‚   └── api/mcp/
β”‚       β”œβ”€β”€ route.ts            # MCP endpoint: createMcpHandler β€” tools + UI resource
β”‚       └── ares-explorer-html.ts  # build-generated (gitignored): inlined UI HTML
β”œβ”€β”€ scripts/
β”‚   └── inline-html.mjs         # embeds dist/ares-explorer.html into the function as a string
β”œβ”€β”€ ares-explorer.html          # app entry HTML (inline styles)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ types.ts                # shared data contract (GraphData …)
β”‚   β”œβ”€β”€ ares.ts                 # ARES REST client + tolerant ties parser
β”‚   └── mcp-app.ts              # UI: D3 force graph, node expansion
β”œβ”€β”€ test/
β”‚   └── graph.test.ts           # parser unit tests (fixtures, no network)
β”œβ”€β”€ vercel.json                 # Vercel: framework, build, maxDuration
β”œβ”€β”€ next.config.mjs
β”œβ”€β”€ vite.config.ts
β”œβ”€β”€ tsconfig.json
└── package.json

Notes & limits

  • ARES data is for information only and has no character of an official document (see the ARES terms). The API is rate-limited to 500 requests/min.
  • The parser covers the most common forms (s.r.o., a.s., spolek). For exotic structures some ties may be missing β€” it deliberately omits rather than guesses. The logic is covered by unit tests.
  • Subjects with no VR record (e.g. some sole traders / OSVČ) show up as a standalone node with no ties.
  • Graph depth is capped (~80 ties per record) to stay readable; deeper levels are filled in by expanding nodes.

License

MIT β€” see LICENSE.

Data: Β© ARES / Ministry of Finance of the Czech Republic, provided as open data.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured