kyb-mcp
kyb-mcp
A KYB (Know Your Business) workbench exposed over the Model Context Protocol. It searches the French company registry (SIRENE / RNE through the free recherche-entreprises.api.gouv.fr API), keeps review dossiers in PostgreSQL, and exposes all of it to Claude Code, claude.ai or any MCP client.
Built on the MCP Python SDK v2 (protocol revision 2026-07-28) as a learning project that uses every protocol primitive on purpose: tools, resources, prompts, completions, elicitation, sampling, progress, change notifications, stdio and Streamable HTTP.
┌────────────┐ stdio / Streamable HTTP ┌──────────────────────────┐ https ┌────────────────────────┐
│ MCP client │ ◄───────────────────────► │ kyb-mcp (MCPServer) │ ────────► │ recherche-entreprises │
│ Claude Code│ tools · resources · │ tools/ resources.py │ 5 req/s │ .api.gouv.fr (public) │
│ claude.ai │ prompts · completions │ prompts.py core.py │ └────────────────────────┘
│ Inspector │ elicit · sample · │ db/repo.py (port) │ SQL ┌────────────────────────┐
└────────────┘ progress · notify │ ├ InMemoryDossierRepo │ ────────► │ PostgreSQL │
│ └ PostgresDossierRepo │ │ (Compose local / Neon) │
└──────────────────────────┘ └────────────────────────┘Quick start
uv sync
uv run kyb-mcp # stdio server, in-memory dossiers, no config needed
uv run mcp dev src/kyb_mcp/server.py # same server inside the MCP Inspector (needs Node)Register it in Claude Code (stdio):
claude mcp add kyb -- uv run --directory /absolute/path/to/kyb-mcp kyb-mcpThen try: "Find the company Qonto, open a dossier for it and run the KYB review prompt."
What the server exposes
Primitive | Name | What it teaches |
Tool |
| Typed inputs ( |
Tool |
| Lifespan-held store, |
Tool |
| Elicitation through a |
Tool |
| Sampling: |
Tool |
|
|
Resource |
| URI templates, |
Prompt |
| Multi-message prompts with an |
Completion |
| Server-side autocomplete fed by recently seen companies |
All tool calls to the registry go through one httpx.AsyncClient with a token bucket (5 req/s, the public
limit is 7) and a 60 s cache. Directors' birth dates are dropped before anything leaves the process.
Configuration
Variable | Default | Purpose |
| unset → in-memory | PostgreSQL DSN for durable dossiers |
| localhost only | Host allowlist for HTTP behind a real hostname (comma-separated) |
| none | Browser origins (CORS twin) |
| per-process random | Shared key for multi-instance HTTP (elicitation / sampling retries) |
| 5 | Upstream rate limit |
| unset | Disable DNS-rebinding checks when the proxy owns |
Streamable HTTP, Docker, Compose
uv run uvicorn kyb_mcp.http:app --port 8000 # http://127.0.0.1:8000/mcp (+ /healthz)
claude mcp add --transport http kyb-http http://127.0.0.1:8000/mcp
docker compose up -d --build # PostgreSQL 16 (host port 5433) + server on :8000Tagged releases publish ghcr.io/igitscor/kyb-mcp with an SBOM and provenance attestation
(.github/workflows/image.yml).
Deploy (Vercel Hobby + Neon, no credit card)
npm i -g vercel@latest && vercel loginwith your personal account, thenvercel link.Create a free Neon project and add its DSN:
vercel env add DATABASE_URL production.vercel env add KYB_REQUEST_STATE_KEY productionwithpython -c "import secrets; print(secrets.token_hex(32))".vercel deploy --prod. The entrypoint iskyb_mcp.http:app(see[tool.vercel]inpyproject.toml).Point Claude Code at
https://<project>.vercel.app/mcp, or add it as a claude.ai custom connector.
Why this host and database: ADR 0004.
Development
uv run pytest # 23 offline tests (respx mocks the registry)
docker compose up -d db && KYB_TEST_DATABASE_URL=postgresql://kyb:kyb@localhost:5433/kyb uv run pytest tests/test_repo_postgres.py
uv run ruff check && uv run ruff format --check && uv run pyrightCI runs the same on every push with a PostgreSQL service container, then builds the Docker image and
smoke-tests /healthz and server/discover.
Design notes
ADR 0001: why SDK v2 / protocol 2026-07-28, and what changed from FastMCP.
ADR 0002: PostgreSQL behind a repository port, in-memory adapter for zero-setup runs.
ADR 0003: stateless HTTP, DNS-rebinding protection, shared request-state key.
ADR 0004: hosting comparison and the no-card constraint.
SECURITY.md: data handling, transport exposure, what is not protected yet.
Learning path (how this repo was built)
Stage | Files | Concepts |
1 |
| stdio, |
2 |
| URI templates, MIME types, embedded resources, completions |
3 |
| lifespan, typed |
4 |
| elicitation and sampling via |
5 |
| in-memory |
6 |
| Streamable HTTP, transport security, containers |
7 |
| serverless deployment, Neon |
Next steps
OAuth 2.1 resource server (
AuthSettings+TokenVerifier) before exposing write tools publicly.OpenTelemetry exporter: the SDK already emits a span per request; add
opentelemetry-sdkand an OTLP endpoint.Publish to the official MCP Registry with
mcp-publisher.
License
MIT. Registry data is public data from INSEE / INPI under the Licence Ouverte 2.0.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/iGitScor/kyb-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server