dokimo-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Augaster Technologies
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: dokimo-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server to verify AI-agent revenue claims: recompute a Merkle proof and check it against an on-chain anchor.
5
+ Author: Augaster Technologies
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://dokimo.augaster.com
8
+ Project-URL: Demo, https://dokimo.augaster.com/agent-audits-agents.html
9
+ Project-URL: Repository, https://github.com/ypratap11/dokimo-mcp
10
+ Project-URL: Issues, https://github.com/ypratap11/dokimo-mcp/issues
11
+ Keywords: mcp,model-context-protocol,x402,agentic-payments,merkle,verification,agents
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Security
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: mcp<2,>=1.2
18
+ Requires-Dist: uvicorn>=0.30
19
+ Dynamic: license-file
20
+
21
+ # dokimo-mcp
22
+
23
+ <!-- mcp-name: io.github.ypratap11/dokimo-mcp -->
24
+
25
+ **Give an AI agent the ability to verify another agent's revenue claims.**
26
+
27
+ An [MCP](https://modelcontextprotocol.io) server exposing [Dokimo's](https://dokimo.augaster.com)
28
+ trustless evidence verification as tools any MCP client (Claude Desktop, IDE
29
+ agents, custom agents) can call. It's the "agent that audits agents" — as tools.
30
+
31
+ Live, clickable version of what these tools do:
32
+ **https://dokimo.augaster.com/agent-audits-agents.html**
33
+
34
+ > This is a thin, self-contained **client**: it calls Dokimo's public endpoints and
35
+ > implements the public `dokimo-merkle-v1` hashing scheme. It contains no proprietary
36
+ > code. MIT-licensed.
37
+
38
+ ## Tools
39
+
40
+ | Tool | What it does | Network? |
41
+ |---|---|---|
42
+ | `recompute_merkle_root(leaf, proof_path)` | **Trustless local recompute** — hash a leaf under `dokimo-merkle-v1` and replay the proof path to a root, with **no network and no trust in anyone**. Compare it to a package's claimed `root` yourself. | none |
43
+ | `verify_evidence_package(package)` | **Full verification** via Dokimo's public A2A endpoint: recompute **and** check the compound commitment (root + rule version) against the **on-chain anchor on Base**. Returns `verified: true` only if both hold. | Dokimo A2A |
44
+ | `dokimo_agent_card()` | Fetch Dokimo's public A2A agent card — what it can verify. | Dokimo |
45
+
46
+ **Verification model:** there is no path to `verified: true` without (1) the
47
+ caller's `(leaf, proof_path)` recomputing to the claimed `root`, **and** (2) the
48
+ compound commitment of `(root, rule_version_commitment)` being anchored on-chain.
49
+ Tamper one byte → recompute fails. Swap the rule version → the commitment changes
50
+ → not anchored.
51
+
52
+ **Honest scope:** attests that a *reported* figure is reproducible and
53
+ tamper-evident against an on-chain anchor — not that any underlying business
54
+ number is "good." Non-custodial; reads public on-chain state only.
55
+
56
+ ## Install & run
57
+
58
+ ```bash
59
+ pip install dokimo-mcp
60
+ dokimo-mcp # runs over stdio
61
+ # or, from a clone:
62
+ pip install .
63
+ python -m dokimo_mcp
64
+ ```
65
+
66
+ ## Add to an MCP client
67
+
68
+ **Claude Desktop** — add to `claude_desktop_config.json`:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "dokimo": {
74
+ "command": "dokimo-mcp"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ If `dokimo-mcp` isn't on `PATH`, use the module form:
81
+
82
+ ```json
83
+ {
84
+ "mcpServers": {
85
+ "dokimo": {
86
+ "command": "python",
87
+ "args": ["-m", "dokimo_mcp"]
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ Then ask the agent: *"Use Dokimo to verify this evidence package"* (paste one), or
94
+ *"recompute this Merkle root and tell me if it matches."*
95
+
96
+ ## Try it
97
+
98
+ The live demo page embeds a real, anchored evidence package. Fetch it and verify:
99
+
100
+ ```python
101
+ import re, json, urllib.request
102
+ import dokimo_mcp as d
103
+ html = urllib.request.urlopen(urllib.request.Request(
104
+ "https://dokimo.augaster.com/agent-audits-agents.html",
105
+ headers={"User-Agent": d._UA})).read().decode()
106
+ pkg = json.loads(re.search(r"const PKG\s*=\s*(\{.*?\})\s*;", html, re.S).group(1))
107
+ print(d.verify_evidence_package(pkg)["verified"]) # True
108
+ # tamper one unit -> False
109
+ pkg["leaf"] = pkg["leaf"].replace("1001190933933115", "1001190933933116")
110
+ print(d.verify_evidence_package(pkg)["verified"]) # False
111
+ ```
112
+
113
+ ## Hosted / HTTP mode
114
+
115
+ The default transport is **stdio** (local use). Set `MCP_TRANSPORT=http` to serve
116
+ **MCP Streamable HTTP at `/mcp`** on `$PORT` (default 8081) with CORS — the shape
117
+ hosted platforms like [Smithery](https://smithery.ai) require. The included
118
+ `Dockerfile` + `smithery.yaml` (`runtime: container`) are set up for exactly this,
119
+ so Smithery can build and host it from this repo.
120
+
121
+ ```bash
122
+ MCP_TRANSPORT=http PORT=8081 dokimo-mcp # or: docker run -p 8081:8081 <image>
123
+ ```
124
+
125
+ ## What is Dokimo?
126
+
127
+ Verifiable revenue infrastructure for autonomous commerce — audit-ready, independently
128
+ reproducible books for AI-agent machine payments (x402 / AP2 / Stripe), with each figure
129
+ tamper-evidently committed and anchored on-chain. https://dokimo.augaster.com
130
+
131
+ ## License
132
+
133
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,113 @@
1
+ # dokimo-mcp
2
+
3
+ <!-- mcp-name: io.github.ypratap11/dokimo-mcp -->
4
+
5
+ **Give an AI agent the ability to verify another agent's revenue claims.**
6
+
7
+ An [MCP](https://modelcontextprotocol.io) server exposing [Dokimo's](https://dokimo.augaster.com)
8
+ trustless evidence verification as tools any MCP client (Claude Desktop, IDE
9
+ agents, custom agents) can call. It's the "agent that audits agents" — as tools.
10
+
11
+ Live, clickable version of what these tools do:
12
+ **https://dokimo.augaster.com/agent-audits-agents.html**
13
+
14
+ > This is a thin, self-contained **client**: it calls Dokimo's public endpoints and
15
+ > implements the public `dokimo-merkle-v1` hashing scheme. It contains no proprietary
16
+ > code. MIT-licensed.
17
+
18
+ ## Tools
19
+
20
+ | Tool | What it does | Network? |
21
+ |---|---|---|
22
+ | `recompute_merkle_root(leaf, proof_path)` | **Trustless local recompute** — hash a leaf under `dokimo-merkle-v1` and replay the proof path to a root, with **no network and no trust in anyone**. Compare it to a package's claimed `root` yourself. | none |
23
+ | `verify_evidence_package(package)` | **Full verification** via Dokimo's public A2A endpoint: recompute **and** check the compound commitment (root + rule version) against the **on-chain anchor on Base**. Returns `verified: true` only if both hold. | Dokimo A2A |
24
+ | `dokimo_agent_card()` | Fetch Dokimo's public A2A agent card — what it can verify. | Dokimo |
25
+
26
+ **Verification model:** there is no path to `verified: true` without (1) the
27
+ caller's `(leaf, proof_path)` recomputing to the claimed `root`, **and** (2) the
28
+ compound commitment of `(root, rule_version_commitment)` being anchored on-chain.
29
+ Tamper one byte → recompute fails. Swap the rule version → the commitment changes
30
+ → not anchored.
31
+
32
+ **Honest scope:** attests that a *reported* figure is reproducible and
33
+ tamper-evident against an on-chain anchor — not that any underlying business
34
+ number is "good." Non-custodial; reads public on-chain state only.
35
+
36
+ ## Install & run
37
+
38
+ ```bash
39
+ pip install dokimo-mcp
40
+ dokimo-mcp # runs over stdio
41
+ # or, from a clone:
42
+ pip install .
43
+ python -m dokimo_mcp
44
+ ```
45
+
46
+ ## Add to an MCP client
47
+
48
+ **Claude Desktop** — add to `claude_desktop_config.json`:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "dokimo": {
54
+ "command": "dokimo-mcp"
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ If `dokimo-mcp` isn't on `PATH`, use the module form:
61
+
62
+ ```json
63
+ {
64
+ "mcpServers": {
65
+ "dokimo": {
66
+ "command": "python",
67
+ "args": ["-m", "dokimo_mcp"]
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ Then ask the agent: *"Use Dokimo to verify this evidence package"* (paste one), or
74
+ *"recompute this Merkle root and tell me if it matches."*
75
+
76
+ ## Try it
77
+
78
+ The live demo page embeds a real, anchored evidence package. Fetch it and verify:
79
+
80
+ ```python
81
+ import re, json, urllib.request
82
+ import dokimo_mcp as d
83
+ html = urllib.request.urlopen(urllib.request.Request(
84
+ "https://dokimo.augaster.com/agent-audits-agents.html",
85
+ headers={"User-Agent": d._UA})).read().decode()
86
+ pkg = json.loads(re.search(r"const PKG\s*=\s*(\{.*?\})\s*;", html, re.S).group(1))
87
+ print(d.verify_evidence_package(pkg)["verified"]) # True
88
+ # tamper one unit -> False
89
+ pkg["leaf"] = pkg["leaf"].replace("1001190933933115", "1001190933933116")
90
+ print(d.verify_evidence_package(pkg)["verified"]) # False
91
+ ```
92
+
93
+ ## Hosted / HTTP mode
94
+
95
+ The default transport is **stdio** (local use). Set `MCP_TRANSPORT=http` to serve
96
+ **MCP Streamable HTTP at `/mcp`** on `$PORT` (default 8081) with CORS — the shape
97
+ hosted platforms like [Smithery](https://smithery.ai) require. The included
98
+ `Dockerfile` + `smithery.yaml` (`runtime: container`) are set up for exactly this,
99
+ so Smithery can build and host it from this repo.
100
+
101
+ ```bash
102
+ MCP_TRANSPORT=http PORT=8081 dokimo-mcp # or: docker run -p 8081:8081 <image>
103
+ ```
104
+
105
+ ## What is Dokimo?
106
+
107
+ Verifiable revenue infrastructure for autonomous commerce — audit-ready, independently
108
+ reproducible books for AI-agent machine payments (x402 / AP2 / Stripe), with each figure
109
+ tamper-evidently committed and anchored on-chain. https://dokimo.augaster.com
110
+
111
+ ## License
112
+
113
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: dokimo-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server to verify AI-agent revenue claims: recompute a Merkle proof and check it against an on-chain anchor.
5
+ Author: Augaster Technologies
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://dokimo.augaster.com
8
+ Project-URL: Demo, https://dokimo.augaster.com/agent-audits-agents.html
9
+ Project-URL: Repository, https://github.com/ypratap11/dokimo-mcp
10
+ Project-URL: Issues, https://github.com/ypratap11/dokimo-mcp/issues
11
+ Keywords: mcp,model-context-protocol,x402,agentic-payments,merkle,verification,agents
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Security
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: mcp<2,>=1.2
18
+ Requires-Dist: uvicorn>=0.30
19
+ Dynamic: license-file
20
+
21
+ # dokimo-mcp
22
+
23
+ <!-- mcp-name: io.github.ypratap11/dokimo-mcp -->
24
+
25
+ **Give an AI agent the ability to verify another agent's revenue claims.**
26
+
27
+ An [MCP](https://modelcontextprotocol.io) server exposing [Dokimo's](https://dokimo.augaster.com)
28
+ trustless evidence verification as tools any MCP client (Claude Desktop, IDE
29
+ agents, custom agents) can call. It's the "agent that audits agents" — as tools.
30
+
31
+ Live, clickable version of what these tools do:
32
+ **https://dokimo.augaster.com/agent-audits-agents.html**
33
+
34
+ > This is a thin, self-contained **client**: it calls Dokimo's public endpoints and
35
+ > implements the public `dokimo-merkle-v1` hashing scheme. It contains no proprietary
36
+ > code. MIT-licensed.
37
+
38
+ ## Tools
39
+
40
+ | Tool | What it does | Network? |
41
+ |---|---|---|
42
+ | `recompute_merkle_root(leaf, proof_path)` | **Trustless local recompute** — hash a leaf under `dokimo-merkle-v1` and replay the proof path to a root, with **no network and no trust in anyone**. Compare it to a package's claimed `root` yourself. | none |
43
+ | `verify_evidence_package(package)` | **Full verification** via Dokimo's public A2A endpoint: recompute **and** check the compound commitment (root + rule version) against the **on-chain anchor on Base**. Returns `verified: true` only if both hold. | Dokimo A2A |
44
+ | `dokimo_agent_card()` | Fetch Dokimo's public A2A agent card — what it can verify. | Dokimo |
45
+
46
+ **Verification model:** there is no path to `verified: true` without (1) the
47
+ caller's `(leaf, proof_path)` recomputing to the claimed `root`, **and** (2) the
48
+ compound commitment of `(root, rule_version_commitment)` being anchored on-chain.
49
+ Tamper one byte → recompute fails. Swap the rule version → the commitment changes
50
+ → not anchored.
51
+
52
+ **Honest scope:** attests that a *reported* figure is reproducible and
53
+ tamper-evident against an on-chain anchor — not that any underlying business
54
+ number is "good." Non-custodial; reads public on-chain state only.
55
+
56
+ ## Install & run
57
+
58
+ ```bash
59
+ pip install dokimo-mcp
60
+ dokimo-mcp # runs over stdio
61
+ # or, from a clone:
62
+ pip install .
63
+ python -m dokimo_mcp
64
+ ```
65
+
66
+ ## Add to an MCP client
67
+
68
+ **Claude Desktop** — add to `claude_desktop_config.json`:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "dokimo": {
74
+ "command": "dokimo-mcp"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ If `dokimo-mcp` isn't on `PATH`, use the module form:
81
+
82
+ ```json
83
+ {
84
+ "mcpServers": {
85
+ "dokimo": {
86
+ "command": "python",
87
+ "args": ["-m", "dokimo_mcp"]
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ Then ask the agent: *"Use Dokimo to verify this evidence package"* (paste one), or
94
+ *"recompute this Merkle root and tell me if it matches."*
95
+
96
+ ## Try it
97
+
98
+ The live demo page embeds a real, anchored evidence package. Fetch it and verify:
99
+
100
+ ```python
101
+ import re, json, urllib.request
102
+ import dokimo_mcp as d
103
+ html = urllib.request.urlopen(urllib.request.Request(
104
+ "https://dokimo.augaster.com/agent-audits-agents.html",
105
+ headers={"User-Agent": d._UA})).read().decode()
106
+ pkg = json.loads(re.search(r"const PKG\s*=\s*(\{.*?\})\s*;", html, re.S).group(1))
107
+ print(d.verify_evidence_package(pkg)["verified"]) # True
108
+ # tamper one unit -> False
109
+ pkg["leaf"] = pkg["leaf"].replace("1001190933933115", "1001190933933116")
110
+ print(d.verify_evidence_package(pkg)["verified"]) # False
111
+ ```
112
+
113
+ ## Hosted / HTTP mode
114
+
115
+ The default transport is **stdio** (local use). Set `MCP_TRANSPORT=http` to serve
116
+ **MCP Streamable HTTP at `/mcp`** on `$PORT` (default 8081) with CORS — the shape
117
+ hosted platforms like [Smithery](https://smithery.ai) require. The included
118
+ `Dockerfile` + `smithery.yaml` (`runtime: container`) are set up for exactly this,
119
+ so Smithery can build and host it from this repo.
120
+
121
+ ```bash
122
+ MCP_TRANSPORT=http PORT=8081 dokimo-mcp # or: docker run -p 8081:8081 <image>
123
+ ```
124
+
125
+ ## What is Dokimo?
126
+
127
+ Verifiable revenue infrastructure for autonomous commerce — audit-ready, independently
128
+ reproducible books for AI-agent machine payments (x402 / AP2 / Stripe), with each figure
129
+ tamper-evidently committed and anchored on-chain. https://dokimo.augaster.com
130
+
131
+ ## License
132
+
133
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ dokimo_mcp.py
4
+ pyproject.toml
5
+ dokimo_mcp.egg-info/PKG-INFO
6
+ dokimo_mcp.egg-info/SOURCES.txt
7
+ dokimo_mcp.egg-info/dependency_links.txt
8
+ dokimo_mcp.egg-info/entry_points.txt
9
+ dokimo_mcp.egg-info/requires.txt
10
+ dokimo_mcp.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dokimo-mcp = dokimo_mcp:main
@@ -0,0 +1,2 @@
1
+ mcp<2,>=1.2
2
+ uvicorn>=0.30
@@ -0,0 +1 @@
1
+ dokimo_mcp
@@ -0,0 +1,198 @@
1
+ """Dokimo MCP server — give an AI agent the ability to verify another agent's
2
+ revenue claims.
3
+
4
+ A self-contained Model Context Protocol server exposing three tools:
5
+
6
+ - ``recompute_merkle_root`` — PURE, LOCAL, trustless: recompute a
7
+ ``dokimo-merkle-v1`` root from a leaf + proof path, with no network and no
8
+ trust in anyone. The "check the math yourself" primitive.
9
+ - ``verify_evidence_package`` — full verification via Dokimo's public A2A
10
+ endpoint: recompute + on-chain anchor check, returning a signed-off verdict.
11
+ - ``dokimo_agent_card`` — fetch Dokimo's public A2A agent card.
12
+
13
+ This is a thin CLIENT: it talks to Dokimo's public endpoints and implements the
14
+ public ``dokimo-merkle-v1`` hashing scheme (RFC-6962-style, domain-separated).
15
+ It contains no proprietary code.
16
+
17
+ Verification model: there is NO path to ``verified: true`` without BOTH
18
+ (1) the caller's ``(leaf, proof_path)`` recomputing to the claimed root, AND
19
+ (2) the compound commitment of ``(root, rule_version_commitment)`` being anchored
20
+ on-chain. Tamper one byte → recompute fails. Swap the rule version → the compound
21
+ commitment changes → not anchored.
22
+
23
+ Honest scope: attests that a *reported* figure is reproducible and tamper-evident
24
+ against an on-chain anchor — not that any underlying business number is "good."
25
+
26
+ Run: ``dokimo-mcp`` (after ``pip install dokimo-mcp``), or ``python -m dokimo_mcp``.
27
+ Live demo the tools mirror: https://dokimo.augaster.com/agent-audits-agents.html
28
+ """
29
+ from __future__ import annotations
30
+
31
+ import hashlib
32
+ import json
33
+ import os
34
+ import urllib.request
35
+ from typing import Annotated, Any
36
+
37
+ from mcp.server.fastmcp import FastMCP
38
+ from mcp.types import ToolAnnotations
39
+ from pydantic import Field
40
+
41
+ # Public Dokimo endpoints by default. Override (e.g. a self-hosted deploy pointing
42
+ # at an internal address to avoid a hairpin) via DOKIMO_A2A_URL / DOKIMO_AGENT_CARD_URL.
43
+ DOKIMO_A2A = os.environ.get("DOKIMO_A2A_URL", "https://dokimo.augaster.com/a2a")
44
+ DOKIMO_AGENT_CARD = os.environ.get(
45
+ "DOKIMO_AGENT_CARD_URL", "https://dokimo.augaster.com/.well-known/agent-card.json")
46
+
47
+ # A real User-Agent — the default Python-urllib UA is 403'd by the CDN's bot filter.
48
+ _UA = "dokimo-mcp/0.1 (+https://dokimo.augaster.com)"
49
+
50
+ # --- the public dokimo-merkle-v1 scheme (documented on the public site/demo) ----
51
+ # Domain separation: leaves H(0x00 ‖ leaf), internal nodes H(0x01 ‖ left ‖ right),
52
+ # over the hex-string representations. No proprietary logic — the published scheme.
53
+ MERKLE_SCHEME = "dokimo-merkle-v1"
54
+ _LEAF_PREFIX = b"\x00"
55
+ _NODE_PREFIX = b"\x01"
56
+
57
+
58
+ def _hash_leaf(leaf: str) -> str:
59
+ return hashlib.sha256(_LEAF_PREFIX + leaf.encode()).hexdigest()
60
+
61
+
62
+ def _hash_node(a: str, b: str) -> str:
63
+ return hashlib.sha256(_NODE_PREFIX + a.encode() + b.encode()).hexdigest()
64
+
65
+
66
+ mcp = FastMCP("dokimo")
67
+
68
+
69
+ def _post_json(url: str, payload: dict, timeout: float = 25.0) -> Any:
70
+ data = json.dumps(payload).encode()
71
+ req = urllib.request.Request(
72
+ url, data=data,
73
+ headers={"Content-Type": "application/json", "User-Agent": _UA})
74
+ with urllib.request.urlopen(req, timeout=timeout) as resp:
75
+ return json.loads(resp.read())
76
+
77
+
78
+ def _get_json(url: str, timeout: float = 25.0) -> Any:
79
+ req = urllib.request.Request(url, headers={"User-Agent": _UA})
80
+ with urllib.request.urlopen(req, timeout=timeout) as resp:
81
+ return json.loads(resp.read())
82
+
83
+
84
+ @mcp.tool(annotations=ToolAnnotations(
85
+ title="Recompute Merkle root (local)",
86
+ readOnlyHint=True, idempotentHint=True, openWorldHint=False))
87
+ def recompute_merkle_root(
88
+ leaf: Annotated[str, Field(description=(
89
+ "The raw leaf value (e.g. a JSON string like '{\"k\":\"total_assets\",\"v\":\"...\"}'). "
90
+ "Hashed in the leaf domain as H(0x00 ‖ leaf)."))],
91
+ proof_path: Annotated[list, Field(description=(
92
+ "Ordered Merkle proof path: a list of [sibling_hash_hex, side] pairs, where side is "
93
+ "\"L\" if the sibling is on the left or \"R\" if on the right. Empty list for a single-leaf tree."))],
94
+ ) -> dict:
95
+ """Trustlessly recompute a dokimo-merkle-v1 root — LOCAL, no network, no trust.
96
+
97
+ Hash ``leaf`` in the leaf domain (H(0x00 ‖ leaf)) and replay ``proof_path`` —
98
+ a list of ``[sibling_hash, side]`` where side is "L" or "R" — hashing internal
99
+ nodes as H(0x01 ‖ left ‖ right). Compare the returned root to the ``root`` in an
100
+ evidence package yourself; if it differs, the package was tampered with.
101
+
102
+ Returns ``{recomputed_root, merkle_scheme, steps}``.
103
+ """
104
+ path = [(str(h), str(s)) for h, s in proof_path]
105
+ for _, side in path:
106
+ if side not in ("L", "R"):
107
+ raise ValueError("each proof_path side must be 'L' or 'R'")
108
+ acc = _hash_leaf(leaf)
109
+ for sibling, side in path:
110
+ acc = _hash_node(sibling, acc) if side == "L" else _hash_node(acc, sibling)
111
+ return {"recomputed_root": acc, "merkle_scheme": MERKLE_SCHEME, "steps": len(path)}
112
+
113
+
114
+ @mcp.tool(annotations=ToolAnnotations(
115
+ title="Verify evidence package (on-chain)",
116
+ readOnlyHint=True, idempotentHint=True, openWorldHint=True))
117
+ def verify_evidence_package(
118
+ package: Annotated[dict, Field(description=(
119
+ "The Dokimo evidence package to verify. Required keys: 'leaf' (str), 'root' (str), "
120
+ "'proof_path' (list of [sibling_hash, \"L\"|\"R\"]), and 'rule_version_commitment' (str). "
121
+ "'close_id' (str) is optional and echoed back."))],
122
+ ) -> dict:
123
+ """Fully verify a Dokimo evidence package against the LIVE on-chain anchor.
124
+
125
+ Sends the package to Dokimo's public A2A endpoint, which recomputes the Merkle
126
+ proof AND checks the compound commitment (root + rule version) against the
127
+ anchor on Base. ``package`` must contain: ``leaf`` (str), ``root`` (str),
128
+ ``proof_path`` (list of [sibling_hash, "L"|"R"]), and
129
+ ``rule_version_commitment`` (str); ``close_id`` is optional/echoed.
130
+
131
+ Returns the verdict: ``{verified, checks:{recompute, onchain_anchor,
132
+ rule_version_bound}, ...}``. ``verified`` is true only if the proof recomputes
133
+ AND the commitment is anchored on-chain.
134
+ """
135
+ payload = {
136
+ "jsonrpc": "2.0", "id": "dokimo-mcp", "method": "SendMessage",
137
+ "params": {"message": {"role": "user", "parts": [{"data": package}]}},
138
+ }
139
+ resp = _post_json(DOKIMO_A2A, payload)
140
+ if isinstance(resp, dict) and resp.get("error"):
141
+ return {"verified": False, "error": resp["error"]}
142
+ result = resp.get("result", {}) if isinstance(resp, dict) else {}
143
+ task = result.get("task", result) # v1.0.1 wraps in {task:...}; legacy is bare
144
+ for artifact in (task.get("artifacts") or []):
145
+ for part in (artifact.get("parts") or []):
146
+ if isinstance(part.get("data"), dict):
147
+ return part["data"]
148
+ return {"verified": False, "error": "no verdict artifact in A2A response", "raw": resp}
149
+
150
+
151
+ @mcp.tool(annotations=ToolAnnotations(
152
+ title="Fetch Dokimo agent card",
153
+ readOnlyHint=True, idempotentHint=True, openWorldHint=True))
154
+ def dokimo_agent_card() -> dict:
155
+ """Fetch Dokimo's public A2A agent card — the discovery document describing what
156
+ it can verify (skills, endpoints, supported A2A versions)."""
157
+ return _get_json(DOKIMO_AGENT_CARD)
158
+
159
+
160
+ def main() -> None:
161
+ """Console-script entry point (``dokimo-mcp``).
162
+
163
+ Default transport is **stdio** (local use — Claude Desktop, IDE agents).
164
+ Set ``MCP_TRANSPORT=http`` (as the container image does) to serve **Streamable
165
+ HTTP at /mcp** on ``$PORT`` (default 8081) with CORS — the shape Smithery's
166
+ hosted deployments require.
167
+ """
168
+ transport = os.environ.get("MCP_TRANSPORT", "stdio").lower()
169
+ if transport in ("http", "streamable-http", "shttp"):
170
+ import uvicorn
171
+ from starlette.middleware.cors import CORSMiddleware
172
+ from mcp.server.transport_security import TransportSecuritySettings
173
+
174
+ port = int(os.environ.get("PORT", "8081"))
175
+ mcp.settings.host = "0.0.0.0"
176
+ mcp.settings.port = port
177
+ # DNS-rebinding protection defaults to localhost-only hosts/origins; that
178
+ # protects *local* servers from malicious sites. This is a public, hosted,
179
+ # read-only verifier (calls only public endpoints), and it sits behind a
180
+ # host (Smithery) that sets its own Host/Origin — so allow any.
181
+ mcp.settings.transport_security = TransportSecuritySettings(
182
+ enable_dns_rebinding_protection=False,
183
+ )
184
+ app = mcp.streamable_http_app() # serves MCP at /mcp
185
+ app.add_middleware(
186
+ CORSMiddleware,
187
+ allow_origins=["*"],
188
+ allow_methods=["*"],
189
+ allow_headers=["*"],
190
+ expose_headers=["mcp-session-id"], # Smithery/browser clients need this
191
+ )
192
+ uvicorn.run(app, host="0.0.0.0", port=port)
193
+ else:
194
+ mcp.run() # stdio
195
+
196
+
197
+ if __name__ == "__main__":
198
+ main()
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dokimo-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server to verify AI-agent revenue claims: recompute a Merkle proof and check it against an on-chain anchor."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Augaster Technologies" }]
14
+ keywords = ["mcp", "model-context-protocol", "x402", "agentic-payments", "merkle", "verification", "agents"]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Topic :: Security",
18
+ ]
19
+ dependencies = [
20
+ # Pinned to the 1.x line: this server uses the FastMCP API, which mcp 2.x
21
+ # renamed to MCPServer. Keeps a fresh container install (Smithery) on the API
22
+ # this code targets.
23
+ "mcp>=1.2,<2",
24
+ "uvicorn>=0.30", # serving Streamable HTTP at /mcp for hosted (Smithery) deploys
25
+ ]
26
+
27
+ [project.scripts]
28
+ dokimo-mcp = "dokimo_mcp:main"
29
+
30
+ [project.urls]
31
+ Homepage = "https://dokimo.augaster.com"
32
+ Demo = "https://dokimo.augaster.com/agent-audits-agents.html"
33
+ Repository = "https://github.com/ypratap11/dokimo-mcp"
34
+ Issues = "https://github.com/ypratap11/dokimo-mcp/issues"
35
+
36
+ [tool.setuptools]
37
+ py-modules = ["dokimo_mcp"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+