ZAP - Zero-Copy App Proto for Python
Project description
ZAP Python
Docs: ZAP Python SDK · part of the ZAP Protocol
zap-proto is the Python implementation of ZAP (Zero-Copy App Proto): a
zero-copy binary wire format plus a small RPC layer for AI-agent communication.
The core — the wire codec, router envelope, JSON framing, RPC client/server,
identity, and consensus — is pure standard library. import zap pulls no
third-party dependency.
Installation
pip install zap-proto
# or
uv add zap-proto
Optional extras:
pip install "zap-proto[crypto]" # real ML-KEM-768 / ML-DSA-65 / X25519
pip install "zap-proto[app]" # the FastMCP-style decorator app (pydantic)
Wire format (the core)
The zero-copy codec is byte-for-byte compatible with the canonical Go runtime
(zap-proto/go) — the same 16-byte ZAP\x00 header, the same fixed-offset
struct layout. A buffer this library writes is read by Go and vice versa.
from zap import Builder, parse
# Build a message: field @0 uint32, @8 text, @16 bytes.
b = Builder()
obj = b.start_object(24)
obj.set_uint32(0, 0xDEADBEEF)
obj.set_text(8, "zap")
obj.set_bytes(16, b"\x01\x02\x03\x04")
obj.finish_as_root()
buf = b.finish()
# Read it back with zero copy.
root = parse(buf).root()
assert root.uint32(0) == 0xDEADBEEF
assert root.text(8) == "zap"
assert root.bytes(16) == b"\x01\x02\x03\x04"
Lists (flat fixed-stride and variable-element) and nested objects are supported; the reader rejects out-of-bounds and backward pointers that would alias the wire header, and clamps list lengths — so an adversarial buffer that Go rejects is rejected here too.
RPC
A real request/response transport over TCP, dispatching the Zap interface
method ordinals declared in zap.zap.
Server (decorator app — needs [app])
from zap import ZAP, PromptMessage
app = ZAP("my-agent", version="1.0.0")
@app.tool
def search(query: str, limit: int = 10) -> list[dict]:
"""Search for content in the knowledge base"""
return [{"title": f"Result for {query}", "score": 0.95}]
@app.resource("file://{path}")
def read_file(path: str) -> str:
"""Read a file from disk"""
return open(path).read()
@app.prompt
def greeting(name: str) -> list[PromptMessage]:
"""Generate a personalized greeting"""
return [PromptMessage(role="assistant", content=f"Hello, {name}!")]
if __name__ == "__main__":
app.run(port=9999) # serves real ZAP RPC
Client
from zap import Client
with Client("localhost:9999") as client:
info = client.connect()
tools = client.list_tools()
result = client.call_tool("search", {"query": "hello world"})
print(result.content) # bytes
content = client.read_resource("file:///tmp/test.txt")
print(content.text)
Router client
ZapClient talks to the local zapd router over its Unix domain socket
(byte-compatible with zap-proto/zapd's frame codec). Used by
hanzo-tools-browser's zapd_consumer.
from zap import ZapClient, frame
c = ZapClient.connect(id="consumer:hanzo-mcp/123", role="consumer")
providers = c.providers_list(kind="browser")
reply = c.route(to=providers[0].id, payload=frame.encode_cmd("Target.getTargets", {}))
Post-quantum cryptography (needs [crypto])
Real ML-KEM-768 (FIPS 203) + ML-DSA-65 (FIPS 204) via pqcrypto, classical
X25519 via cryptography, mixed with HKDF-SHA256. There is no silent fallback:
if a backend is missing, every operation raises CryptoError.
from zap import HybridKeyExchange
alice = HybridKeyExchange.generate()
bob = HybridKeyExchange.generate()
a_x_pub, a_k_pub = alice.initiate()
b_x_pub, ciphertext, bob_secret = bob.respond(a_x_pub, a_k_pub)
alice_secret = alice.finalize(b_x_pub, ciphertext)
assert alice_secret == bob_secret # both sides agree
Agent consensus
from zap import AgentConsensus, Query, Response, DID, DIDMethod
consensus = AgentConsensus()
agent = DID(method=DIDMethod.KEY, id="z6MkAgent...")
query = Query.create("What is the capital of France?", agent)
consensus.submit_query(query)
Related packages
- zap-proto/go — canonical Go runtime
- zap-proto/js — JavaScript/TypeScript
- zap-proto/spec — schema + reference
License
MIT
Project details
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 zap_proto-1.2.0.tar.gz.
File metadata
- Download URL: zap_proto-1.2.0.tar.gz
- Upload date:
- Size: 66.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c741a0534abd77f393a639d5bded2a00b755bbc59d0e71c6f197ce79e66a86b5
|
|
| MD5 |
12424abec89aa0715ca835bf6d1ffc74
|
|
| BLAKE2b-256 |
b9c2d2d1882c2a93caf9882c9ada7d3094bf5baa7ab183db38d88c5833537d2c
|
File details
Details for the file zap_proto-1.2.0-py3-none-any.whl.
File metadata
- Download URL: zap_proto-1.2.0-py3-none-any.whl
- Upload date:
- Size: 34.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e58a83e4df5ff8b02b4104b7c91795179ddf7f74e168f91f86dfe85ead634d16
|
|
| MD5 |
c8641f0c2e0bfd6ce12a15fbbcb344df
|
|
| BLAKE2b-256 |
33f3c30f66b6755f80ba76434f389a7de2a9bada3facc8d6987e79058cf1d4ad
|