ctxprotocol 0.5.5__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,326 @@
1
+ Metadata-Version: 2.4
2
+ Name: ctxprotocol
3
+ Version: 0.5.5
4
+ Summary: Official Python SDK for the Context Protocol - Discover and execute AI tools programmatically
5
+ Project-URL: Homepage, https://ctxprotocol.com
6
+ Project-URL: Documentation, https://docs.ctxprotocol.com
7
+ Project-URL: Repository, https://github.com/ctxprotocol/sdk-python
8
+ Project-URL: Issues, https://github.com/ctxprotocol/sdk-python/issues
9
+ Author-email: Context Protocol <team@ctxprotocol.com>
10
+ License-Expression: MIT
11
+ Keywords: ai,api-client,context-protocol,ctxprotocol,mcp,sdk,tools
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: cryptography>=42.0.0
26
+ Requires-Dist: httpx>=0.27.0
27
+ Requires-Dist: pydantic>=2.0.0
28
+ Requires-Dist: pyjwt[crypto]>=2.8.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
34
+ Provides-Extra: fastapi
35
+ Requires-Dist: fastapi>=0.111.0; extra == 'fastapi'
36
+ Requires-Dist: starlette>=0.37.0; extra == 'fastapi'
37
+ Description-Content-Type: text/markdown
38
+
39
+ # ctxprotocol
40
+
41
+ **The Universal Adapter for AI Agents.**
42
+
43
+ Connect your AI to the real world without managing API keys, hosting servers, or reading documentation.
44
+
45
+ Context Protocol is **pip for AI capabilities**. Just as you install packages to add functionality to your code, use the Context SDK to give your Agent instant access to thousands of live data sources and actionsβ€”from DeFi and Gas Oracles to Weather and Search.
46
+
47
+ [![PyPI version](https://img.shields.io/pypi/v/ctxprotocol.svg)](https://pypi.org/project/ctxprotocol/)
48
+ [![Python versions](https://img.shields.io/pypi/pyversions/ctxprotocol.svg)](https://pypi.org/project/ctxprotocol/)
49
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
50
+
51
+ ## Why use Context?
52
+
53
+ - **πŸ”Œ One Interface, Everything:** Stop integrating APIs one by one. Use a single SDK to access any tool in the marketplace.
54
+ - **🧠 Zero-Ops:** We're a gateway to the best MCP tools. Just send the JSON and get the result.
55
+ - **⚑️ Agentic Discovery:** Your Agent can search the marketplace at runtime to find tools it didn't know it needed.
56
+ - **πŸ’Έ Micro-Billing:** Pay only for what you use (e.g., $0.001/query). No monthly subscriptions for tools you rarely use.
57
+
58
+ ## Who Is This SDK For?
59
+
60
+ | Role | What You Use |
61
+ |------|--------------|
62
+ | **AI Agent Developer** | `ctxprotocol` β€” Query marketplace, execute tools, handle payments |
63
+ | **Tool Contributor (Data Broker)** | `mcp` + `ctxprotocol` β€” Standard MCP server + security middleware |
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install ctxprotocol
69
+ ```
70
+
71
+ Or with optional FastAPI support:
72
+
73
+ ```bash
74
+ pip install ctxprotocol[fastapi]
75
+ ```
76
+
77
+ ## Prerequisites
78
+
79
+ Before using the API, complete setup at [ctxprotocol.com](https://ctxprotocol.com):
80
+
81
+ 1. **Sign in** β€” Creates your embedded wallet
82
+ 2. **Enable Auto Pay** β€” Approve USDC spending for tool payments
83
+ 3. **Fund wallet** β€” Add USDC for tool execution fees
84
+ 4. **Generate API key** β€” In Settings page
85
+
86
+ ## Quick Start
87
+
88
+ ```python
89
+ import asyncio
90
+ from ctxprotocol import ContextClient
91
+
92
+ async def main():
93
+ async with ContextClient(api_key="sk_live_...") as client:
94
+ # Discover tools
95
+ tools = await client.discovery.search("gas prices")
96
+
97
+ # Execute a tool
98
+ result = await client.tools.execute(
99
+ tool_id=tools[0].id,
100
+ tool_name=tools[0].mcp_tools[0].name,
101
+ args={"chainId": 1},
102
+ )
103
+
104
+ print(result.result)
105
+
106
+ asyncio.run(main())
107
+ ```
108
+
109
+ ## Configuration
110
+
111
+ ### Client Options
112
+
113
+ | Option | Type | Required | Default | Description |
114
+ |--------|------|----------|---------|-------------|
115
+ | `api_key` | `str` | Yes | β€” | Your Context Protocol API key |
116
+ | `base_url` | `str` | No | `https://ctxprotocol.com` | API base URL (for development) |
117
+
118
+ ```python
119
+ # Production
120
+ client = ContextClient(api_key=os.environ["CONTEXT_API_KEY"])
121
+
122
+ # Local development
123
+ client = ContextClient(
124
+ api_key="sk_test_...",
125
+ base_url="http://localhost:3000",
126
+ )
127
+ ```
128
+
129
+ ## API Reference
130
+
131
+ ### Discovery
132
+
133
+ #### `client.discovery.search(query, limit?)`
134
+
135
+ Search for tools matching a query string.
136
+
137
+ ```python
138
+ tools = await client.discovery.search("ethereum gas", limit=10)
139
+ ```
140
+
141
+ #### `client.discovery.get_featured(limit?)`
142
+
143
+ Get featured/popular tools.
144
+
145
+ ```python
146
+ featured = await client.discovery.get_featured(limit=5)
147
+ ```
148
+
149
+ ### Tools
150
+
151
+ #### `client.tools.execute(tool_id, tool_name, args?)`
152
+
153
+ Execute a tool method.
154
+
155
+ ```python
156
+ result = await client.tools.execute(
157
+ tool_id="uuid-of-tool",
158
+ tool_name="get_gas_prices",
159
+ args={"chainId": 1},
160
+ )
161
+ ```
162
+
163
+ ## Types
164
+
165
+ ```python
166
+ from ctxprotocol import (
167
+ # Auth utilities for tool contributors
168
+ verify_context_request,
169
+ is_protected_mcp_method,
170
+ is_open_mcp_method,
171
+
172
+ # Client types
173
+ ContextClientOptions,
174
+ Tool,
175
+ McpTool,
176
+ ExecuteOptions,
177
+ ExecutionResult,
178
+ ContextErrorCode,
179
+
180
+ # Auth types (for MCP server contributors)
181
+ VerifyRequestOptions,
182
+
183
+ # Context types (for MCP server contributors receiving injected data)
184
+ ContextRequirementType,
185
+ HyperliquidContext,
186
+ PolymarketContext,
187
+ WalletContext,
188
+ UserContext,
189
+ )
190
+ ```
191
+
192
+ ## Error Handling
193
+
194
+ The SDK raises `ContextError` with specific error codes:
195
+
196
+ ```python
197
+ from ctxprotocol import ContextClient, ContextError
198
+
199
+ try:
200
+ result = await client.tools.execute(...)
201
+ except ContextError as e:
202
+ match e.code:
203
+ case "no_wallet":
204
+ # User needs to set up wallet
205
+ print(f"Setup required: {e.help_url}")
206
+ case "insufficient_allowance":
207
+ # User needs to enable Auto Pay
208
+ print(f"Enable Auto Pay: {e.help_url}")
209
+ case "payment_failed":
210
+ # Insufficient USDC balance
211
+ pass
212
+ case "execution_failed":
213
+ # Tool execution error
214
+ pass
215
+ ```
216
+
217
+ ### Error Codes
218
+
219
+ | Code | Description | Handling |
220
+ |------|-------------|----------|
221
+ | `unauthorized` | Invalid API key | Check configuration |
222
+ | `no_wallet` | Wallet not set up | Direct user to `help_url` |
223
+ | `insufficient_allowance` | Auto Pay not enabled | Direct user to `help_url` |
224
+ | `payment_failed` | USDC payment failed | Check balance |
225
+ | `execution_failed` | Tool error | Retry with different args |
226
+
227
+ ## πŸ”’ Securing Your Tool (MCP Contributors)
228
+
229
+ If you're building an MCP server (tool contributor), verify incoming requests:
230
+
231
+ ### Quick Implementation with FastAPI
232
+
233
+ ```python
234
+ from fastapi import FastAPI, Request, Depends, HTTPException
235
+ from ctxprotocol import create_context_middleware, ContextError
236
+
237
+ app = FastAPI()
238
+ verify_context = create_context_middleware(audience="https://your-tool.com/mcp")
239
+
240
+ @app.post("/mcp")
241
+ async def handle_mcp(request: Request, context: dict = Depends(verify_context)):
242
+ # context contains verified JWT payload (on protected methods)
243
+ # None for open methods like tools/list
244
+ body = await request.json()
245
+ # Handle MCP request...
246
+ ```
247
+
248
+ ### Manual Verification
249
+
250
+ ```python
251
+ from ctxprotocol import verify_context_request, is_protected_mcp_method, ContextError
252
+
253
+ # Check if a method requires auth
254
+ if is_protected_mcp_method(body["method"]):
255
+ try:
256
+ payload = await verify_context_request(
257
+ authorization_header=request.headers.get("authorization"),
258
+ audience="https://your-tool.com/mcp", # optional
259
+ )
260
+ # payload contains verified JWT claims
261
+ except ContextError as e:
262
+ # Handle authentication error
263
+ raise HTTPException(status_code=401, detail="Unauthorized")
264
+ ```
265
+
266
+ ### Security Model
267
+
268
+ | MCP Method | Auth Required | Reason |
269
+ |------------|---------------|--------|
270
+ | `tools/list` | ❌ No | Discovery - just returns tool schemas |
271
+ | `tools/call` | βœ… Yes | Execution - runs code, may cost money |
272
+ | `initialize` | ❌ No | Session setup |
273
+ | `resources/list` | ❌ No | Discovery |
274
+ | `prompts/list` | ❌ No | Discovery |
275
+
276
+ ## Context Injection (Personalized Tools)
277
+
278
+ For tools that analyze user data, Context automatically injects user context:
279
+
280
+ ```python
281
+ from ctxprotocol import CONTEXT_REQUIREMENTS_KEY, HyperliquidContext
282
+
283
+ # Define tool with context requirements
284
+ TOOLS = [{
285
+ "name": "analyze_my_positions",
286
+ "description": "Analyze your positions with personalized insights",
287
+ "_meta": {
288
+ "contextRequirements": ["hyperliquid"],
289
+ },
290
+ "inputSchema": {
291
+ "type": "object",
292
+ "properties": {
293
+ "portfolio": {
294
+ "type": "object",
295
+ "description": "Portfolio context (injected by platform)",
296
+ },
297
+ },
298
+ "required": ["portfolio"],
299
+ },
300
+ }]
301
+
302
+ # Your handler receives typed context
303
+ async def handle_analyze_positions(portfolio: HyperliquidContext):
304
+ positions = portfolio.perp_positions
305
+ account = portfolio.account_summary
306
+ # ... analyze and return insights
307
+ ```
308
+
309
+ ## Links
310
+
311
+ - [Context Protocol](https://ctxprotocol.com) β€” Main website
312
+ - [Documentation](https://docs.ctxprotocol.com)
313
+ - [GitHub](https://github.com/ctxprotocol/sdk-python) β€” This SDK
314
+ - [TypeScript SDK](https://github.com/ctxprotocol/sdk) β€” For Node.js
315
+ - [PyPI Package](https://pypi.org/project/ctxprotocol/)
316
+
317
+ ## Requirements
318
+
319
+ - Python 3.10+
320
+ - httpx
321
+ - pydantic
322
+ - pyjwt[crypto]
323
+
324
+ ## License
325
+
326
+ MIT
@@ -0,0 +1,288 @@
1
+ # ctxprotocol
2
+
3
+ **The Universal Adapter for AI Agents.**
4
+
5
+ Connect your AI to the real world without managing API keys, hosting servers, or reading documentation.
6
+
7
+ Context Protocol is **pip for AI capabilities**. Just as you install packages to add functionality to your code, use the Context SDK to give your Agent instant access to thousands of live data sources and actionsβ€”from DeFi and Gas Oracles to Weather and Search.
8
+
9
+ [![PyPI version](https://img.shields.io/pypi/v/ctxprotocol.svg)](https://pypi.org/project/ctxprotocol/)
10
+ [![Python versions](https://img.shields.io/pypi/pyversions/ctxprotocol.svg)](https://pypi.org/project/ctxprotocol/)
11
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
12
+
13
+ ## Why use Context?
14
+
15
+ - **πŸ”Œ One Interface, Everything:** Stop integrating APIs one by one. Use a single SDK to access any tool in the marketplace.
16
+ - **🧠 Zero-Ops:** We're a gateway to the best MCP tools. Just send the JSON and get the result.
17
+ - **⚑️ Agentic Discovery:** Your Agent can search the marketplace at runtime to find tools it didn't know it needed.
18
+ - **πŸ’Έ Micro-Billing:** Pay only for what you use (e.g., $0.001/query). No monthly subscriptions for tools you rarely use.
19
+
20
+ ## Who Is This SDK For?
21
+
22
+ | Role | What You Use |
23
+ |------|--------------|
24
+ | **AI Agent Developer** | `ctxprotocol` β€” Query marketplace, execute tools, handle payments |
25
+ | **Tool Contributor (Data Broker)** | `mcp` + `ctxprotocol` β€” Standard MCP server + security middleware |
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install ctxprotocol
31
+ ```
32
+
33
+ Or with optional FastAPI support:
34
+
35
+ ```bash
36
+ pip install ctxprotocol[fastapi]
37
+ ```
38
+
39
+ ## Prerequisites
40
+
41
+ Before using the API, complete setup at [ctxprotocol.com](https://ctxprotocol.com):
42
+
43
+ 1. **Sign in** β€” Creates your embedded wallet
44
+ 2. **Enable Auto Pay** β€” Approve USDC spending for tool payments
45
+ 3. **Fund wallet** β€” Add USDC for tool execution fees
46
+ 4. **Generate API key** β€” In Settings page
47
+
48
+ ## Quick Start
49
+
50
+ ```python
51
+ import asyncio
52
+ from ctxprotocol import ContextClient
53
+
54
+ async def main():
55
+ async with ContextClient(api_key="sk_live_...") as client:
56
+ # Discover tools
57
+ tools = await client.discovery.search("gas prices")
58
+
59
+ # Execute a tool
60
+ result = await client.tools.execute(
61
+ tool_id=tools[0].id,
62
+ tool_name=tools[0].mcp_tools[0].name,
63
+ args={"chainId": 1},
64
+ )
65
+
66
+ print(result.result)
67
+
68
+ asyncio.run(main())
69
+ ```
70
+
71
+ ## Configuration
72
+
73
+ ### Client Options
74
+
75
+ | Option | Type | Required | Default | Description |
76
+ |--------|------|----------|---------|-------------|
77
+ | `api_key` | `str` | Yes | β€” | Your Context Protocol API key |
78
+ | `base_url` | `str` | No | `https://ctxprotocol.com` | API base URL (for development) |
79
+
80
+ ```python
81
+ # Production
82
+ client = ContextClient(api_key=os.environ["CONTEXT_API_KEY"])
83
+
84
+ # Local development
85
+ client = ContextClient(
86
+ api_key="sk_test_...",
87
+ base_url="http://localhost:3000",
88
+ )
89
+ ```
90
+
91
+ ## API Reference
92
+
93
+ ### Discovery
94
+
95
+ #### `client.discovery.search(query, limit?)`
96
+
97
+ Search for tools matching a query string.
98
+
99
+ ```python
100
+ tools = await client.discovery.search("ethereum gas", limit=10)
101
+ ```
102
+
103
+ #### `client.discovery.get_featured(limit?)`
104
+
105
+ Get featured/popular tools.
106
+
107
+ ```python
108
+ featured = await client.discovery.get_featured(limit=5)
109
+ ```
110
+
111
+ ### Tools
112
+
113
+ #### `client.tools.execute(tool_id, tool_name, args?)`
114
+
115
+ Execute a tool method.
116
+
117
+ ```python
118
+ result = await client.tools.execute(
119
+ tool_id="uuid-of-tool",
120
+ tool_name="get_gas_prices",
121
+ args={"chainId": 1},
122
+ )
123
+ ```
124
+
125
+ ## Types
126
+
127
+ ```python
128
+ from ctxprotocol import (
129
+ # Auth utilities for tool contributors
130
+ verify_context_request,
131
+ is_protected_mcp_method,
132
+ is_open_mcp_method,
133
+
134
+ # Client types
135
+ ContextClientOptions,
136
+ Tool,
137
+ McpTool,
138
+ ExecuteOptions,
139
+ ExecutionResult,
140
+ ContextErrorCode,
141
+
142
+ # Auth types (for MCP server contributors)
143
+ VerifyRequestOptions,
144
+
145
+ # Context types (for MCP server contributors receiving injected data)
146
+ ContextRequirementType,
147
+ HyperliquidContext,
148
+ PolymarketContext,
149
+ WalletContext,
150
+ UserContext,
151
+ )
152
+ ```
153
+
154
+ ## Error Handling
155
+
156
+ The SDK raises `ContextError` with specific error codes:
157
+
158
+ ```python
159
+ from ctxprotocol import ContextClient, ContextError
160
+
161
+ try:
162
+ result = await client.tools.execute(...)
163
+ except ContextError as e:
164
+ match e.code:
165
+ case "no_wallet":
166
+ # User needs to set up wallet
167
+ print(f"Setup required: {e.help_url}")
168
+ case "insufficient_allowance":
169
+ # User needs to enable Auto Pay
170
+ print(f"Enable Auto Pay: {e.help_url}")
171
+ case "payment_failed":
172
+ # Insufficient USDC balance
173
+ pass
174
+ case "execution_failed":
175
+ # Tool execution error
176
+ pass
177
+ ```
178
+
179
+ ### Error Codes
180
+
181
+ | Code | Description | Handling |
182
+ |------|-------------|----------|
183
+ | `unauthorized` | Invalid API key | Check configuration |
184
+ | `no_wallet` | Wallet not set up | Direct user to `help_url` |
185
+ | `insufficient_allowance` | Auto Pay not enabled | Direct user to `help_url` |
186
+ | `payment_failed` | USDC payment failed | Check balance |
187
+ | `execution_failed` | Tool error | Retry with different args |
188
+
189
+ ## πŸ”’ Securing Your Tool (MCP Contributors)
190
+
191
+ If you're building an MCP server (tool contributor), verify incoming requests:
192
+
193
+ ### Quick Implementation with FastAPI
194
+
195
+ ```python
196
+ from fastapi import FastAPI, Request, Depends, HTTPException
197
+ from ctxprotocol import create_context_middleware, ContextError
198
+
199
+ app = FastAPI()
200
+ verify_context = create_context_middleware(audience="https://your-tool.com/mcp")
201
+
202
+ @app.post("/mcp")
203
+ async def handle_mcp(request: Request, context: dict = Depends(verify_context)):
204
+ # context contains verified JWT payload (on protected methods)
205
+ # None for open methods like tools/list
206
+ body = await request.json()
207
+ # Handle MCP request...
208
+ ```
209
+
210
+ ### Manual Verification
211
+
212
+ ```python
213
+ from ctxprotocol import verify_context_request, is_protected_mcp_method, ContextError
214
+
215
+ # Check if a method requires auth
216
+ if is_protected_mcp_method(body["method"]):
217
+ try:
218
+ payload = await verify_context_request(
219
+ authorization_header=request.headers.get("authorization"),
220
+ audience="https://your-tool.com/mcp", # optional
221
+ )
222
+ # payload contains verified JWT claims
223
+ except ContextError as e:
224
+ # Handle authentication error
225
+ raise HTTPException(status_code=401, detail="Unauthorized")
226
+ ```
227
+
228
+ ### Security Model
229
+
230
+ | MCP Method | Auth Required | Reason |
231
+ |------------|---------------|--------|
232
+ | `tools/list` | ❌ No | Discovery - just returns tool schemas |
233
+ | `tools/call` | βœ… Yes | Execution - runs code, may cost money |
234
+ | `initialize` | ❌ No | Session setup |
235
+ | `resources/list` | ❌ No | Discovery |
236
+ | `prompts/list` | ❌ No | Discovery |
237
+
238
+ ## Context Injection (Personalized Tools)
239
+
240
+ For tools that analyze user data, Context automatically injects user context:
241
+
242
+ ```python
243
+ from ctxprotocol import CONTEXT_REQUIREMENTS_KEY, HyperliquidContext
244
+
245
+ # Define tool with context requirements
246
+ TOOLS = [{
247
+ "name": "analyze_my_positions",
248
+ "description": "Analyze your positions with personalized insights",
249
+ "_meta": {
250
+ "contextRequirements": ["hyperliquid"],
251
+ },
252
+ "inputSchema": {
253
+ "type": "object",
254
+ "properties": {
255
+ "portfolio": {
256
+ "type": "object",
257
+ "description": "Portfolio context (injected by platform)",
258
+ },
259
+ },
260
+ "required": ["portfolio"],
261
+ },
262
+ }]
263
+
264
+ # Your handler receives typed context
265
+ async def handle_analyze_positions(portfolio: HyperliquidContext):
266
+ positions = portfolio.perp_positions
267
+ account = portfolio.account_summary
268
+ # ... analyze and return insights
269
+ ```
270
+
271
+ ## Links
272
+
273
+ - [Context Protocol](https://ctxprotocol.com) β€” Main website
274
+ - [Documentation](https://docs.ctxprotocol.com)
275
+ - [GitHub](https://github.com/ctxprotocol/sdk-python) β€” This SDK
276
+ - [TypeScript SDK](https://github.com/ctxprotocol/sdk) β€” For Node.js
277
+ - [PyPI Package](https://pypi.org/project/ctxprotocol/)
278
+
279
+ ## Requirements
280
+
281
+ - Python 3.10+
282
+ - httpx
283
+ - pydantic
284
+ - pyjwt[crypto]
285
+
286
+ ## License
287
+
288
+ MIT