Skip to main content

Official Python SDK for the Context Protocol - Discover and execute AI tools programmatically

Project description

ctxprotocol

The Universal Adapter for AI Agents.

Connect your AI to the real world without managing API keys, hosting servers, or reading documentation.

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.

PyPI version Python versions License: MIT

Why use Context?

  • 🔌 One Interface, Everything: Stop integrating APIs one by one. Use a single SDK to access any tool in the marketplace.
  • 🧠 Zero-Ops: We're a gateway to the best MCP tools. Just send the JSON and get the result.
  • ⚡️ Agentic Discovery: Your Agent can search the marketplace at runtime to find tools it didn't know it needed.
  • 💸 Micro-Billing: Pay only for what you use (e.g., $0.001/query). No monthly subscriptions for tools you rarely use.

Who Is This SDK For?

Role What You Use
AI Agent Developer ctxprotocol — Query marketplace, execute tools, handle payments
Tool Contributor (Data Broker) mcp + ctxprotocol — Standard MCP server + security middleware

Installation

pip install ctxprotocol

Or with optional FastAPI support:

pip install ctxprotocol[fastapi]

Prerequisites

Before using the API, complete setup at ctxprotocol.com:

  1. Sign in — Creates your embedded wallet
  2. Enable Auto Pay — Approve USDC spending for tool payments
  3. Fund wallet — Add USDC for tool execution fees
  4. Generate API key — In Settings page

Quick Start

import asyncio
from ctxprotocol import ContextClient

async def main():
    async with ContextClient(api_key="sk_live_...") as client:
        # Discover tools
        tools = await client.discovery.search("gas prices")
        
        # Execute a tool
        result = await client.tools.execute(
            tool_id=tools[0].id,
            tool_name=tools[0].mcp_tools[0].name,
            args={"chainId": 1},
        )
        
        print(result.result)

asyncio.run(main())

Configuration

Client Options

Option Type Required Default Description
api_key str Yes Your Context Protocol API key
base_url str No https://ctxprotocol.com API base URL (for development)
# Production
client = ContextClient(api_key=os.environ["CONTEXT_API_KEY"])

# Local development
client = ContextClient(
    api_key="sk_test_...",
    base_url="http://localhost:3000",
)

API Reference

Discovery

client.discovery.search(query, limit?)

Search for tools matching a query string.

tools = await client.discovery.search("ethereum gas", limit=10)

client.discovery.get_featured(limit?)

Get featured/popular tools.

featured = await client.discovery.get_featured(limit=5)

Tools

client.tools.execute(tool_id, tool_name, args?)

Execute a tool method.

result = await client.tools.execute(
    tool_id="uuid-of-tool",
    tool_name="get_gas_prices",
    args={"chainId": 1},
)

Types

from ctxprotocol import (
    # Auth utilities for tool contributors
    verify_context_request,
    is_protected_mcp_method,
    is_open_mcp_method,
    
    # Client types
    ContextClientOptions,
    Tool,
    McpTool,
    ExecuteOptions,
    ExecutionResult,
    ContextErrorCode,
    
    # Auth types (for MCP server contributors)
    VerifyRequestOptions,
    
    # Context types (for MCP server contributors receiving injected data)
    ContextRequirementType,
    HyperliquidContext,
    PolymarketContext,
    WalletContext,
    UserContext,
)

Error Handling

The SDK raises ContextError with specific error codes:

from ctxprotocol import ContextClient, ContextError

try:
    result = await client.tools.execute(...)
except ContextError as e:
    match e.code:
        case "no_wallet":
            # User needs to set up wallet
            print(f"Setup required: {e.help_url}")
        case "insufficient_allowance":
            # User needs to enable Auto Pay
            print(f"Enable Auto Pay: {e.help_url}")
        case "payment_failed":
            # Insufficient USDC balance
            pass
        case "execution_failed":
            # Tool execution error
            pass

Error Codes

Code Description Handling
unauthorized Invalid API key Check configuration
no_wallet Wallet not set up Direct user to help_url
insufficient_allowance Auto Pay not enabled Direct user to help_url
payment_failed USDC payment failed Check balance
execution_failed Tool error Retry with different args

🔒 Securing Your Tool (MCP Contributors)

If you're building an MCP server (tool contributor), verify incoming requests:

Quick Implementation with FastAPI

from fastapi import FastAPI, Request, Depends, HTTPException
from ctxprotocol import create_context_middleware, ContextError

app = FastAPI()
verify_context = create_context_middleware(audience="https://your-tool.com/mcp")

@app.post("/mcp")
async def handle_mcp(request: Request, context: dict = Depends(verify_context)):
    # context contains verified JWT payload (on protected methods)
    # None for open methods like tools/list
    body = await request.json()
    # Handle MCP request...

Manual Verification

from ctxprotocol import verify_context_request, is_protected_mcp_method, ContextError

# Check if a method requires auth
if is_protected_mcp_method(body["method"]):
    try:
        payload = await verify_context_request(
            authorization_header=request.headers.get("authorization"),
            audience="https://your-tool.com/mcp",  # optional
        )
        # payload contains verified JWT claims
    except ContextError as e:
        # Handle authentication error
        raise HTTPException(status_code=401, detail="Unauthorized")

Security Model

MCP Method Auth Required Reason
tools/list ❌ No Discovery - just returns tool schemas
tools/call ✅ Yes Execution - runs code, may cost money
initialize ❌ No Session setup
resources/list ❌ No Discovery
prompts/list ❌ No Discovery

Context Injection (Personalized Tools)

For tools that analyze user data, Context automatically injects user context:

from ctxprotocol import CONTEXT_REQUIREMENTS_KEY, HyperliquidContext

# Define tool with context requirements
TOOLS = [{
    "name": "analyze_my_positions",
    "description": "Analyze your positions with personalized insights",
    "_meta": {
        "contextRequirements": ["hyperliquid"],
    },
    "inputSchema": {
        "type": "object",
        "properties": {
            "portfolio": {
                "type": "object",
                "description": "Portfolio context (injected by platform)",
            },
        },
        "required": ["portfolio"],
    },
}]

# Your handler receives typed context
async def handle_analyze_positions(portfolio: HyperliquidContext):
    positions = portfolio.perp_positions
    account = portfolio.account_summary
    # ... analyze and return insights

Links

Requirements

  • Python 3.10+
  • httpx
  • pydantic
  • pyjwt[crypto]

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

ctxprotocol-0.5.5.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ctxprotocol-0.5.5-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

File details

Details for the file ctxprotocol-0.5.5.tar.gz.

File metadata

  • Download URL: ctxprotocol-0.5.5.tar.gz
  • Upload date:
  • Size: 16.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for ctxprotocol-0.5.5.tar.gz
Algorithm Hash digest
SHA256 52e3562630d66d9e79bd6a42f840846eb06431793af759898d66031d1bf8b80a
MD5 5b95e85cc0d6c754cf82d0367c04793f
BLAKE2b-256 28b2c3876527a091fcbc80796208059eb38fb5afc6cd61d8d9c24465c55a0527

See more details on using hashes here.

File details

Details for the file ctxprotocol-0.5.5-py3-none-any.whl.

File metadata

  • Download URL: ctxprotocol-0.5.5-py3-none-any.whl
  • Upload date:
  • Size: 22.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for ctxprotocol-0.5.5-py3-none-any.whl
Algorithm Hash digest
SHA256 9b60de6d088250b076cca36ec5661c257f9dd426721ab7338a520244699cceb9
MD5 03e847a21bcd847378da3463778b26d3
BLAKE2b-256 1fef2d44df5aece84d98883d8d87f95c9591ab8aedd0db777288e4d1ab049e12

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page