iqa-mcp — IQA attestation as MCP tools
The IQA attestation primitives — derived intent addressing and AE-128 envelope verification — exposed as Model Context Protocol tools, so any MCP agent can verify trust offline, fail-closed. A thin, stateless wrapper around the published iqa-org 1.3.1 reference implementation. No network. No accounts. No key storage. No state.
In the MCP taxonomy, iqa-mcp is a server — the same category as a filesystem or database server. But it exposes trust primitives, not ordinary data: filesystem servers give you files, database servers give you query results, this server gives you the evidence to decide whether to act. It is the first MCP server that lets an agent verify standing offline — no registry lookup, no issuer call, no network.
The four tools
| Tool | Returns | Key needed |
|---|---|---|
| derive_route_shard | SHA-256(authority)[0:16] hex — the derived, action-independent intent address (SPEC sec. 3). No lookup, no registry, no network call. | no |
| parse_envelope | structural decode of one AE-128 frame: version, lease, shard, organ, nonce, standing — fails closed on every layout rule of the companion draft. | no |
| verify_envelope | full AE-128 verification: constant-time HMAC-SHA256 over the whole 128-byte frame with the attestation field zeroed, plus the lease check. REJECT is a result, not an error. | yes (caller-supplied) |
| published_vector | the published AE128-VECTOR-1 (authority, test key, frame hex) for byte-for-byte self-test. | — |
Install & run
pip install iqa-mcp # console command: iqa-mcp (stdio)
Or from a source checkout:
pip install "iqa-org>=1.3.1" "mcp>=2" python server.py # stdio transport
MCP client configuration (Claude Desktop / Cline style):
{
"mcpServers": {
"iqa": {
"command": "iqa-mcp"
}
}
}
Self-test
python -m test_mcp # installed from PyPI — runs against the console script python test_mcp.py # from a source checkout — runs against ./server.py [PASS] 1 · list_tools -> 4 tools [PASS] 2 · derive_route_shard -> 5c378581f92754d0bc88adaed84b7c5a [PASS] 3 · published_vector -> f3b2a1c4.pillar.example [PASS] 4 · parse_envelope -> standing radiant [PASS] 5 · verify_envelope -> [PASS] radiant · nonce 1 [PASS] 6 · tampered frame -> REJECT (HMAC mismatch) [PASS] 7 · malformed hex -> REJECT ALL 7/7 PASS
Test 6 is the point: flip one byte of the standing field and the frame dies — attestation does not verify. Fail-closed, over the wire.
Design invariants
- Zero-parser — fixed offsets, no TLV, no heap-shaped parsing.
- Fail-closed — malformed input is a REJECT result, never a normalised partial answer.
- Offline — verification needs the frame, the key, and a hash function. Nothing else.
- Stateless — the server stores nothing; the organ key is passed per call and never persisted.
Links
| What | Where |
|---|---|
| Source | github.com/Aicent-Stack/iqa-mcp |
| PyPI | pypi.org/project/iqa-mcp — current release 1.0.2 |
| Releases | github.com/Aicent-Stack/iqa-mcp/releases — v1.0.2 with wheel + sdist assets |
| npm | npmjs.com/package/iqa-mcp — launcher 1.0.2 (spawns the installed server) |
| crates.io | crates.io/crates/iqa-mcp - launcher 1.0.2 (spawns the installed server) |
| The library it wraps | iqa-org 1.3.1 — four registries, byte-exact vectors, offline self-test |
| Public record, dated | iqa.org/brief |
| Live demos | Stack Compare · Delegation Stress Test |
| Whitepaper | iqa.org/whitepaper |
| Internet-Draft | draft-li-rttp-iqa-addressing — Independent Submission, in review |