ctxprotocol 0.5.5__tar.gz → 0.5.7__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.
- ctxprotocol-0.5.7/.gitignore +51 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/PKG-INFO +46 -7
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/README.md +45 -6
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/__init__.py +45 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/auth/__init__.py +34 -7
- ctxprotocol-0.5.7/ctxprotocol/handshake/__init__.py +418 -0
- ctxprotocol-0.5.7/examples/server/hummingbot-contributor/README.md +249 -0
- ctxprotocol-0.5.7/examples/server/hummingbot-contributor/env.example +16 -0
- ctxprotocol-0.5.7/examples/server/hummingbot-contributor/requirements.txt +23 -0
- ctxprotocol-0.5.7/examples/server/hummingbot-contributor/server.py +769 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/pyproject.toml +1 -1
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/client/__init__.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/client/client.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/client/resources/__init__.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/client/resources/discovery.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/client/resources/tools.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/client/types.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/context/__init__.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/context/hyperliquid.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/context/polymarket.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/context/wallet.py +0 -0
- {ctxprotocol-0.5.5 → ctxprotocol-0.5.7}/ctxprotocol/py.typed +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.env
|
|
25
|
+
.venv
|
|
26
|
+
env/
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
|
|
30
|
+
# IDE
|
|
31
|
+
.idea/
|
|
32
|
+
.vscode/
|
|
33
|
+
*.swp
|
|
34
|
+
*.swo
|
|
35
|
+
|
|
36
|
+
# Testing
|
|
37
|
+
.tox/
|
|
38
|
+
.coverage
|
|
39
|
+
.coverage.*
|
|
40
|
+
htmlcov/
|
|
41
|
+
.pytest_cache/
|
|
42
|
+
|
|
43
|
+
# md files
|
|
44
|
+
*.md
|
|
45
|
+
!README.md
|
|
46
|
+
!docs/mcp-builder-template.md
|
|
47
|
+
|
|
48
|
+
# Shell scripts (deployment)
|
|
49
|
+
*.sh
|
|
50
|
+
|
|
51
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ctxprotocol
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.7
|
|
4
4
|
Summary: Official Python SDK for the Context Protocol - Discover and execute AI tools programmatically
|
|
5
5
|
Project-URL: Homepage, https://ctxprotocol.com
|
|
6
6
|
Project-URL: Documentation, https://docs.ctxprotocol.com
|
|
@@ -48,12 +48,26 @@ Context Protocol is **pip for AI capabilities**. Just as you install packages to
|
|
|
48
48
|
[](https://pypi.org/project/ctxprotocol/)
|
|
49
49
|
[](https://opensource.org/licenses/MIT)
|
|
50
50
|
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### 💰 $10,000 Developer Grant Program
|
|
54
|
+
|
|
55
|
+
We're funding the initial supply of MCP Tools for the Context Marketplace. **Become a Data Broker.**
|
|
56
|
+
|
|
57
|
+
- **🛠️ Build:** Create an MCP Server using this SDK (Solana data, Trading tools, Scrapers, etc.)
|
|
58
|
+
- **📦 List:** Publish it to the Context Registry
|
|
59
|
+
- **💵 Earn:** Get a **$250–$1,000 Grant** + earn USDC every time an agent queries your tool
|
|
60
|
+
|
|
61
|
+
👉 [**View Open Bounties & Apply Here**](https://docs.ctxprotocol.com/grants)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
51
65
|
## Why use Context?
|
|
52
66
|
|
|
53
67
|
- **🔌 One Interface, Everything:** Stop integrating APIs one by one. Use a single SDK to access any tool in the marketplace.
|
|
54
68
|
- **🧠 Zero-Ops:** We're a gateway to the best MCP tools. Just send the JSON and get the result.
|
|
55
69
|
- **⚡️ Agentic Discovery:** Your Agent can search the marketplace at runtime to find tools it didn't know it needed.
|
|
56
|
-
- **💸
|
|
70
|
+
- **💸 Pay-Per-Response:** The $500/year subscription? Now $0.01/response. No monthly fees, just results.
|
|
57
71
|
|
|
58
72
|
## Who Is This SDK For?
|
|
59
73
|
|
|
@@ -263,15 +277,40 @@ if is_protected_mcp_method(body["method"]):
|
|
|
263
277
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
264
278
|
```
|
|
265
279
|
|
|
266
|
-
### Security Model
|
|
280
|
+
### MCP Security Model
|
|
281
|
+
|
|
282
|
+
The SDK implements a **selective authentication** model — discovery is open, execution is protected:
|
|
267
283
|
|
|
268
|
-
| MCP Method | Auth Required |
|
|
269
|
-
|
|
270
|
-
| `tools/list` | ❌ No | Discovery - just returns tool schemas |
|
|
271
|
-
| `tools/call` | ✅ Yes | Execution - runs code, may cost money |
|
|
284
|
+
| MCP Method | Auth Required | Why |
|
|
285
|
+
|------------|---------------|-----|
|
|
272
286
|
| `initialize` | ❌ No | Session setup |
|
|
287
|
+
| `tools/list` | ❌ No | Discovery - agents need to see your schemas |
|
|
273
288
|
| `resources/list` | ❌ No | Discovery |
|
|
274
289
|
| `prompts/list` | ❌ No | Discovery |
|
|
290
|
+
| `tools/call` | ✅ **Yes** | **Execution - costs money, runs your code** |
|
|
291
|
+
|
|
292
|
+
**What this means in practice:**
|
|
293
|
+
- ✅ `https://your-mcp.com/mcp` + `initialize` → Works without auth
|
|
294
|
+
- ✅ `https://your-mcp.com/mcp` + `tools/list` → Works without auth
|
|
295
|
+
- ❌ `https://your-mcp.com/mcp` + `tools/call` → **Requires Context Protocol JWT**
|
|
296
|
+
|
|
297
|
+
This matches standard API patterns (OpenAPI schemas are public, GraphQL introspection is open).
|
|
298
|
+
|
|
299
|
+
## Execution Timeout & Product Design
|
|
300
|
+
|
|
301
|
+
⚠️ **Important**: MCP tool execution has a **~60 second timeout** (enforced at the platform/client level, not by MCP itself). This is intentional—it encourages building pre-computed insight products rather than raw data access.
|
|
302
|
+
|
|
303
|
+
**Best practice**: Run heavy queries offline (via cron jobs), store results in your database, and serve instant results via MCP. This is how Bloomberg, Nansen, and Arkham work.
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
# ❌ BAD: Raw access (timeout-prone, no moat)
|
|
307
|
+
{"name": "run_sql", "description": "Run any SQL against blockchain data"}
|
|
308
|
+
|
|
309
|
+
# ✅ GOOD: Pre-computed product (instant, defensible)
|
|
310
|
+
{"name": "get_smart_money_wallets", "description": "Top 100 wallets that timed market tops"}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
See the [full documentation](https://docs.ctxprotocol.com/guides/build-tools#execution-limits--product-design) for detailed guidance.
|
|
275
314
|
|
|
276
315
|
## Context Injection (Personalized Tools)
|
|
277
316
|
|
|
@@ -10,12 +10,26 @@ Context Protocol is **pip for AI capabilities**. Just as you install packages to
|
|
|
10
10
|
[](https://pypi.org/project/ctxprotocol/)
|
|
11
11
|
[](https://opensource.org/licenses/MIT)
|
|
12
12
|
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
### 💰 $10,000 Developer Grant Program
|
|
16
|
+
|
|
17
|
+
We're funding the initial supply of MCP Tools for the Context Marketplace. **Become a Data Broker.**
|
|
18
|
+
|
|
19
|
+
- **🛠️ Build:** Create an MCP Server using this SDK (Solana data, Trading tools, Scrapers, etc.)
|
|
20
|
+
- **📦 List:** Publish it to the Context Registry
|
|
21
|
+
- **💵 Earn:** Get a **$250–$1,000 Grant** + earn USDC every time an agent queries your tool
|
|
22
|
+
|
|
23
|
+
👉 [**View Open Bounties & Apply Here**](https://docs.ctxprotocol.com/grants)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
13
27
|
## Why use Context?
|
|
14
28
|
|
|
15
29
|
- **🔌 One Interface, Everything:** Stop integrating APIs one by one. Use a single SDK to access any tool in the marketplace.
|
|
16
30
|
- **🧠 Zero-Ops:** We're a gateway to the best MCP tools. Just send the JSON and get the result.
|
|
17
31
|
- **⚡️ Agentic Discovery:** Your Agent can search the marketplace at runtime to find tools it didn't know it needed.
|
|
18
|
-
- **💸
|
|
32
|
+
- **💸 Pay-Per-Response:** The $500/year subscription? Now $0.01/response. No monthly fees, just results.
|
|
19
33
|
|
|
20
34
|
## Who Is This SDK For?
|
|
21
35
|
|
|
@@ -225,15 +239,40 @@ if is_protected_mcp_method(body["method"]):
|
|
|
225
239
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
226
240
|
```
|
|
227
241
|
|
|
228
|
-
### Security Model
|
|
242
|
+
### MCP Security Model
|
|
243
|
+
|
|
244
|
+
The SDK implements a **selective authentication** model — discovery is open, execution is protected:
|
|
229
245
|
|
|
230
|
-
| MCP Method | Auth Required |
|
|
231
|
-
|
|
232
|
-
| `tools/list` | ❌ No | Discovery - just returns tool schemas |
|
|
233
|
-
| `tools/call` | ✅ Yes | Execution - runs code, may cost money |
|
|
246
|
+
| MCP Method | Auth Required | Why |
|
|
247
|
+
|------------|---------------|-----|
|
|
234
248
|
| `initialize` | ❌ No | Session setup |
|
|
249
|
+
| `tools/list` | ❌ No | Discovery - agents need to see your schemas |
|
|
235
250
|
| `resources/list` | ❌ No | Discovery |
|
|
236
251
|
| `prompts/list` | ❌ No | Discovery |
|
|
252
|
+
| `tools/call` | ✅ **Yes** | **Execution - costs money, runs your code** |
|
|
253
|
+
|
|
254
|
+
**What this means in practice:**
|
|
255
|
+
- ✅ `https://your-mcp.com/mcp` + `initialize` → Works without auth
|
|
256
|
+
- ✅ `https://your-mcp.com/mcp` + `tools/list` → Works without auth
|
|
257
|
+
- ❌ `https://your-mcp.com/mcp` + `tools/call` → **Requires Context Protocol JWT**
|
|
258
|
+
|
|
259
|
+
This matches standard API patterns (OpenAPI schemas are public, GraphQL introspection is open).
|
|
260
|
+
|
|
261
|
+
## Execution Timeout & Product Design
|
|
262
|
+
|
|
263
|
+
⚠️ **Important**: MCP tool execution has a **~60 second timeout** (enforced at the platform/client level, not by MCP itself). This is intentional—it encourages building pre-computed insight products rather than raw data access.
|
|
264
|
+
|
|
265
|
+
**Best practice**: Run heavy queries offline (via cron jobs), store results in your database, and serve instant results via MCP. This is how Bloomberg, Nansen, and Arkham work.
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
# ❌ BAD: Raw access (timeout-prone, no moat)
|
|
269
|
+
{"name": "run_sql", "description": "Run any SQL against blockchain data"}
|
|
270
|
+
|
|
271
|
+
# ✅ GOOD: Pre-computed product (instant, defensible)
|
|
272
|
+
{"name": "get_smart_money_wallets", "description": "Top 100 wallets that timed market tops"}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
See the [full documentation](https://docs.ctxprotocol.com/guides/build-tools#execution-limits--product-design) for detailed guidance.
|
|
237
276
|
|
|
238
277
|
## Context Injection (Personalized Tools)
|
|
239
278
|
|
|
@@ -91,6 +91,31 @@ from ctxprotocol.auth import (
|
|
|
91
91
|
CreateContextMiddlewareOptions,
|
|
92
92
|
)
|
|
93
93
|
|
|
94
|
+
# Handshake types and helpers for tools that need user interaction
|
|
95
|
+
# (signatures, transactions, OAuth)
|
|
96
|
+
from ctxprotocol.handshake import (
|
|
97
|
+
# Types
|
|
98
|
+
HandshakeMeta,
|
|
99
|
+
EIP712Domain,
|
|
100
|
+
EIP712TypeField,
|
|
101
|
+
SignatureRequest,
|
|
102
|
+
TransactionProposalMeta,
|
|
103
|
+
TransactionProposal,
|
|
104
|
+
AuthRequiredMeta,
|
|
105
|
+
AuthRequired,
|
|
106
|
+
HandshakeAction,
|
|
107
|
+
# Type guards
|
|
108
|
+
is_handshake_action,
|
|
109
|
+
is_signature_request,
|
|
110
|
+
is_transaction_proposal,
|
|
111
|
+
is_auth_required,
|
|
112
|
+
# Helper functions
|
|
113
|
+
create_signature_request,
|
|
114
|
+
create_transaction_proposal,
|
|
115
|
+
create_auth_required,
|
|
116
|
+
wrap_handshake_response,
|
|
117
|
+
)
|
|
118
|
+
|
|
94
119
|
__all__ = [
|
|
95
120
|
# Version
|
|
96
121
|
"__version__",
|
|
@@ -144,5 +169,25 @@ __all__ = [
|
|
|
144
169
|
"ContextMiddleware",
|
|
145
170
|
"VerifyRequestOptions",
|
|
146
171
|
"CreateContextMiddlewareOptions",
|
|
172
|
+
# Handshake types
|
|
173
|
+
"HandshakeMeta",
|
|
174
|
+
"EIP712Domain",
|
|
175
|
+
"EIP712TypeField",
|
|
176
|
+
"SignatureRequest",
|
|
177
|
+
"TransactionProposalMeta",
|
|
178
|
+
"TransactionProposal",
|
|
179
|
+
"AuthRequiredMeta",
|
|
180
|
+
"AuthRequired",
|
|
181
|
+
"HandshakeAction",
|
|
182
|
+
# Handshake type guards
|
|
183
|
+
"is_handshake_action",
|
|
184
|
+
"is_signature_request",
|
|
185
|
+
"is_transaction_proposal",
|
|
186
|
+
"is_auth_required",
|
|
187
|
+
# Handshake helper functions
|
|
188
|
+
"create_signature_request",
|
|
189
|
+
"create_transaction_proposal",
|
|
190
|
+
"create_auth_required",
|
|
191
|
+
"wrap_handshake_response",
|
|
147
192
|
]
|
|
148
193
|
|
|
@@ -160,17 +160,32 @@ async def verify_context_request(
|
|
|
160
160
|
CONTEXT_PLATFORM_PUBLIC_KEY_PEM.encode()
|
|
161
161
|
)
|
|
162
162
|
|
|
163
|
+
# Build decode options - match TypeScript SDK behavior
|
|
164
|
+
decode_options: dict[str, Any] = {
|
|
165
|
+
"verify_signature": True,
|
|
166
|
+
"verify_exp": True,
|
|
167
|
+
"verify_iat": True,
|
|
168
|
+
"require": ["exp", "iat"],
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# Only verify issuer if we expect it (TypeScript SDK does this)
|
|
172
|
+
# But don't require it in case the platform doesn't always include it
|
|
173
|
+
decode_options["verify_iss"] = True
|
|
174
|
+
|
|
175
|
+
# Only verify audience if explicitly provided
|
|
176
|
+
if audience:
|
|
177
|
+
decode_options["verify_aud"] = True
|
|
178
|
+
else:
|
|
179
|
+
decode_options["verify_aud"] = False
|
|
180
|
+
|
|
163
181
|
# Verify the JWT
|
|
164
182
|
payload = jwt.decode(
|
|
165
183
|
token,
|
|
166
184
|
public_key,
|
|
167
185
|
algorithms=["RS256"],
|
|
168
186
|
issuer="https://ctxprotocol.com",
|
|
169
|
-
audience=audience,
|
|
170
|
-
options=
|
|
171
|
-
"require": ["iss", "sub", "exp", "iat"],
|
|
172
|
-
"verify_aud": audience is not None,
|
|
173
|
-
},
|
|
187
|
+
audience=audience if audience else None,
|
|
188
|
+
options=decode_options,
|
|
174
189
|
)
|
|
175
190
|
|
|
176
191
|
return payload
|
|
@@ -193,9 +208,21 @@ async def verify_context_request(
|
|
|
193
208
|
code="unauthorized",
|
|
194
209
|
status_code=401,
|
|
195
210
|
)
|
|
196
|
-
except jwt.
|
|
211
|
+
except jwt.DecodeError as e:
|
|
212
|
+
raise ContextError(
|
|
213
|
+
message=f"JWT decode error: {e}",
|
|
214
|
+
code="unauthorized",
|
|
215
|
+
status_code=401,
|
|
216
|
+
)
|
|
217
|
+
except jwt.InvalidSignatureError:
|
|
218
|
+
raise ContextError(
|
|
219
|
+
message="Invalid JWT signature",
|
|
220
|
+
code="unauthorized",
|
|
221
|
+
status_code=401,
|
|
222
|
+
)
|
|
223
|
+
except jwt.PyJWTError as e:
|
|
197
224
|
raise ContextError(
|
|
198
|
-
message="
|
|
225
|
+
message=f"JWT verification failed: {e}",
|
|
199
226
|
code="unauthorized",
|
|
200
227
|
status_code=401,
|
|
201
228
|
)
|