idm-mcp
Mock identity-management MCP server for decentralized identity that allows minting DIDs, issuing signed Verifiable Credentials, and verifying them.
README
IDM MCP Server
A mock identity-management MCP server for decentralized identity. It exposes tools to mint DIDs, issue signed W3C-style Verifiable Credentials (VCs), and verify them — over the Model Context Protocol.
Status: mock / proof-of-concept. State is held in memory (not persistent), the issuer signing key is regenerated on every restart, and several fields are simplified for demonstration. See Limitations.
Features
get_did— mint adid:ietf:<uuid>identifier + record from an agent's public key.get_vc— issue an Ed25519-signed Verifiable Credential for a subject DID, and store it.verify_vc— verify the issuer signature on a credential.ping/echo— trivial health/echo tools used to smoke-test the MCP plumbing.
The server acts as its own credential issuer: at startup it generates an
Ed25519 keypair and mints its own DID (by calling get_did with
entity_type="IDM"). Credentials are signed with that issuer key, which stays
in-process and is never returned by any tool.
Requirements
- uv
- Python 3.12 (pinned via
.python-version) - Node.js /
npx— only needed for the MCP Inspector (mcp dev)
Dependencies (mcp[cli], cryptography) are managed by uv and installed on first run.
Setup
This project uses uv. Dependencies are declared in
pyproject.toml and pinned in uv.lock — together these replace a
requirements.txt.
After installing uv once, clone or unzip the project and run:
uv run python main.py
uv run automatically creates the virtual environment, installs the exact
locked dependencies, and even fetches Python 3.12 (pinned in .python-version)
if it's missing — no manual venv creation or activate step. Run uv sync
first if you'd rather install dependencies without starting the server.
Prefer plain pip? Export a requirements file from the lockfile, then install the old way:
uv export --format requirements-txt --no-hashes > requirements.txt
# recipient: python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
Running
# Run the server (transport is selected in main(); currently streamable-http,
# served at http://127.0.0.1:8000/mcp)
uv run python main.py
# Develop / test interactively with the MCP Inspector (opens a browser UI)
uv run mcp dev main.py
To change the transport, edit the transport variable in main() ("stdio" or
"streamable-http").
Using it from Claude Code
Register the server as a stdio MCP server:
claude mcp add idm-mcp -- uv --directory /path/to/idm_mcp run python main.py
(For stdio, set transport = 'stdio' in main().)
Generating a keypair
The tools operate on an Ed25519 keypair that the agent owns. To generate one, run:
uv run python keygen.py
# Public Key: <64 hex chars>
# Secret Key: <64 hex chars>
The public key (hex) is what you pass as pk to get_did. Keep the
secret key with the agent — it is never sent to the server.
Tools
get_did(entity_type, pk, pktype, description="", protocol="", transparency="")
Creates a DID record from an agent's public key.
| Param | Required | Description |
|---|---|---|
entity_type |
yes | Kind of entity, e.g. "AIagent", "toolbox". |
pk |
yes | Raw Ed25519 public key as hex (64 chars, from keygen.generate_raw_keys()). |
pktype |
yes | Key algorithm label, e.g. "ed25519". |
description, protocol, transparency |
no | Optional metadata recorded on the record. |
Returns the DID record, including its id (the DID).
get_vc(subjectID, content, keyType, signType, usage)
Issues and stores a Verifiable Credential for a subject DID.
| Param | Description |
|---|---|
subjectID |
The subject's DID (as minted by get_did). |
content |
What the credential grants, e.g. "callTools". |
keyType |
Recorded as the proof's cryptosuite value, e.g. "Ed25519". |
signType |
signature scheme, e.g. "asy"; Reserved (currently unused; only asymmetric signing is performed). |
usage |
Intended use, e.g. "authorization". |
The credential is signed by the issuer key over a canonical serialization
(sorted-key compact JSON, with proof empty at signing time).
verify_vc(vc)
Verifies a credential's issuer signature. Rebuilds the exact signed bytes
(proof reset to ""), resolves the issuer key, and checks the Ed25519
signature. Returns {"valid": bool, "issuer": ..., "subjectId": ..., "reason": ...}.
Only credentials issued by this server are verifiable, because other issuers' DIDs are not yet resolvable (no DID registry).
Example flow
An MCP client — an agent, Claude Code, or the MCP Inspector — calls the tools in sequence. The agent supplies its own Ed25519 public key (hex) when requesting a DID (see Generating a keypair).
-
get_did— request a DID for the agent:{ "entity_type": "AIagent", "pk": "4bb0…3c6f", "pktype": "ed25519", "description": "AIassistant", "protocol": "MCP", "transparency": "6GPDL" }→ returns a DID record whose
idis e.g.did:ietf:ebc391…. -
get_vc— issue a credential for that DID as the subject:{ "subjectID": "did:ietf:ebc391…", "content": "callTools", "keyType": "Ed25519", "signType": "asy", "usage": "authorization" }→ returns a signed Verifiable Credential.
-
verify_vc— pass the credential back to check its signature:{ "vc": { "...": "the credential returned by step 2" } }→
{ "valid": true, "issuer": "did:ietf:…", "subjectId": "did:ietf:ebc391…" }
The quickest way to try this by hand is uv run mcp dev main.py, which opens the
MCP Inspector where you can call each tool and paste results between steps.
Project structure
idm_mcp/
├── main.py # FastMCP server + the get_did / get_vc / verify_vc tools
├── keygen.py # Ed25519 key generation + sign/verify primitives (hex-encoded keys)
├── pyproject.toml # uv project + dependencies
└── README.md
Limitations
This is a mock, not production identity infrastructure:
- In-memory only — issued VCs and the issuer key are lost on restart.
- No DID registry — DIDs aren't stored, so only this server's own credentials can be verified.
signTypeis unused, andpktypeis not validated (onlyed25519is actually handled;pkis validated to be a 32-byte Ed25519 key).- Canonical JSON signing, not full JSON-LD Data Integrity canonicalization.
Recommended Servers
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.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
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.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.