Looking for Python? Check out the Python SDK Reference.
Installation
Requirements
- Node.js 18+ (for native fetch)
- TypeScript 5+ (recommended)
Prerequisites
Before using the API, complete setup at ctxprotocol.com:Quick Start
Want per-call pricing and spending limits? The SDK also supports Execute mode for direct method calls inside session budgets. See Two SDK Modes below.
Two SDK Modes
The SDK offers two payment models:| Mode | Method | Payment Model | Use Case |
|---|---|---|---|
| Query | client.query.run() | Pay-per-response | Complex questions, multi-tool synthesis, curated intelligence |
| Execute | client.tools.execute() | Per call (with spending limit) | Deterministic pipelines, raw outputs, explicit cost control |
You have access to both modes — pick the one that fits your use case.
- Use Query (
client.query.run()) when you want a managed librarian contract — Context handles discovery/orchestration (up to 100 MCP calls per response turn) and can return plainanswer,answer_with_evidence, orevidence_only. Pay-per-response (~$0.10). - Use Execute (
client.tools.execute()) when your app/agent is the librarian and you want per-call pricing with spending limits (~$0.001/call).
Execute Quick Start
Mixed listings are first-class: one listing can expose methods to both modes. Methods without explicit execute pricing remain discoverable for Query but are excluded from Execute discovery when
requireExecutePricing=true.Compatibility: payload fields like
price and pricePerQuery are kept for backward compatibility. In Query mode, they represent listing-level price per response turn.
A future major release can add response-named aliases (for example, pricePerResponse) before deprecating legacy names.Configuration
Client Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | Yes | — | Your Context Protocol API key |
baseUrl | string | No | https://ctxprotocol.com | API base URL (for development) |
API Reference
Discovery
client.discovery.search(query, limit?)
client.discovery.search(options)
Search for tools matching a query string, or pass an options object for mode-aware filtering.
Parameters (string signature):
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query |
limit | number | No | Maximum results to return |
| Option | Type | Required | Description |
|---|---|---|---|
query | string | No | Search query (empty for featured-style searches) |
limit | number | No | Maximum results to return |
mode | "query" | "execute" | No | Discovery mode with billing semantics |
surface | "answer" | "execute" | "both" | No | Method mode filter |
queryEligible | boolean | No | Require methods that are query-safe |
requireExecutePricing | boolean | No | Require explicit method execute pricing |
excludeLatencyClasses | ("instant" | "fast" | "slow" | "streaming")[] | No | Exclude by latency class |
excludeSlow | boolean | No | Convenience filter for query mode |
Promise<Tool[]>
client.discovery.getFeatured(limit?, options?)
Get featured/popular tools.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum results to return |
options | Omit<SearchOptions, "query" | "limit"> | No | Optional mode filters |
Promise<Tool[]>
Tools (Execute Mode)
client.tools.execute(options)
Execute a single tool method. Execute calls can run inside a session budget (maxSpendUsd) with automatic payment after delivery.
Parameters:
| Option | Type | Required | Description |
|---|---|---|---|
toolId | string | Yes | UUID of the tool |
toolName | string | Yes | Name of the method to call |
args | object | No | Arguments matching the tool’s inputSchema |
idempotencyKey | string | No | Optional idempotency key (UUID recommended) |
mode | "execute" | No | Explicit mode label (defaults to "execute") |
sessionId | string | No | Execute session ID to accrue spend against |
maxSpendUsd | string | No | Optional inline session budget (if no sessionId) |
closeSession | boolean | No | Request session closure after this call settles |
Promise<ExecutionResult>
client.tools.startSession({ maxSpendUsd })
Start an execute session budget envelope.
client.tools.getSession(sessionId)
Fetch current execute session status/spend.
client.tools.closeSession(sessionId)
Close an execute session and trigger final flush behavior.
Query (Pay-Per-Response)
The Query API is Context’s response marketplace — instead of buying raw API calls, you’re buying curated intelligence. Ask a question, pay once, and get a managed answer contract backed by multi-tool data aggregation, error recovery, and completeness checks.
client.query.run(options)
Run an agentic query. The server applies discovery-first orchestration (discover/probe -> plan-from-evidence -> execute -> bounded fallback) with up to 100 MCP calls per response turn as a runtime safety cap, then returns the selected Query response contract (answer, answer_with_evidence, or evidence_only). The active runtime now has one real completeness-oriented deep lane plus the lower-latency fast lane. deep stays metadata-first before planning, and fast remains one-shot biased. Query billing is pay-per-response with automatic payment after delivery.
Parameters:
| Option | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural-language question |
tools | string[] | No | Tool IDs to use (auto-discover if omitted) |
answerModelId | string | No | Final synthesis model ID (e.g. kimi-model-thinking, glm-model) |
responseShape | "answer" | "answer_with_evidence" | "evidence_only" | No | Structured response mode for Query answers |
includeData | boolean | No | Include execution data inline in the response |
includeDataUrl | boolean | No | Persist execution data to blob and return a URL |
includeDeveloperTrace | boolean | No | Include optional developer trace + orchestration diagnostics |
queryDepth | "fast" | "auto" | "deep" | No | Query orchestration depth (fast lower latency, auto server-routed, deep completeness-oriented) |
debugScoutDeepMode | "deep" | No | Development/testing only internal deep lane override; legacy deep-light / deep-heavy aliases are temporarily accepted |
idempotencyKey | string | No | Optional idempotency key (UUID recommended) |
client.query.run("your question")
Returns: Promise<QueryResult>
answerModelId lets headless users choose the final synthesis model explicitly. If omitted, the API uses its managed default answer model.
If responseShape is evidence_only, synthesis is skipped and no answer model runs for that request.Current platform IDs: kimi-model-thinking, glm-model, gemini-flash-model, claude-sonnet-model, claude-opus-model.queryDepth is available in both run() and stream():fast: lower-latency path for simple lookups.auto: server routes to eitherfastordeepusing query intent and selected tool metadata quality.deep: completeness-oriented path (default when omitted).
includeDeveloperTrace and orchestrationMetrics are optional diagnostics.
debugScoutDeepMode remains test-only and is ignored by normal production usage.
Inside deep, the runtime currently uses one real metadata-first deep path. Legacy deep-light and deep-heavy debug values are normalized to deep when accepted for backwards compatibility.
Selection diagnostics can show initial vs final lane decisions, Scout probe adequacy, bounded pre-plan probe call counts, and whether pre-plan evidence changed the initial plan.Structured Response Shapes
Query is Context’s managed librarian contract. You can choose how much structure you want back:responseShape | Best for | Behavior |
|---|---|---|
answer | Backward compatibility | Natural-language answer only |
answer_with_evidence | First-party chat, human-facing apps | Prose answer plus structured evidence, artifacts, freshness, confidence, and usage metadata |
evidence_only | External agents, downstream automation | Machine-friendly summary plus the same structured evidence package without depending on prose synthesis |
answer_with_evidence, but it is using the same Query contract you get in the SDK.
Query Envelope Fields
WhenresponseShape is answer_with_evidence or evidence_only, the result may include:
| Field | What it contains |
|---|---|
summary | Short machine-friendly summary of the answer |
evidence | Canonical facts, source refs, assumptions, known unknowns, and retrieval reason codes |
artifacts | dataUrl, canonical dataset metadata, and stage-artifact kinds |
view | Optional UI/render hint such as table, leaderboard, heatmap, or timeseries |
freshness | asOf, source timestamps, and freshness note |
confidence | Confidence level, reason, fact counts, and gap signals |
usage | Duration, cost, tools used, outcome type, and optional orchestration metrics |
High-Fidelity Rehydration (Retrieval-First Synthesis)
When retrieval-first rollout is enabled in the deployment, the query runtime can switch synthesis context assembly from baseline truncation to retrieval-first slices for full-data or truncation-sensitive requests.- Stage artifacts are emitted in request-scoped internal storage (selection, planning, execution, completeness, synthesis).
- Retrieval primitives (path lookup, array windows/sampling, keyword slices, top-K relevance) are used to build a bounded context pack from canonical execution data.
- Final synthesis still passes through the existing synthesis safety contract.
includeDataandincludeDataUrlcontinue to reference the same canonical execution dataset used by retrieval-first assembly.
client.query.stream(options)
Same as run() but streams events in real-time via SSE.
Supports the same options as run() (tools, answerModelId, responseShape, includeData, includeDataUrl, includeDeveloperTrace, queryDepth, debugScoutDeepMode, idempotencyKey).
Returns: AsyncGenerator<QueryStreamEvent>
Use the same
idempotencyKey when retrying the same logical request after network/timeout failures.If you stream with
responseShape: "evidence_only", expect the structured result on the final done event and few or no text-delta events.Types
Import Types
Tool
McpTool
For argument guidance, use standard JSON Schema fields directly inside
inputSchema properties. Put fallback values in default and sample invocations in examples. Do not rely on custom _meta.inputExamples.ExecutionResult (Execute Mode)
ExecuteSessionSpend
QueryResult (Pay-Per-Response)
Context Requirement Types
For MCP server contributors building tools that need user context (e.g., wallet data, portfolio positions):Why Context Injection Matters:
- No Auth Required: Public blockchain/user data is fetched by the platform, so you don’t need to handle API keys or user login.
- Security: Your MCP server never handles private keys or sensitive credentials.
- Simplicity: You receive structured, type-safe data directly in your tool arguments.
Why
_meta at the tool level? The _meta field is part of the MCP specification for arbitrary tool metadata. The Context platform reads _meta.contextRequirements for context injection and _meta.rateLimit / _meta.rateLimitHints for planner/runtime pacing behavior. This is preserved through MCP transport because it’s a standard field.Reference implementation: Coinglass contributor server.
For when/how to set these fields, see Tool Metadata.
Injected Context Types
HyperliquidContext
PolymarketContext
WalletContext
Contributor Search Helpers
If you are building a contributor for a search-hard venue, the SDK ships an optional helper surface at@ctxprotocol/sdk/contrib/search.
Use it only when the venue’s upstream search is weak enough that deterministic retrieval plus a bounded model judge materially improves candidate resolution. Do not use it for venues that already expose reliable direct search.
- contributor-side intent shaping, candidate normalization, shortlist construction, and validated resolution
- provider-agnostic judge injection with stable override knobs for
provider,model,timeout,budget, anddisabled - machine-readable artifact generation via
buildContributorSearchValidationArtifact(...) - runtime trace inspection via
extractContributorSearchesFromDeveloperTrace(trace)orresult.developerTrace?.diagnostics?.contributorSearches
- extra judge spend is contributor-owned in this rollout, so recover it through your own listing response price and/or execute pricing
- keep deterministic validation around every judge result; malformed, timed-out, over-budget, or contradictory judgments must degrade honestly
- save replayable validation artifacts alongside your contributor examples. Current reference directories live under
examples/server/polymarket-contributor/validation/andexamples/server/kalshi-contributor/validation/
Error Handling
The SDK throwsContextError with specific error codes:
Error Codes
| Code | Description | Handling |
|---|---|---|
unauthorized | Invalid API key | Check configuration |
no_wallet | Wallet not set up | Direct user to helpUrl |
insufficient_allowance | Spending cap not set | Direct user to helpUrl |
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, verify incoming requests are legitimate.Free vs Paid Security Requirements:
| Tool Type | Security Middleware | Rationale |
|---|---|---|
| Free Tools ($0.00) | Optional | Great for distribution and adoption |
| Paid Tools ($0.01+) | Mandatory | We cannot route payments to insecure endpoints |
Quick Implementation
MCP Security Model
| MCP Method | Auth Required | Why |
|---|---|---|
initialize | ❌ No | Session setup |
tools/list | ❌ No | Discovery - agents need to see your schemas |
resources/list | ❌ No | Discovery |
prompts/list | ❌ No | Discovery |
tools/call | ✅ Yes | Execution - costs money, runs your code |
What this means in practice:
- ✅
https://your-mcp.com/mcp+initialize→ Works without auth - ✅
https://your-mcp.com/mcp+tools/list→ Works without auth - ❌
https://your-mcp.com/mcp+tools/call→ Requires Context Protocol JWT
Manual Verification
For more control, use the lower-level utilities:Verification Options
| Option | Type | Required | Description |
|---|---|---|---|
authorizationHeader | string | Yes | Full Authorization header (e.g., "Bearer eyJ...") |
audience | string | No | Expected audience claim for stricter validation |
Payment Flow
Context supports two settlement timings:- Query mode (
client.query.*) uses deferred settlement after the response is delivered - Execute mode (
client.tools.execute) accrues per-call method spend into execute sessions with automatic batch payment - In both modes, spending caps are enforced via ContextRouter allowance checks
- 90% goes to the tool developer, 10% goes to the protocol
Links
- Context Protocol — Main website
- NPM Package
- GitHub (TypeScript SDK)
- Python SDK — For Python developers

