jep-mcp-wrapper
jep-mcp-wrapper adds verifiable accountability semantics to MCP tool execution without changing the MCP protocol. Existing tool callables are wrapped in a side-channel JEP runtime that emits deterministic, append-only events for each execution lifecycle step.
What it provides
JEPMCPWrapperwraps sync and async MCP tool callables.MCPExecutionTracerwrites lifecycle events (requested,running,succeeded,failed).ToolDelegationRuntimetracks the active actor, delegation lineage, parent context, and authority scope across nested tool calls.ReplayVerifierreplays archived execution chains, verifies lineage, validates deterministic hashes, and detects archive tampering.AppendOnlyEventArchivestores JSONL events as an append-only hash chain.
The wrapper records:
tool_nameactor- delegation lineage
- authority scope
- execution state
- parent event linkage
- deterministic event hash and previous hash
Quick start
from pathlib import Path
from jep_mcp_wrapper import JEPMCPWrapper, ReplayVerifier
archive = "jep-events.jsonl"
wrapper = JEPMCPWrapper(
archive,
default_actor="agent:file-reader",
default_authority_scope={"filesystem": "read-only"},
)
def read_file(path: str) -> str:
return Path(path).read_text(encoding="utf-8")
read_file = wrapper.wrap_tool("filesystem.read_file", read_file)
print(read_file("README.md"))
replay = ReplayVerifier(archive).replay()
assert replay.verified
Chained delegation
Nested wrapped calls automatically extend lineage. A search.query tool that calls a wrapped browser.fetch tool produces two execution chains: one with ("search.query",) and one with ("search.query", "browser.fetch").
from jep_mcp_wrapper import JEPMCPWrapper
wrapper = JEPMCPWrapper("events.jsonl", default_actor="agent:researcher")
def browser_fetch(url: str) -> str:
return f"page:{url}"
def search(query: str, fetch) -> str:
return fetch(f"https://example.test?q={query}")
fetch = wrapper.wrap_tool("browser.fetch", browser_fetch, authority_scope={"network": "example.test"})
search = wrapper.wrap_tool("search.query", search, authority_scope={"purpose": "research"})
search("accountability", fetch=fetch)
Replay and tamper detection
from jep_mcp_wrapper import ReplayVerifier
verifier = ReplayVerifier("events.jsonl")
result = verifier.replay()
print(result.verified)
print(result.lineage_by_call)
print(verifier.detect_tampering())
Replay verification checks:
- deterministic hash equality for every event,
- previous-hash continuity across the append-only archive,
- monotonic event sequence numbers,
- valid tool lifecycle transitions,
- stable lineage for every tool call,
- parent/child lineage consistency when parent links are present.
Examples
examples/filesystem_tool.pywraps a filesystem read tool.examples/browser_search_chain.pywraps browser and search tools with chained delegation.
Non-goals
- It does not modify MCP protocol schemas or wire semantics.
- It does not implement an orchestration framework.
- It does not decide whether a tool is authorized; it records the declared authority scope so execution can be audited and replayed.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jep_mcp_wrapper-0.1.1.tar.gz.
File metadata
- Download URL: jep_mcp_wrapper-0.1.1.tar.gz
- Upload date:
- Size: 11.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d71afda56d0fa53103998434a975ad647dfa008a1bc159df0d922d7bca760ce7
|
|
| MD5 |
160c7111e7a47c95cca6e66b49374a9b
|
|
| BLAKE2b-256 |
76aab7266df8128b90bb7081fafbc2cda90542d259df26d3351faad7a64092f8
|
Provenance
The following attestation bundles were made for jep_mcp_wrapper-0.1.1.tar.gz:
Publisher:
release.yml on hjs-spec/jep-mcp-wrapper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jep_mcp_wrapper-0.1.1.tar.gz -
Subject digest:
d71afda56d0fa53103998434a975ad647dfa008a1bc159df0d922d7bca760ce7 - Sigstore transparency entry: 2813987354
- Sigstore integration time:
-
Permalink:
hjs-spec/jep-mcp-wrapper@b824b3e163bb25ac373279c4c31ba6d9e22a1ccc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hjs-spec
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b824b3e163bb25ac373279c4c31ba6d9e22a1ccc -
Trigger Event:
push
-
Statement type:
File details
Details for the file jep_mcp_wrapper-0.1.1-py3-none-any.whl.
File metadata
- Download URL: jep_mcp_wrapper-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6ec5e7d92b0eea70c9186af08d9ba08cb829fc758577bfb27515ed4ff3a722c
|
|
| MD5 |
e301c1bb0911e8fb7ab58d833cd8e24d
|
|
| BLAKE2b-256 |
405558d2515f93a13737c9b9f81ea42cf84ba7e8c8cedbef84bab8674247be5c
|
Provenance
The following attestation bundles were made for jep_mcp_wrapper-0.1.1-py3-none-any.whl:
Publisher:
release.yml on hjs-spec/jep-mcp-wrapper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jep_mcp_wrapper-0.1.1-py3-none-any.whl -
Subject digest:
d6ec5e7d92b0eea70c9186af08d9ba08cb829fc758577bfb27515ed4ff3a722c - Sigstore transparency entry: 2813987419
- Sigstore integration time:
-
Permalink:
hjs-spec/jep-mcp-wrapper@b824b3e163bb25ac373279c4c31ba6d9e22a1ccc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hjs-spec
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b824b3e163bb25ac373279c4c31ba6d9e22a1ccc -
Trigger Event:
push
-
Statement type: