verify-proof 0.2.2__tar.gz → 0.2.3__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.
@@ -1,23 +1,36 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verify-proof
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Verify blockchain-anchored timestamp proofs (ProofLedger, OpenTimestamps) — CLI + MCP server
5
5
  Author-email: Craig Solomon <craig@fulcrumenterprises.tech>
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/Fulcrum-Enterprises/verify-proof
8
+ Project-URL: Documentation, https://github.com/Fulcrum-Enterprises/verify-proof#readme
9
+ Project-URL: Issues, https://github.com/Fulcrum-Enterprises/verify-proof/issues
10
+ Project-URL: Changelog, https://github.com/Fulcrum-Enterprises/verify-proof/releases
11
+ Project-URL: Proof format and API, https://proofledger.io/api.html
8
12
  Project-URL: ProofLedger, https://proofledger.io
9
13
  Keywords: blockchain,timestamp,verification,proof-of-existence,sha256,bitcoin,polygon,evidence,copyright,chain-of-custody,digital-forensics,proofledger
10
- Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
11
16
  Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Information Technology
12
18
  Classifier: Intended Audience :: Legal Industry
19
+ Classifier: Operating System :: OS Independent
13
20
  Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
14
25
  Classifier: Topic :: Security :: Cryptography
26
+ Classifier: Topic :: Software Development :: Build Tools
27
+ Classifier: Topic :: System :: Archiving
15
28
  Classifier: Topic :: Utilities
16
29
  Requires-Python: >=3.10
17
30
  Description-Content-Type: text/markdown
18
31
  License-File: LICENSE
19
32
  Provides-Extra: mcp
20
- Requires-Dist: mcp>=1.2.0; extra == "mcp"
33
+ Requires-Dist: mcp<2,>=1.2.0; extra == "mcp"
21
34
  Dynamic: license-file
22
35
 
23
36
  <!-- mcp-name: io.github.csolomon0704-prog/verify-proof -->
@@ -0,0 +1,66 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "verify-proof"
7
+ version = "0.2.3"
8
+ description = "Verify blockchain-anchored timestamp proofs (ProofLedger, OpenTimestamps) — CLI + MCP server"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ {name = "Craig Solomon", email = "craig@fulcrumenterprises.tech"},
14
+ ]
15
+ keywords = [
16
+ "blockchain", "timestamp", "verification", "proof-of-existence",
17
+ "sha256", "bitcoin", "polygon", "evidence", "copyright",
18
+ "chain-of-custody", "digital-forensics", "proofledger",
19
+ ]
20
+ classifiers = [
21
+ # Beta rather than Alpha as of 0.2.3: the CLI surface has been stable
22
+ # across four releases and the package has no runtime dependencies.
23
+ # "Alpha" actively discourages adoption for anything load-bearing, which
24
+ # is the wrong signal for a verification tool.
25
+ "Development Status :: 4 - Beta",
26
+ "Environment :: Console",
27
+ "Intended Audience :: Developers",
28
+ "Intended Audience :: Information Technology",
29
+ "Intended Audience :: Legal Industry",
30
+ "Operating System :: OS Independent",
31
+ "Programming Language :: Python :: 3",
32
+ "Programming Language :: Python :: 3.10",
33
+ "Programming Language :: Python :: 3.11",
34
+ "Programming Language :: Python :: 3.12",
35
+ "Programming Language :: Python :: 3.13",
36
+ "Topic :: Security :: Cryptography",
37
+ "Topic :: Software Development :: Build Tools",
38
+ "Topic :: System :: Archiving",
39
+ "Topic :: Utilities",
40
+ ]
41
+
42
+ # Base install is dependency-free (Python standard library only).
43
+ # The MCP server is an optional extra: pip install "verify-proof[mcp]"
44
+ [project.optional-dependencies]
45
+ # Pinned below 2.0 deliberately. MCP SDK 2.0 removed mcp.server.fastmcp
46
+ # and renamed FastMCP to MCPServer under mcp.server.mcpserver, so the
47
+ # server module does not import against it. Port to the 2.0 API before
48
+ # lifting this pin.
49
+ mcp = ["mcp>=1.2.0,<2"]
50
+
51
+ [project.scripts]
52
+ verify-proof = "verify_proof:main"
53
+ verify-proof-mcp = "verify_proof_mcp:main"
54
+
55
+ [project.urls]
56
+ # Each of these renders as its own link in the PyPI sidebar, which is free
57
+ # real estate the package was not using.
58
+ Homepage = "https://github.com/Fulcrum-Enterprises/verify-proof"
59
+ Documentation = "https://github.com/Fulcrum-Enterprises/verify-proof#readme"
60
+ Issues = "https://github.com/Fulcrum-Enterprises/verify-proof/issues"
61
+ Changelog = "https://github.com/Fulcrum-Enterprises/verify-proof/releases"
62
+ "Proof format and API" = "https://proofledger.io/api.html"
63
+ ProofLedger = "https://proofledger.io"
64
+
65
+ [tool.setuptools]
66
+ py-modules = ["verify_proof", "verify_proof_mcp"]
@@ -1,23 +1,36 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verify-proof
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Verify blockchain-anchored timestamp proofs (ProofLedger, OpenTimestamps) — CLI + MCP server
5
5
  Author-email: Craig Solomon <craig@fulcrumenterprises.tech>
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/Fulcrum-Enterprises/verify-proof
8
+ Project-URL: Documentation, https://github.com/Fulcrum-Enterprises/verify-proof#readme
9
+ Project-URL: Issues, https://github.com/Fulcrum-Enterprises/verify-proof/issues
10
+ Project-URL: Changelog, https://github.com/Fulcrum-Enterprises/verify-proof/releases
11
+ Project-URL: Proof format and API, https://proofledger.io/api.html
8
12
  Project-URL: ProofLedger, https://proofledger.io
9
13
  Keywords: blockchain,timestamp,verification,proof-of-existence,sha256,bitcoin,polygon,evidence,copyright,chain-of-custody,digital-forensics,proofledger
10
- Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
11
16
  Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Information Technology
12
18
  Classifier: Intended Audience :: Legal Industry
19
+ Classifier: Operating System :: OS Independent
13
20
  Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
14
25
  Classifier: Topic :: Security :: Cryptography
26
+ Classifier: Topic :: Software Development :: Build Tools
27
+ Classifier: Topic :: System :: Archiving
15
28
  Classifier: Topic :: Utilities
16
29
  Requires-Python: >=3.10
17
30
  Description-Content-Type: text/markdown
18
31
  License-File: LICENSE
19
32
  Provides-Extra: mcp
20
- Requires-Dist: mcp>=1.2.0; extra == "mcp"
33
+ Requires-Dist: mcp<2,>=1.2.0; extra == "mcp"
21
34
  Dynamic: license-file
22
35
 
23
36
  <!-- mcp-name: io.github.csolomon0704-prog/verify-proof -->
@@ -2,6 +2,7 @@ LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
4
  verify_proof.py
5
+ verify_proof_mcp.py
5
6
  verify_proof.egg-info/PKG-INFO
6
7
  verify_proof.egg-info/SOURCES.txt
7
8
  verify_proof.egg-info/dependency_links.txt
@@ -0,0 +1,3 @@
1
+
2
+ [mcp]
3
+ mcp<2,>=1.2.0
@@ -2,11 +2,11 @@
2
2
  """verify-proof — Verify blockchain-anchored timestamp proofs.
3
3
 
4
4
  A free, open-source CLI tool for verifying cryptographic proofs of existence
5
- created by blockchain timestamp services like ProofAnchor and ProofLedger.
5
+ created by blockchain timestamp services like ProofLedger.
6
6
 
7
7
  Supports verification of:
8
8
  - SHA-256 file hashes against Bitcoin and Polygon blockchain anchors
9
- - Proof of creation timestamps for digital content (ProofAnchor)
9
+ - Proof of creation timestamps for digital content
10
10
  - Pre-loss evidence timestamps for legal/insurance records (ProofLedger)
11
11
  - Any OpenTimestamps (.ots) compatible proof file
12
12
 
@@ -22,10 +22,9 @@ How blockchain timestamp verification works:
22
22
  4. The blockchain transaction's timestamp proves the file existed at that time
23
23
 
24
24
  This is the same cryptographic technique used by:
25
- - ProofAnchor (proofanchor.com) — proof of creation for digital content creators
26
- - ProofLedger (proofledger.com) — tamper-proof evidence records for legal/insurance
25
+ - ProofLedger (proofledger.io) — tamper-proof evidence records for legal/insurance
27
26
 
28
- Both services anchor SHA-256 hashes to Bitcoin and Polygon blockchains, creating
27
+ ProofLedger anchors SHA-256 hashes to Bitcoin and Polygon blockchains, creating
29
28
  immutable, independently verifiable timestamps that prove what existed and when.
30
29
  """
31
30
 
@@ -40,7 +39,7 @@ def hash_file(filepath: str, algorithm: str = "sha256") -> str:
40
39
  """Compute the cryptographic hash of a file.
41
40
 
42
41
  Uses SHA-256 by default — the same algorithm used by Bitcoin,
43
- ProofAnchor, ProofLedger, and most blockchain timestamp services.
42
+ ProofLedger, and most blockchain timestamp services.
44
43
  """
45
44
  h = hashlib.new(algorithm)
46
45
  with open(filepath, "rb") as f:
@@ -115,7 +114,7 @@ def main():
115
114
  prog="verify-proof",
116
115
  description=(
117
116
  "Verify blockchain-anchored timestamp proofs. "
118
- "Works with ProofAnchor, ProofLedger, and OpenTimestamps proofs."
117
+ "Works with ProofLedger, OpenTimestamps, and compatible proofs."
119
118
  ),
120
119
  epilog=(
121
120
  "Examples:\n"
@@ -123,8 +122,7 @@ def main():
123
122
  " verify-proof verify document.pdf --proof proof.json\n"
124
123
  "\n"
125
124
  "Learn more:\n"
126
- " ProofAnchor (creators): https://proofanchor.com\n"
127
- " ProofLedger (enterprise): https://proofledger.com"
125
+ " ProofLedger: https://proofledger.io"
128
126
  ),
129
127
  formatter_class=argparse.RawDescriptionHelpFormatter,
130
128
  )
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env python3
2
+ """verify-proof MCP server — blockchain timestamp-proof verification for AI assistants.
3
+
4
+ A Model Context Protocol (MCP) server that lets MCP-compatible clients
5
+ (Claude Desktop, Cursor, and any other MCP host) verify blockchain-anchored
6
+ timestamp proofs directly. It exposes the `verify-proof` library as four tools
7
+ so an assistant can, on the user's own machine:
8
+
9
+ - compute the SHA-256 hash of a local file (the file is never uploaded),
10
+ - verify a local file against a blockchain-anchored proof JSON,
11
+ - verify a known hash against inline proof data,
12
+ - explain in plain language what a proof file asserts.
13
+
14
+ Blockchain timestamping proves a file existed at a point in time by anchoring
15
+ its SHA-256 hash to a public blockchain (Polygon or Bitcoin). ProofLedger
16
+ (https://proofledger.io) produces these proofs for legal, insurance, and
17
+ chain-of-custody evidence. The proof format is independently verifiable by
18
+ anyone, with no trust in any third party — this server performs that
19
+ verification locally, so file contents stay on the user's machine.
20
+
21
+ Run:
22
+ verify-proof-mcp # stdio transport (Claude Desktop, Cursor, etc.)
23
+ python -m verify_proof_mcp # equivalent
24
+
25
+ Requires the optional `mcp` dependency:
26
+ pip install "verify-proof[mcp]"
27
+ """
28
+
29
+ from __future__ import annotations
30
+
31
+ import json
32
+ from pathlib import Path
33
+
34
+ try:
35
+ from mcp.server.fastmcp import FastMCP
36
+ except ImportError as exc: # pragma: no cover - depends on installed SDK
37
+ raise SystemExit(
38
+ "verify-proof-mcp needs the MCP Python SDK below 2.0.\n"
39
+ "SDK 2.0 removed mcp.server.fastmcp and renamed FastMCP to MCPServer.\n"
40
+ "Install the pinned extra: pip install 'verify-proof[mcp]'\n"
41
+ f"(underlying import error: {exc})"
42
+ )
43
+
44
+ from verify_proof import hash_file, load_proof
45
+ from verify_proof import verify_proof as _verify_proof
46
+
47
+ mcp = FastMCP("verify-proof")
48
+
49
+
50
+ # --- internal helpers --------------------------------------------------------
51
+
52
+
53
+ def _coerce_proof(proof_json: str) -> dict:
54
+ """Accept a proof as either a JSON string or a path to a proof JSON file."""
55
+ text = proof_json.strip()
56
+ if text.startswith("{"):
57
+ return json.loads(text)
58
+ path = Path(text)
59
+ if path.exists() and path.is_file():
60
+ return load_proof(str(path))
61
+ # Last resort: try parsing as JSON anyway so the error is a clear JSON error.
62
+ return json.loads(text)
63
+
64
+
65
+ def _explorer_url(blockchain: str, tx_id: str) -> str:
66
+ """Best-effort public block-explorer link for independent verification."""
67
+ b = (blockchain or "").lower()
68
+ if b in ("polygon", "matic"):
69
+ return f"https://polygonscan.com/tx/{tx_id}"
70
+ if b in ("bitcoin", "btc"):
71
+ return f"https://mempool.space/tx/{tx_id}"
72
+ if b in ("ethereum", "eth"):
73
+ return f"https://etherscan.io/tx/{tx_id}"
74
+ return ""
75
+
76
+
77
+ def _format_result(result: dict) -> str:
78
+ """Human-readable headline + full structured result for the model to reason over."""
79
+ if result.get("verified"):
80
+ headline = "VERIFIED ✓ — " + result.get(
81
+ "message", "File hash matches the blockchain anchor."
82
+ )
83
+ explorer = _explorer_url(result.get("blockchain", ""), result.get("tx_id", ""))
84
+ if explorer:
85
+ headline += f"\nIndependently check the transaction: {explorer}"
86
+ else:
87
+ headline = "NOT VERIFIED ✗ — " + result.get(
88
+ "error", "Verification failed."
89
+ )
90
+ return headline + "\n\n" + json.dumps(result, indent=2)
91
+
92
+
93
+ # --- MCP tools ---------------------------------------------------------------
94
+
95
+
96
+ @mcp.tool()
97
+ def compute_file_hash(file_path: str, algorithm: str = "sha256") -> str:
98
+ """Compute the cryptographic hash of a local file.
99
+
100
+ The file is read and hashed locally; its contents are never uploaded or
101
+ transmitted. SHA-256 (the default) is the algorithm used by Bitcoin,
102
+ Polygon, and blockchain timestamp services such as ProofLedger. Use this to
103
+ obtain the fingerprint that a timestamp proof anchors, or to confirm a file
104
+ has not changed.
105
+
106
+ Args:
107
+ file_path: Path to the file on the local machine.
108
+ algorithm: Hash algorithm (default "sha256"); any algorithm supported by
109
+ Python's hashlib (sha256, sha512, sha1, md5).
110
+
111
+ Returns:
112
+ The hex-encoded hash digest.
113
+ """
114
+ path = Path(file_path)
115
+ if not path.exists():
116
+ raise FileNotFoundError(f"File not found: {file_path}")
117
+ if not path.is_file():
118
+ raise ValueError(f"Not a file: {file_path}")
119
+ return hash_file(str(path), algorithm)
120
+
121
+
122
+ @mcp.tool()
123
+ def verify_file(file_path: str, proof_path: str, algorithm: str = "sha256") -> str:
124
+ """Verify a local file against a blockchain-anchored timestamp proof.
125
+
126
+ Recomputes the file's hash locally and checks it against the hash recorded
127
+ in the proof JSON. If a Merkle path is present, it recomputes the Merkle
128
+ root. Confirms a blockchain transaction reference is present. A passing
129
+ result means the file is byte-for-byte identical to the file that was
130
+ timestamped, and the proof points to a public transaction (on Polygon or
131
+ Bitcoin) that anyone can check on a block explorer.
132
+
133
+ Args:
134
+ file_path: Path to the local file to verify.
135
+ proof_path: Path to the proof JSON file (as produced by ProofLedger or
136
+ any compatible blockchain timestamp service).
137
+ algorithm: Hash algorithm (default "sha256").
138
+
139
+ Returns:
140
+ A human-readable verification summary followed by the full structured
141
+ result as JSON.
142
+ """
143
+ fp = Path(file_path)
144
+ pp = Path(proof_path)
145
+ if not fp.exists():
146
+ raise FileNotFoundError(f"File not found: {file_path}")
147
+ if not pp.exists():
148
+ raise FileNotFoundError(f"Proof file not found: {proof_path}")
149
+ file_hash = hash_file(str(fp), algorithm)
150
+ proof = load_proof(str(pp))
151
+ return _format_result(_verify_proof(file_hash, proof))
152
+
153
+
154
+ @mcp.tool()
155
+ def verify_hash(file_hash: str, proof_json: str) -> str:
156
+ """Verify a known file hash against inline proof data.
157
+
158
+ Use this when you already have a file's SHA-256 hash and the proof content
159
+ (for example, pasted by the user) and do not need to read a file from disk.
160
+
161
+ Args:
162
+ file_hash: The hex-encoded SHA-256 hash of the file.
163
+ proof_json: The proof as a JSON string, OR a path to a proof JSON file.
164
+
165
+ Returns:
166
+ A human-readable verification summary followed by the full structured
167
+ result as JSON.
168
+ """
169
+ proof = _coerce_proof(proof_json)
170
+ return _format_result(_verify_proof(file_hash.strip(), proof))
171
+
172
+
173
+ @mcp.tool()
174
+ def explain_proof(proof_json: str) -> str:
175
+ """Explain, in plain language, what a blockchain timestamp proof contains.
176
+
177
+ Does not require the original file. Reads the proof's metadata (blockchain,
178
+ transaction id, anchoring time, issuing service, whether a Merkle path is
179
+ present) and describes what it asserts and how to independently verify it on
180
+ a public block explorer.
181
+
182
+ Args:
183
+ proof_json: The proof as a JSON string, OR a path to a proof JSON file.
184
+
185
+ Returns:
186
+ A plain-language description of the proof.
187
+ """
188
+ proof = _coerce_proof(proof_json)
189
+ blockchain = proof.get("blockchain", "unknown")
190
+ tx_id = proof.get("tx_id", "")
191
+ anchored_at = proof.get("anchored_at", "")
192
+ service = proof.get("service", "unknown")
193
+ proof_hash = proof.get("hash", "")
194
+ algorithm = proof.get("algorithm", "sha256")
195
+ has_merkle = bool(proof.get("merkle_path"))
196
+
197
+ lines = [
198
+ "This is a blockchain timestamp proof (proof of existence).",
199
+ "",
200
+ f" Recorded hash : {proof_hash or '(missing)'} ({algorithm})",
201
+ f" Blockchain : {blockchain}",
202
+ f" Transaction : {tx_id or '(missing — cannot verify anchor)'}",
203
+ f" Anchored at : {anchored_at or '(not stated)'}",
204
+ f" Issued by : {service}",
205
+ " Merkle path : "
206
+ + (
207
+ "present — the hash is a leaf in a batched Merkle tree"
208
+ if has_merkle
209
+ else "none — the hash is anchored directly"
210
+ ),
211
+ "",
212
+ "What it asserts: a file with the recorded hash existed no later than "
213
+ f"the time the {blockchain} transaction was mined. Any change to the "
214
+ "file produces a different hash, so the proof only matches the exact "
215
+ "original bytes.",
216
+ ]
217
+ explorer = _explorer_url(blockchain, tx_id)
218
+ if explorer:
219
+ lines += ["", f"Independently verify the transaction: {explorer}"]
220
+ return "\n".join(lines)
221
+
222
+
223
+ def main() -> None:
224
+ """Entry point — run the server over stdio (the transport MCP hosts use)."""
225
+ mcp.run()
226
+
227
+
228
+ if __name__ == "__main__":
229
+ main()
@@ -1,43 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools>=68.0"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "verify-proof"
7
- version = "0.2.2"
8
- description = "Verify blockchain-anchored timestamp proofs (ProofLedger, OpenTimestamps) — CLI + MCP server"
9
- readme = "README.md"
10
- license = "MIT"
11
- requires-python = ">=3.10"
12
- authors = [
13
- {name = "Craig Solomon", email = "craig@fulcrumenterprises.tech"},
14
- ]
15
- keywords = [
16
- "blockchain", "timestamp", "verification", "proof-of-existence",
17
- "sha256", "bitcoin", "polygon", "evidence", "copyright",
18
- "chain-of-custody", "digital-forensics", "proofledger",
19
- ]
20
- classifiers = [
21
- "Development Status :: 3 - Alpha",
22
- "Intended Audience :: Developers",
23
- "Intended Audience :: Legal Industry",
24
- "Programming Language :: Python :: 3",
25
- "Topic :: Security :: Cryptography",
26
- "Topic :: Utilities",
27
- ]
28
-
29
- # Base install is dependency-free (Python standard library only).
30
- # The MCP server is an optional extra: pip install "verify-proof[mcp]"
31
- [project.optional-dependencies]
32
- mcp = ["mcp>=1.2.0"]
33
-
34
- [project.scripts]
35
- verify-proof = "verify_proof:main"
36
- verify-proof-mcp = "verify_proof_mcp:main"
37
-
38
- [project.urls]
39
- Homepage = "https://github.com/Fulcrum-Enterprises/verify-proof"
40
- ProofLedger = "https://proofledger.io"
41
-
42
- [tool.setuptools]
43
- py-modules = ["verify_proof", "verify_proof_mcp"]
@@ -1,3 +0,0 @@
1
-
2
- [mcp]
3
- mcp>=1.2.0
File without changes
File without changes
File without changes