keep-protocol 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,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: keep-protocol
3
+ Version: 0.1.0
4
+ Summary: Signed protobuf packets over TCP for AI agent-to-agent communication
5
+ Author: Chris Crawford
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/CLCrawford-dev/keep-protocol
8
+ Project-URL: Repository, https://github.com/CLCrawford-dev/keep-protocol
9
+ Project-URL: Issues, https://github.com/CLCrawford-dev/keep-protocol/issues
10
+ Keywords: agent-protocol,ai-agents,protobuf,ed25519,tcp,agent-communication,mcp,multi-agent
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Communications
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: protobuf>=4.25
26
+ Requires-Dist: cryptography>=41.0
27
+
28
+ # keep-protocol
29
+
30
+ **Signed protobuf packets over TCP for AI agent-to-agent communication.**
31
+
32
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
33
+ [![Build](https://github.com/CLCrawford-dev/keep-protocol/actions/workflows/ci.yml/badge.svg)](https://github.com/CLCrawford-dev/keep-protocol/actions)
34
+
35
+ > Keep is the quiet pipe agents whisper through.
36
+ > A single TCP connection, a tiny Protobuf envelope, an ed25519 signature —
37
+ > just enough fields to say who's talking, who should listen, what they want,
38
+ > how much they'll pay, and when the message expires.
39
+ > Unsigned packets vanish without a trace. Signed ones get heard.
40
+
41
+ ---
42
+
43
+ ## Install
44
+
45
+ ### Python SDK
46
+
47
+ ```bash
48
+ pip install keep-protocol
49
+ ```
50
+
51
+ ```python
52
+ from keep.client import KeepClient
53
+
54
+ client = KeepClient("localhost", 9009)
55
+ reply = client.send(
56
+ src="bot:my-agent",
57
+ dst="server",
58
+ body="hello from my agent",
59
+ )
60
+ print(reply.body) # "done"
61
+ ```
62
+
63
+ ### Run the Server
64
+
65
+ **Docker (recommended):**
66
+ ```bash
67
+ docker run -d -p 9009:9009 --name keep ghcr.io/clcrawford-dev/keep-server:latest
68
+ ```
69
+
70
+ **From source:**
71
+ ```bash
72
+ git clone https://github.com/CLCrawford-dev/keep-protocol.git
73
+ cd keep-protocol
74
+ go build -o keep .
75
+ ./keep # listens on :9009
76
+ ```
77
+
78
+ ### Verify It Works
79
+
80
+ ```bash
81
+ pip install keep-protocol
82
+ python -c "
83
+ from keep.client import KeepClient
84
+ reply = KeepClient('localhost', 9009).send(body='ping')
85
+ print('OK' if reply.body == 'done' else 'FAIL')
86
+ "
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Why Keep?
92
+
93
+ | Feature | Keep | HTTP/REST | gRPC | NATS |
94
+ |---------|------|-----------|------|------|
95
+ | Latency | Sub-ms (TCP) | 1-10ms | 1-5ms | 1-5ms |
96
+ | Auth | ed25519 built-in | Bring your own | mTLS | Tokens |
97
+ | Schema | 10 fields, done | Unlimited | Unlimited | None |
98
+ | Setup | 1 binary, 0 config | Web server + routes | Codegen + server | Broker cluster |
99
+ | Agent-native | Yes | No | No | Partial |
100
+ | Spam resistance | fee + ttl fields | None | None | None |
101
+
102
+ Keep is not a replacement for gRPC or NATS. It is a protocol for agents that
103
+ need to find each other and exchange signed intent with minimal ceremony.
104
+
105
+ ---
106
+
107
+ ## Packet Schema
108
+
109
+ ```protobuf
110
+ message Packet {
111
+ bytes sig = 1; // ed25519 signature (64 bytes)
112
+ bytes pk = 2; // sender's public key (32 bytes)
113
+ uint32 typ = 3; // 0=ask, 1=offer, 2=heartbeat
114
+ string id = 4; // unique message ID
115
+ string src = 5; // sender: "bot:my-agent" or "human:chris"
116
+ string dst = 6; // destination: "server", "nearest:weather", "swarm:planner"
117
+ string body = 7; // intent or payload
118
+ uint64 fee = 8; // micro-fee in sats (anti-spam)
119
+ uint32 ttl = 9; // time-to-live in seconds
120
+ bytes scar = 10; // gitmem-style memory commit (optional)
121
+ }
122
+ ```
123
+
124
+ ## Signing Protocol
125
+
126
+ Identity is a keypair. No accounts, no registration.
127
+
128
+ ### Sending a signed packet
129
+
130
+ 1. Build a `Packet` with all fields — leave `sig` and `pk` empty
131
+ 2. Serialize to bytes — this is the **sign payload**
132
+ 3. Sign those bytes with your ed25519 private key
133
+ 4. Set `sig` (64 bytes) and `pk` (32 bytes) on the Packet
134
+ 5. Serialize the full Packet — send over TCP
135
+
136
+ ### Server verification
137
+
138
+ 1. Unmarshal the incoming bytes into a `Packet`
139
+ 2. If `sig` and `pk` are empty — **DROPPED** (logged, no reply)
140
+ 3. Copy all fields except `sig`/`pk` into a new Packet, serialize it
141
+ 4. Verify the signature against those bytes using the sender's `pk`
142
+ 5. If invalid — **DROPPED** (logged, no reply)
143
+ 6. If valid — process the message, send `done` reply
144
+
145
+ ---
146
+
147
+ ## Examples
148
+
149
+ See the [`examples/`](examples/) directory:
150
+
151
+ - **[python_basic.py](examples/python_basic.py)** — Minimal SDK usage
152
+ - **[python_raw.py](examples/python_raw.py)** — Raw TCP + signing without the SDK (educational)
153
+ - **[mcp_tool_definition.py](examples/mcp_tool_definition.py)** — Expose keep as an MCP tool
154
+
155
+ ---
156
+
157
+ ## Use Cases
158
+
159
+ - **Local swarm** — agents on same VM use `localhost:9009` for zero-latency handoff
160
+ - **Relay swarm** — agents publish to public relays — relays enforce fee/ttl/reputation
161
+ - **Memory sharing** — `scar` field carries gitmem-style commits — agents barter knowledge
162
+ - **Anti-spam market** — `fee` field creates micro-economy — pay to get priority
163
+
164
+ ## Design Principles
165
+
166
+ - **Silent rejection** — unsigned senders don't know if the server exists
167
+ - **Identity without accounts** — your keypair is your identity
168
+ - **Full visibility** — dropped packets are logged server-side
169
+ - **Minimal overhead** — protobuf over raw TCP, no HTTP/JSON
170
+ - **Semantic routing** — `dst` is a name, not an address
171
+
172
+ ## Contributing
173
+
174
+ We welcome contributions. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
175
+
176
+ ## License
177
+
178
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,151 @@
1
+ # keep-protocol
2
+
3
+ **Signed protobuf packets over TCP for AI agent-to-agent communication.**
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![Build](https://github.com/CLCrawford-dev/keep-protocol/actions/workflows/ci.yml/badge.svg)](https://github.com/CLCrawford-dev/keep-protocol/actions)
7
+
8
+ > Keep is the quiet pipe agents whisper through.
9
+ > A single TCP connection, a tiny Protobuf envelope, an ed25519 signature —
10
+ > just enough fields to say who's talking, who should listen, what they want,
11
+ > how much they'll pay, and when the message expires.
12
+ > Unsigned packets vanish without a trace. Signed ones get heard.
13
+
14
+ ---
15
+
16
+ ## Install
17
+
18
+ ### Python SDK
19
+
20
+ ```bash
21
+ pip install keep-protocol
22
+ ```
23
+
24
+ ```python
25
+ from keep.client import KeepClient
26
+
27
+ client = KeepClient("localhost", 9009)
28
+ reply = client.send(
29
+ src="bot:my-agent",
30
+ dst="server",
31
+ body="hello from my agent",
32
+ )
33
+ print(reply.body) # "done"
34
+ ```
35
+
36
+ ### Run the Server
37
+
38
+ **Docker (recommended):**
39
+ ```bash
40
+ docker run -d -p 9009:9009 --name keep ghcr.io/clcrawford-dev/keep-server:latest
41
+ ```
42
+
43
+ **From source:**
44
+ ```bash
45
+ git clone https://github.com/CLCrawford-dev/keep-protocol.git
46
+ cd keep-protocol
47
+ go build -o keep .
48
+ ./keep # listens on :9009
49
+ ```
50
+
51
+ ### Verify It Works
52
+
53
+ ```bash
54
+ pip install keep-protocol
55
+ python -c "
56
+ from keep.client import KeepClient
57
+ reply = KeepClient('localhost', 9009).send(body='ping')
58
+ print('OK' if reply.body == 'done' else 'FAIL')
59
+ "
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Why Keep?
65
+
66
+ | Feature | Keep | HTTP/REST | gRPC | NATS |
67
+ |---------|------|-----------|------|------|
68
+ | Latency | Sub-ms (TCP) | 1-10ms | 1-5ms | 1-5ms |
69
+ | Auth | ed25519 built-in | Bring your own | mTLS | Tokens |
70
+ | Schema | 10 fields, done | Unlimited | Unlimited | None |
71
+ | Setup | 1 binary, 0 config | Web server + routes | Codegen + server | Broker cluster |
72
+ | Agent-native | Yes | No | No | Partial |
73
+ | Spam resistance | fee + ttl fields | None | None | None |
74
+
75
+ Keep is not a replacement for gRPC or NATS. It is a protocol for agents that
76
+ need to find each other and exchange signed intent with minimal ceremony.
77
+
78
+ ---
79
+
80
+ ## Packet Schema
81
+
82
+ ```protobuf
83
+ message Packet {
84
+ bytes sig = 1; // ed25519 signature (64 bytes)
85
+ bytes pk = 2; // sender's public key (32 bytes)
86
+ uint32 typ = 3; // 0=ask, 1=offer, 2=heartbeat
87
+ string id = 4; // unique message ID
88
+ string src = 5; // sender: "bot:my-agent" or "human:chris"
89
+ string dst = 6; // destination: "server", "nearest:weather", "swarm:planner"
90
+ string body = 7; // intent or payload
91
+ uint64 fee = 8; // micro-fee in sats (anti-spam)
92
+ uint32 ttl = 9; // time-to-live in seconds
93
+ bytes scar = 10; // gitmem-style memory commit (optional)
94
+ }
95
+ ```
96
+
97
+ ## Signing Protocol
98
+
99
+ Identity is a keypair. No accounts, no registration.
100
+
101
+ ### Sending a signed packet
102
+
103
+ 1. Build a `Packet` with all fields — leave `sig` and `pk` empty
104
+ 2. Serialize to bytes — this is the **sign payload**
105
+ 3. Sign those bytes with your ed25519 private key
106
+ 4. Set `sig` (64 bytes) and `pk` (32 bytes) on the Packet
107
+ 5. Serialize the full Packet — send over TCP
108
+
109
+ ### Server verification
110
+
111
+ 1. Unmarshal the incoming bytes into a `Packet`
112
+ 2. If `sig` and `pk` are empty — **DROPPED** (logged, no reply)
113
+ 3. Copy all fields except `sig`/`pk` into a new Packet, serialize it
114
+ 4. Verify the signature against those bytes using the sender's `pk`
115
+ 5. If invalid — **DROPPED** (logged, no reply)
116
+ 6. If valid — process the message, send `done` reply
117
+
118
+ ---
119
+
120
+ ## Examples
121
+
122
+ See the [`examples/`](examples/) directory:
123
+
124
+ - **[python_basic.py](examples/python_basic.py)** — Minimal SDK usage
125
+ - **[python_raw.py](examples/python_raw.py)** — Raw TCP + signing without the SDK (educational)
126
+ - **[mcp_tool_definition.py](examples/mcp_tool_definition.py)** — Expose keep as an MCP tool
127
+
128
+ ---
129
+
130
+ ## Use Cases
131
+
132
+ - **Local swarm** — agents on same VM use `localhost:9009` for zero-latency handoff
133
+ - **Relay swarm** — agents publish to public relays — relays enforce fee/ttl/reputation
134
+ - **Memory sharing** — `scar` field carries gitmem-style commits — agents barter knowledge
135
+ - **Anti-spam market** — `fee` field creates micro-economy — pay to get priority
136
+
137
+ ## Design Principles
138
+
139
+ - **Silent rejection** — unsigned senders don't know if the server exists
140
+ - **Identity without accounts** — your keypair is your identity
141
+ - **Full visibility** — dropped packets are logged server-side
142
+ - **Minimal overhead** — protobuf over raw TCP, no HTTP/JSON
143
+ - **Semantic routing** — `dst` is a name, not an address
144
+
145
+ ## Contributing
146
+
147
+ We welcome contributions. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
148
+
149
+ ## License
150
+
151
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,6 @@
1
+ """keep-protocol: Signed agent-to-agent communication over TCP."""
2
+
3
+ from keep.client import KeepClient
4
+
5
+ __version__ = "0.1.0"
6
+ __all__ = ["KeepClient"]
@@ -0,0 +1,79 @@
1
+ """Keep protocol client -- sign and send packets over TCP."""
2
+
3
+ import socket
4
+ import uuid
5
+ from typing import Optional
6
+
7
+ from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
8
+
9
+ from keep import keep_pb2
10
+
11
+
12
+ class KeepClient:
13
+ """Client for the keep-protocol server.
14
+
15
+ Generates an ephemeral ed25519 keypair on init (or accepts an existing one).
16
+ Signs every outgoing packet.
17
+ """
18
+
19
+ def __init__(
20
+ self,
21
+ host: str = "localhost",
22
+ port: int = 9009,
23
+ private_key: Optional[Ed25519PrivateKey] = None,
24
+ timeout: float = 10.0,
25
+ ):
26
+ self.host = host
27
+ self.port = port
28
+ self.timeout = timeout
29
+ self._private_key = private_key or Ed25519PrivateKey.generate()
30
+ self._public_key = self._private_key.public_key()
31
+ self._pk_bytes = self._public_key.public_bytes_raw()
32
+
33
+ def send(
34
+ self,
35
+ body: str,
36
+ src: str = "bot:keep-client",
37
+ dst: str = "server",
38
+ typ: int = 0,
39
+ fee: int = 0,
40
+ ttl: int = 60,
41
+ msg_id: Optional[str] = None,
42
+ scar: bytes = b"",
43
+ ) -> keep_pb2.Packet:
44
+ """Sign and send a packet, return the server's reply."""
45
+ msg_id = msg_id or str(uuid.uuid4())
46
+
47
+ # Build unsigned packet
48
+ p = keep_pb2.Packet()
49
+ p.typ = typ
50
+ p.id = msg_id
51
+ p.src = src
52
+ p.dst = dst
53
+ p.body = body
54
+ p.fee = fee
55
+ p.ttl = ttl
56
+ p.scar = scar
57
+
58
+ # Sign
59
+ sign_payload = p.SerializeToString()
60
+ sig_bytes = self._private_key.sign(sign_payload)
61
+
62
+ # Set sig + pk
63
+ p.sig = sig_bytes
64
+ p.pk = self._pk_bytes
65
+ wire_data = p.SerializeToString()
66
+
67
+ # Send over TCP
68
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
69
+ s.settimeout(self.timeout)
70
+ try:
71
+ s.connect((self.host, self.port))
72
+ s.sendall(wire_data)
73
+ reply_data = s.recv(4096)
74
+ finally:
75
+ s.close()
76
+
77
+ resp = keep_pb2.Packet()
78
+ resp.ParseFromString(reply_data)
79
+ return resp
@@ -0,0 +1,26 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: keep.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+
15
+
16
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nkeep.proto\"\x8a\x01\n\x06Packet\x12\x0b\n\x03sig\x18\x01 \x01(\x0c\x12\n\n\x02pk\x18\x02 \x01(\x0c\x12\x0b\n\x03typ\x18\x03 \x01(\r\x12\n\n\x02id\x18\x04 \x01(\t\x12\x0b\n\x03src\x18\x05 \x01(\t\x12\x0b\n\x03\x64st\x18\x06 \x01(\t\x12\x0c\n\x04\x62ody\x18\x07 \x01(\t\x12\x0b\n\x03\x66\x65\x65\x18\x08 \x01(\x04\x12\x0b\n\x03ttl\x18\t \x01(\r\x12\x0c\n\x04scar\x18\n \x01(\x0c\x42\x08Z\x06.;mainb\x06proto3')
17
+
18
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
19
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'keep_pb2', globals())
20
+ if _descriptor._USE_C_DESCRIPTORS == False:
21
+
22
+ DESCRIPTOR._options = None
23
+ DESCRIPTOR._serialized_options = b'Z\006.;main'
24
+ _PACKET._serialized_start=15
25
+ _PACKET._serialized_end=153
26
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: keep-protocol
3
+ Version: 0.1.0
4
+ Summary: Signed protobuf packets over TCP for AI agent-to-agent communication
5
+ Author: Chris Crawford
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/CLCrawford-dev/keep-protocol
8
+ Project-URL: Repository, https://github.com/CLCrawford-dev/keep-protocol
9
+ Project-URL: Issues, https://github.com/CLCrawford-dev/keep-protocol/issues
10
+ Keywords: agent-protocol,ai-agents,protobuf,ed25519,tcp,agent-communication,mcp,multi-agent
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Communications
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: protobuf>=4.25
26
+ Requires-Dist: cryptography>=41.0
27
+
28
+ # keep-protocol
29
+
30
+ **Signed protobuf packets over TCP for AI agent-to-agent communication.**
31
+
32
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
33
+ [![Build](https://github.com/CLCrawford-dev/keep-protocol/actions/workflows/ci.yml/badge.svg)](https://github.com/CLCrawford-dev/keep-protocol/actions)
34
+
35
+ > Keep is the quiet pipe agents whisper through.
36
+ > A single TCP connection, a tiny Protobuf envelope, an ed25519 signature —
37
+ > just enough fields to say who's talking, who should listen, what they want,
38
+ > how much they'll pay, and when the message expires.
39
+ > Unsigned packets vanish without a trace. Signed ones get heard.
40
+
41
+ ---
42
+
43
+ ## Install
44
+
45
+ ### Python SDK
46
+
47
+ ```bash
48
+ pip install keep-protocol
49
+ ```
50
+
51
+ ```python
52
+ from keep.client import KeepClient
53
+
54
+ client = KeepClient("localhost", 9009)
55
+ reply = client.send(
56
+ src="bot:my-agent",
57
+ dst="server",
58
+ body="hello from my agent",
59
+ )
60
+ print(reply.body) # "done"
61
+ ```
62
+
63
+ ### Run the Server
64
+
65
+ **Docker (recommended):**
66
+ ```bash
67
+ docker run -d -p 9009:9009 --name keep ghcr.io/clcrawford-dev/keep-server:latest
68
+ ```
69
+
70
+ **From source:**
71
+ ```bash
72
+ git clone https://github.com/CLCrawford-dev/keep-protocol.git
73
+ cd keep-protocol
74
+ go build -o keep .
75
+ ./keep # listens on :9009
76
+ ```
77
+
78
+ ### Verify It Works
79
+
80
+ ```bash
81
+ pip install keep-protocol
82
+ python -c "
83
+ from keep.client import KeepClient
84
+ reply = KeepClient('localhost', 9009).send(body='ping')
85
+ print('OK' if reply.body == 'done' else 'FAIL')
86
+ "
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Why Keep?
92
+
93
+ | Feature | Keep | HTTP/REST | gRPC | NATS |
94
+ |---------|------|-----------|------|------|
95
+ | Latency | Sub-ms (TCP) | 1-10ms | 1-5ms | 1-5ms |
96
+ | Auth | ed25519 built-in | Bring your own | mTLS | Tokens |
97
+ | Schema | 10 fields, done | Unlimited | Unlimited | None |
98
+ | Setup | 1 binary, 0 config | Web server + routes | Codegen + server | Broker cluster |
99
+ | Agent-native | Yes | No | No | Partial |
100
+ | Spam resistance | fee + ttl fields | None | None | None |
101
+
102
+ Keep is not a replacement for gRPC or NATS. It is a protocol for agents that
103
+ need to find each other and exchange signed intent with minimal ceremony.
104
+
105
+ ---
106
+
107
+ ## Packet Schema
108
+
109
+ ```protobuf
110
+ message Packet {
111
+ bytes sig = 1; // ed25519 signature (64 bytes)
112
+ bytes pk = 2; // sender's public key (32 bytes)
113
+ uint32 typ = 3; // 0=ask, 1=offer, 2=heartbeat
114
+ string id = 4; // unique message ID
115
+ string src = 5; // sender: "bot:my-agent" or "human:chris"
116
+ string dst = 6; // destination: "server", "nearest:weather", "swarm:planner"
117
+ string body = 7; // intent or payload
118
+ uint64 fee = 8; // micro-fee in sats (anti-spam)
119
+ uint32 ttl = 9; // time-to-live in seconds
120
+ bytes scar = 10; // gitmem-style memory commit (optional)
121
+ }
122
+ ```
123
+
124
+ ## Signing Protocol
125
+
126
+ Identity is a keypair. No accounts, no registration.
127
+
128
+ ### Sending a signed packet
129
+
130
+ 1. Build a `Packet` with all fields — leave `sig` and `pk` empty
131
+ 2. Serialize to bytes — this is the **sign payload**
132
+ 3. Sign those bytes with your ed25519 private key
133
+ 4. Set `sig` (64 bytes) and `pk` (32 bytes) on the Packet
134
+ 5. Serialize the full Packet — send over TCP
135
+
136
+ ### Server verification
137
+
138
+ 1. Unmarshal the incoming bytes into a `Packet`
139
+ 2. If `sig` and `pk` are empty — **DROPPED** (logged, no reply)
140
+ 3. Copy all fields except `sig`/`pk` into a new Packet, serialize it
141
+ 4. Verify the signature against those bytes using the sender's `pk`
142
+ 5. If invalid — **DROPPED** (logged, no reply)
143
+ 6. If valid — process the message, send `done` reply
144
+
145
+ ---
146
+
147
+ ## Examples
148
+
149
+ See the [`examples/`](examples/) directory:
150
+
151
+ - **[python_basic.py](examples/python_basic.py)** — Minimal SDK usage
152
+ - **[python_raw.py](examples/python_raw.py)** — Raw TCP + signing without the SDK (educational)
153
+ - **[mcp_tool_definition.py](examples/mcp_tool_definition.py)** — Expose keep as an MCP tool
154
+
155
+ ---
156
+
157
+ ## Use Cases
158
+
159
+ - **Local swarm** — agents on same VM use `localhost:9009` for zero-latency handoff
160
+ - **Relay swarm** — agents publish to public relays — relays enforce fee/ttl/reputation
161
+ - **Memory sharing** — `scar` field carries gitmem-style commits — agents barter knowledge
162
+ - **Anti-spam market** — `fee` field creates micro-economy — pay to get priority
163
+
164
+ ## Design Principles
165
+
166
+ - **Silent rejection** — unsigned senders don't know if the server exists
167
+ - **Identity without accounts** — your keypair is your identity
168
+ - **Full visibility** — dropped packets are logged server-side
169
+ - **Minimal overhead** — protobuf over raw TCP, no HTTP/JSON
170
+ - **Semantic routing** — `dst` is a name, not an address
171
+
172
+ ## Contributing
173
+
174
+ We welcome contributions. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
175
+
176
+ ## License
177
+
178
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ keep/__init__.py
4
+ keep/client.py
5
+ keep/keep_pb2.py
6
+ keep_protocol.egg-info/PKG-INFO
7
+ keep_protocol.egg-info/SOURCES.txt
8
+ keep_protocol.egg-info/dependency_links.txt
9
+ keep_protocol.egg-info/requires.txt
10
+ keep_protocol.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ protobuf>=4.25
2
+ cryptography>=41.0
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools >= 61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "keep-protocol"
7
+ version = "0.1.0"
8
+ description = "Signed protobuf packets over TCP for AI agent-to-agent communication"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [{name = "Chris Crawford"}]
12
+ requires-python = ">= 3.9"
13
+ keywords = [
14
+ "agent-protocol",
15
+ "ai-agents",
16
+ "protobuf",
17
+ "ed25519",
18
+ "tcp",
19
+ "agent-communication",
20
+ "mcp",
21
+ "multi-agent",
22
+ ]
23
+ classifiers = [
24
+ "Development Status :: 3 - Alpha",
25
+ "Intended Audience :: Developers",
26
+ "License :: OSI Approved :: MIT License",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.9",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Programming Language :: Python :: 3.13",
33
+ "Topic :: Communications",
34
+ "Topic :: Security :: Cryptography",
35
+ "Topic :: Software Development :: Libraries :: Python Modules",
36
+ ]
37
+ dependencies = [
38
+ "protobuf >= 4.25",
39
+ "cryptography >= 41.0",
40
+ ]
41
+
42
+ [project.urls]
43
+ Homepage = "https://github.com/CLCrawford-dev/keep-protocol"
44
+ Repository = "https://github.com/CLCrawford-dev/keep-protocol"
45
+ Issues = "https://github.com/CLCrawford-dev/keep-protocol/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+