@ctxprotocol/sdk 0.5.5 → 0.6.0
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.
- package/README.md +123 -47
- package/dist/client/index.cjs +80 -26
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +20 -6
- package/dist/client/index.d.ts +20 -6
- package/dist/client/index.js +80 -26
- package/dist/client/index.js.map +1 -1
- package/dist/index.cjs +176 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +270 -16
- package/dist/index.d.ts +270 -16
- package/dist/index.js +169 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,23 +9,41 @@ Context Protocol is **npm for AI capabilities**. Just as you install packages to
|
|
|
9
9
|
[](https://www.npmjs.com/package/@ctxprotocol/sdk)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
11
|
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
### 💰 $10,000 Developer Grant Program
|
|
15
|
+
|
|
16
|
+
We're funding the initial supply of MCP Tools for the Context Marketplace. **Become a Data Broker.**
|
|
17
|
+
|
|
18
|
+
- **🛠️ Build:** Create an MCP Server using this SDK (Solana data, Trading tools, Scrapers, etc.)
|
|
19
|
+
- **📦 List:** Publish it to the Context Registry
|
|
20
|
+
- **💵 Earn:** Get a **$250–$1,000 Grant** + earn USDC every time an agent queries your tool
|
|
21
|
+
|
|
22
|
+
👉 [**View Open Bounties & Apply Here**](https://docs.ctxprotocol.com/grants)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
12
26
|
## Why use Context?
|
|
13
27
|
|
|
14
28
|
- **🔌 One Interface, Everything:** Stop integrating APIs one by one. Use a single SDK to access any tool in the marketplace.
|
|
15
29
|
- **🧠 Zero-Ops:** We're a gateway to the best MCP tools. Just send the JSON and get the result.
|
|
16
30
|
- **⚡️ Agentic Discovery:** Your Agent can search the marketplace at runtime to find tools it didn't know it needed.
|
|
17
|
-
- **💸
|
|
31
|
+
- **💸 Pay-Per-Response:** The $500/year subscription? Now $0.01/response. No monthly fees, just results.
|
|
18
32
|
|
|
19
33
|
## Who Is This SDK For?
|
|
20
34
|
|
|
21
|
-
**This SDK is for AI Agent developers** who want to query the Context marketplace and execute tools.
|
|
22
|
-
|
|
23
35
|
| Role | What You Use |
|
|
24
36
|
|------|--------------|
|
|
25
37
|
| **AI Agent Developer** | `@ctxprotocol/sdk` — Query marketplace, execute tools, handle payments |
|
|
26
|
-
| **Tool Contributor (Data Broker)** | `@modelcontextprotocol/sdk` — Standard MCP server +
|
|
38
|
+
| **Tool Contributor (Data Broker)** | `@modelcontextprotocol/sdk` + `@ctxprotocol/sdk` — Standard MCP server + security middleware |
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
**For AI Agent Developers:** Use this SDK to search the marketplace, execute tools, and handle micro-payments.
|
|
41
|
+
|
|
42
|
+
**For Tool Contributors:** You need **both** SDKs:
|
|
43
|
+
- `@modelcontextprotocol/sdk` — Build your MCP server (tools, schemas, handlers)
|
|
44
|
+
- `@ctxprotocol/sdk` — Secure your endpoint with `createContextMiddleware()` and receive injected user portfolio data
|
|
45
|
+
|
|
46
|
+
See [Building MCP Servers](#building-mcp-servers-tool-contributors) and [Securing Your Tool](#-securing-your-tool) for the complete pattern.
|
|
29
47
|
|
|
30
48
|
## Installation
|
|
31
49
|
|
|
@@ -265,8 +283,6 @@ const result = await client.tools.execute({
|
|
|
265
283
|
|
|
266
284
|
```typescript
|
|
267
285
|
import {
|
|
268
|
-
// Constant for declaring context requirements
|
|
269
|
-
CONTEXT_REQUIREMENTS_KEY,
|
|
270
286
|
// Auth utilities for tool contributors
|
|
271
287
|
verifyContextRequest,
|
|
272
288
|
isProtectedMcpMethod,
|
|
@@ -330,21 +346,27 @@ interface ExecutionResult<T = unknown> {
|
|
|
330
346
|
### Context Requirement Types (MCP Server Contributors)
|
|
331
347
|
|
|
332
348
|
```typescript
|
|
333
|
-
import {
|
|
349
|
+
import type { ContextRequirementType } from "@ctxprotocol/sdk";
|
|
334
350
|
|
|
335
351
|
/** Context types supported by the marketplace */
|
|
336
352
|
type ContextRequirementType = "polymarket" | "hyperliquid" | "wallet";
|
|
337
353
|
|
|
338
|
-
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
354
|
+
// Usage: Add _meta.contextRequirements to your tool definition
|
|
355
|
+
const TOOLS = [{
|
|
356
|
+
name: "analyze_my_positions",
|
|
357
|
+
description: "...",
|
|
358
|
+
|
|
359
|
+
// ⭐ Declare context requirements in _meta (MCP spec)
|
|
360
|
+
_meta: {
|
|
361
|
+
contextRequirements: ["wallet"] as ContextRequirementType[],
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
inputSchema: {
|
|
365
|
+
type: "object",
|
|
366
|
+
properties: { wallet: { type: "object" } },
|
|
367
|
+
required: ["wallet"]
|
|
368
|
+
},
|
|
369
|
+
}];
|
|
348
370
|
```
|
|
349
371
|
|
|
350
372
|
## Error Handling
|
|
@@ -431,17 +453,22 @@ app.post("/mcp", (req, res) => {
|
|
|
431
453
|
| **Free Tools ($0.00)** | Optional | Perfect for distribution and adoption |
|
|
432
454
|
| **Paid Tools ($0.01+)** | **Mandatory** | We cannot route payments to insecure endpoints |
|
|
433
455
|
|
|
434
|
-
### Security Model
|
|
456
|
+
### MCP Security Model
|
|
435
457
|
|
|
436
|
-
The SDK implements a **selective authentication** model:
|
|
458
|
+
The SDK implements a **selective authentication** model — discovery is open, execution is protected:
|
|
437
459
|
|
|
438
|
-
| MCP Method | Auth Required |
|
|
439
|
-
|
|
440
|
-
| `tools/list` | ❌ No | Discovery - just returns tool schemas |
|
|
441
|
-
| `tools/call` | ✅ Yes | Execution - runs code, may cost money |
|
|
460
|
+
| MCP Method | Auth Required | Why |
|
|
461
|
+
|------------|---------------|-----|
|
|
442
462
|
| `initialize` | ❌ No | Session setup |
|
|
463
|
+
| `tools/list` | ❌ No | Discovery - agents need to see your schemas |
|
|
443
464
|
| `resources/list` | ❌ No | Discovery |
|
|
444
465
|
| `prompts/list` | ❌ No | Discovery |
|
|
466
|
+
| `tools/call` | ✅ **Yes** | **Execution - costs money, runs your code** |
|
|
467
|
+
|
|
468
|
+
**What this means in practice:**
|
|
469
|
+
- ✅ `https://your-mcp.com/mcp` + `initialize` → Works without auth
|
|
470
|
+
- ✅ `https://your-mcp.com/mcp` + `tools/list` → Works without auth
|
|
471
|
+
- ❌ `https://your-mcp.com/mcp` + `tools/call` → **Requires Context Protocol JWT**
|
|
445
472
|
|
|
446
473
|
This matches standard API patterns (OpenAPI schemas are public, GraphQL introspection is open).
|
|
447
474
|
|
|
@@ -505,48 +532,86 @@ Want to earn money by contributing tools to the Context marketplace? Build a sta
|
|
|
505
532
|
| `outputSchema` | AI agents use this to generate type-safe code. Context uses it for dispute resolution. |
|
|
506
533
|
| `structuredContent` | Agents parse this for programmatic access. Text `content` is for humans. |
|
|
507
534
|
|
|
508
|
-
### Context Injection (
|
|
535
|
+
### Context Injection (Personalized Tools)
|
|
509
536
|
|
|
510
|
-
Building tools that analyze user
|
|
537
|
+
Building tools that analyze user data? Context automatically injects user context into your tools no authentication required.
|
|
511
538
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
539
|
+
**How it works:**
|
|
540
|
+
1. User connects their wallet in the Context app (we start with blockchain user data, but we're open to other client-side personal data types in the future)
|
|
541
|
+
2. When your tool is selected, the platform reads `_meta.contextRequirements` from your tool definition
|
|
542
|
+
3. Platform fetches the user's data (wallet balances, protocol positions, etc.)
|
|
543
|
+
4. Data is injected as an argument to your tool
|
|
544
|
+
|
|
545
|
+
**Key benefits:**
|
|
546
|
+
- **No Auth Required** — User data is injected automatically from connected wallets
|
|
547
|
+
- **Type-Safe** — Use SDK types like `WalletContext`, `PolymarketContext`, `HyperliquidContext`
|
|
517
548
|
- **Focus on Analysis** — You receive structured data, you provide insights
|
|
518
549
|
|
|
550
|
+
**What gets injected:**
|
|
551
|
+
|
|
552
|
+
```typescript
|
|
553
|
+
// For hyperliquid context requirement
|
|
554
|
+
interface HyperliquidContext {
|
|
555
|
+
walletAddress: string;
|
|
556
|
+
perpPositions: HyperliquidPerpPosition[];
|
|
557
|
+
spotBalances: HyperliquidSpotBalance[];
|
|
558
|
+
openOrders: HyperliquidOrder[];
|
|
559
|
+
accountSummary: HyperliquidAccountSummary;
|
|
560
|
+
fetchedAt: string;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// For polymarket context requirement
|
|
564
|
+
interface PolymarketContext {
|
|
565
|
+
walletAddress: string;
|
|
566
|
+
positions: PolymarketPosition[];
|
|
567
|
+
openOrders: PolymarketOrder[];
|
|
568
|
+
totalValue?: number;
|
|
569
|
+
fetchedAt: string;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// For wallet context requirement
|
|
573
|
+
interface WalletContext {
|
|
574
|
+
address: string;
|
|
575
|
+
chainId: number;
|
|
576
|
+
balances: TokenBalance[];
|
|
577
|
+
fetchedAt: string;
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
519
581
|
### Context Requirements Declaration
|
|
520
582
|
|
|
521
|
-
If your tool needs user portfolio data, you **MUST** declare this using
|
|
583
|
+
If your tool needs user portfolio data, you **MUST** declare this using `_meta.contextRequirements` on the tool definition:
|
|
522
584
|
|
|
523
585
|
```typescript
|
|
524
|
-
import {
|
|
586
|
+
import type { ContextRequirementType } from "@ctxprotocol/sdk";
|
|
525
587
|
|
|
526
588
|
const TOOLS = [{
|
|
527
589
|
name: "analyze_my_positions",
|
|
528
590
|
description: "Analyze your positions with personalized insights",
|
|
529
591
|
|
|
592
|
+
// ⭐ REQUIRED: Context requirements in _meta (MCP spec for arbitrary metadata)
|
|
593
|
+
// The Context platform reads this to inject user data
|
|
594
|
+
_meta: {
|
|
595
|
+
contextRequirements: ["wallet"] as ContextRequirementType[],
|
|
596
|
+
},
|
|
597
|
+
|
|
530
598
|
inputSchema: {
|
|
531
599
|
type: "object",
|
|
532
|
-
// ⭐ REQUIRED: Context requirements embedded in inputSchema
|
|
533
|
-
[CONTEXT_REQUIREMENTS_KEY]: ["hyperliquid"] as ContextRequirementType[],
|
|
534
|
-
// Or use the string directly: "x-context-requirements": ["hyperliquid"]
|
|
535
600
|
properties: {
|
|
536
|
-
|
|
601
|
+
wallet: {
|
|
537
602
|
type: "object",
|
|
538
|
-
description: "
|
|
603
|
+
description: "Wallet context (injected by platform)",
|
|
539
604
|
},
|
|
540
605
|
},
|
|
541
|
-
required: ["
|
|
606
|
+
required: ["wallet"],
|
|
542
607
|
},
|
|
543
608
|
outputSchema: { /* ... */ },
|
|
544
609
|
}];
|
|
545
610
|
```
|
|
546
611
|
|
|
547
|
-
**Why `
|
|
612
|
+
**Why `_meta` at the tool level?**
|
|
548
613
|
|
|
549
|
-
The
|
|
614
|
+
The `_meta` field is part of the [MCP specification](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-definition) for arbitrary tool metadata. The Context platform reads `_meta.contextRequirements` to determine what user data to inject. This is preserved through MCP transport because it's a standard field.
|
|
550
615
|
|
|
551
616
|
**Available context types:**
|
|
552
617
|
|
|
@@ -556,12 +621,6 @@ The MCP protocol only transmits standard fields (`name`, `description`, `inputSc
|
|
|
556
621
|
| `"polymarket"` | Polymarket prediction markets | `PolymarketContext` |
|
|
557
622
|
| `"wallet"` | Generic EVM wallet | `WalletContext` |
|
|
558
623
|
|
|
559
|
-
**How it works:**
|
|
560
|
-
1. User links their wallet in Context app settings
|
|
561
|
-
2. When your tool is selected, platform reads `inputSchema["x-context-requirements"]`
|
|
562
|
-
3. Platform fetches user's portfolio data from protocol APIs
|
|
563
|
-
4. Data is injected as the `portfolio` argument to your tool
|
|
564
|
-
|
|
565
624
|
### Example: Standard MCP Server
|
|
566
625
|
|
|
567
626
|
Build your server with the standard `@modelcontextprotocol/sdk`:
|
|
@@ -619,6 +678,22 @@ See complete working examples in `/examples/server/`:
|
|
|
619
678
|
- **[blocknative-contributor](./examples/server/blocknative-contributor)** — Gas price API (3 tools)
|
|
620
679
|
- **[hyperliquid-contributor](./examples/server/hyperliquid-contributor)** — DeFi analytics (16 tools)
|
|
621
680
|
|
|
681
|
+
### Execution Timeout & Product Design
|
|
682
|
+
|
|
683
|
+
⚠️ **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.
|
|
684
|
+
|
|
685
|
+
**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—they don't give raw SQL access, they serve curated insights.
|
|
686
|
+
|
|
687
|
+
```typescript
|
|
688
|
+
// ❌ BAD: Raw access (timeout-prone, no moat)
|
|
689
|
+
{ name: "run_sql", description: "Run any SQL against blockchain data" }
|
|
690
|
+
|
|
691
|
+
// ✅ GOOD: Pre-computed product (instant, defensible)
|
|
692
|
+
{ name: "get_smart_money_wallets", description: "Top 100 wallets that timed market tops" }
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
See the [full documentation](https://docs.ctxprotocol.com/guides/build-tools#execution-limits--product-design) for detailed guidance.
|
|
696
|
+
|
|
622
697
|
### Schema Accuracy = Revenue
|
|
623
698
|
|
|
624
699
|
⚠️ **Important**: Your `outputSchema` is a contract. Context's "Robot Judge" validates that your `structuredContent` matches your declared schema. Schema violations result in automatic refunds to users.
|
|
@@ -643,6 +718,7 @@ When you execute a tool:
|
|
|
643
718
|
|
|
644
719
|
| Document | Description |
|
|
645
720
|
|----------|-------------|
|
|
721
|
+
| [MCP Builder Template](./docs/mcp-builder-template.md) | **Start here!** AI-powered template for designing MCP servers with Cursor. Generates discovery questions and tool schemas automatically. |
|
|
646
722
|
| [Context Injection Guide](./docs/context-injection.md) | Architecture guide for building portfolio analysis tools with automatic user data injection |
|
|
647
723
|
| [Polymarket Example](./examples/server/polymarket-contributor) | Complete MCP server for Polymarket intelligence |
|
|
648
724
|
| [Hyperliquid Example](./examples/server/hyperliquid-contributor) | Complete MCP server for Hyperliquid analytics |
|
package/dist/client/index.cjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/client/types.ts
|
|
4
|
-
var ContextError = class extends Error {
|
|
4
|
+
var ContextError = class _ContextError extends Error {
|
|
5
5
|
constructor(message, code, statusCode, helpUrl) {
|
|
6
6
|
super(message);
|
|
7
7
|
this.code = code;
|
|
8
8
|
this.statusCode = statusCode;
|
|
9
9
|
this.helpUrl = helpUrl;
|
|
10
10
|
this.name = "ContextError";
|
|
11
|
+
Object.setPrototypeOf(this, _ContextError.prototype);
|
|
11
12
|
}
|
|
12
13
|
};
|
|
13
14
|
|
|
@@ -40,7 +41,7 @@ var Discovery = class {
|
|
|
40
41
|
}
|
|
41
42
|
const queryString = params.toString();
|
|
42
43
|
const endpoint = `/api/v1/tools/search${queryString ? `?${queryString}` : ""}`;
|
|
43
|
-
const response = await this.client.
|
|
44
|
+
const response = await this.client._fetch(endpoint);
|
|
44
45
|
return response.tools;
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
@@ -97,7 +98,7 @@ var Tools = class {
|
|
|
97
98
|
*/
|
|
98
99
|
async execute(options) {
|
|
99
100
|
const { toolId, toolName, args } = options;
|
|
100
|
-
const response = await this.client.
|
|
101
|
+
const response = await this.client._fetch(
|
|
101
102
|
"/api/v1/tools/execute",
|
|
102
103
|
{
|
|
103
104
|
method: "POST",
|
|
@@ -108,7 +109,8 @@ var Tools = class {
|
|
|
108
109
|
throw new ContextError(
|
|
109
110
|
response.error,
|
|
110
111
|
response.code,
|
|
111
|
-
|
|
112
|
+
void 0,
|
|
113
|
+
// Don't hardcode - this was a 200 OK with error body
|
|
112
114
|
response.helpUrl
|
|
113
115
|
);
|
|
114
116
|
}
|
|
@@ -127,6 +129,7 @@ var Tools = class {
|
|
|
127
129
|
var ContextClient = class {
|
|
128
130
|
apiKey;
|
|
129
131
|
baseUrl;
|
|
132
|
+
_closed = false;
|
|
130
133
|
/**
|
|
131
134
|
* Discovery resource for searching tools
|
|
132
135
|
*/
|
|
@@ -151,38 +154,89 @@ var ContextClient = class {
|
|
|
151
154
|
this.discovery = new Discovery(this);
|
|
152
155
|
this.tools = new Tools(this);
|
|
153
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Close the client and clean up resources.
|
|
159
|
+
* After calling close(), any in-flight requests may be aborted.
|
|
160
|
+
*/
|
|
161
|
+
close() {
|
|
162
|
+
this._closed = true;
|
|
163
|
+
}
|
|
154
164
|
/**
|
|
155
165
|
* Internal method for making authenticated HTTP requests
|
|
156
|
-
*
|
|
166
|
+
* Includes timeout (30s) and retry with exponential backoff for transient errors
|
|
157
167
|
*
|
|
158
168
|
* @internal
|
|
159
169
|
*/
|
|
160
|
-
async
|
|
170
|
+
async _fetch(endpoint, options = {}) {
|
|
171
|
+
if (this._closed) {
|
|
172
|
+
throw new ContextError("Client has been closed");
|
|
173
|
+
}
|
|
161
174
|
const url = `${this.baseUrl}${endpoint}`;
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
if (!response.ok) {
|
|
171
|
-
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
172
|
-
let errorCode;
|
|
173
|
-
let helpUrl;
|
|
175
|
+
const maxRetries = 3;
|
|
176
|
+
const timeoutMs = 3e4;
|
|
177
|
+
let lastError;
|
|
178
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
179
|
+
const controller = new AbortController();
|
|
180
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
174
181
|
try {
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
182
|
+
const response = await fetch(url, {
|
|
183
|
+
...options,
|
|
184
|
+
signal: controller.signal,
|
|
185
|
+
headers: {
|
|
186
|
+
"Content-Type": "application/json",
|
|
187
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
188
|
+
...options.headers
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
clearTimeout(timeout);
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
if (response.status >= 500 && attempt < maxRetries) {
|
|
194
|
+
const delay = Math.min(1e3 * 2 ** attempt, 1e4);
|
|
195
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
199
|
+
let errorCode;
|
|
200
|
+
let helpUrl;
|
|
201
|
+
try {
|
|
202
|
+
const errorBody = await response.json();
|
|
203
|
+
if (errorBody.error) {
|
|
204
|
+
errorMessage = errorBody.error;
|
|
205
|
+
errorCode = errorBody.code;
|
|
206
|
+
helpUrl = errorBody.helpUrl;
|
|
207
|
+
}
|
|
208
|
+
} catch {
|
|
209
|
+
}
|
|
210
|
+
throw new ContextError(errorMessage, errorCode, response.status, helpUrl);
|
|
211
|
+
}
|
|
212
|
+
return response.json();
|
|
213
|
+
} catch (error) {
|
|
214
|
+
clearTimeout(timeout);
|
|
215
|
+
if (error instanceof ContextError) {
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
219
|
+
const isRetryable = lastError.name === "AbortError" || lastError.message.includes("fetch failed") || lastError.message.includes("ECONNRESET") || lastError.message.includes("ETIMEDOUT");
|
|
220
|
+
if (isRetryable && attempt < maxRetries) {
|
|
221
|
+
const delay = Math.min(1e3 * 2 ** attempt, 1e4);
|
|
222
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (lastError.name === "AbortError") {
|
|
226
|
+
throw new ContextError(
|
|
227
|
+
`Request timed out after ${timeoutMs / 1e3}s`,
|
|
228
|
+
void 0,
|
|
229
|
+
408
|
|
230
|
+
);
|
|
180
231
|
}
|
|
181
|
-
|
|
232
|
+
throw new ContextError(
|
|
233
|
+
lastError.message,
|
|
234
|
+
void 0,
|
|
235
|
+
void 0
|
|
236
|
+
);
|
|
182
237
|
}
|
|
183
|
-
throw new ContextError(errorMessage, errorCode, response.status, helpUrl);
|
|
184
238
|
}
|
|
185
|
-
|
|
239
|
+
throw lastError ?? new ContextError("Request failed after retries");
|
|
186
240
|
}
|
|
187
241
|
};
|
|
188
242
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client/types.ts","../../src/client/resources/discovery.ts","../../src/client/resources/tools.ts","../../src/client/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Configuration options for initializing the ContextClient\n */\nexport interface ContextClientOptions {\n /**\n * Your Context Protocol API key\n * @example \"sk_live_abc123...\"\n */\n apiKey: string;\n\n /**\n * Base URL for the Context Protocol API\n * @default \"https://ctxprotocol.com\"\n */\n baseUrl?: string;\n}\n\n/**\n * An individual MCP tool exposed by a tool listing\n */\nexport interface McpTool {\n /** Name of the MCP tool method */\n name: string;\n\n /** Description of what this method does */\n description: string;\n\n /**\n * JSON Schema for the input arguments this tool accepts.\n * Used by LLMs to generate correct arguments.\n */\n inputSchema?: Record<string, unknown>;\n\n /**\n * JSON Schema for the output this tool returns.\n * Used by LLMs to understand the response structure.\n */\n outputSchema?: Record<string, unknown>;\n}\n\n/**\n * Represents a tool available on the Context Protocol marketplace\n */\nexport interface Tool {\n /** Unique identifier for the tool (UUID) */\n id: string;\n\n /** Human-readable name of the tool */\n name: string;\n\n /** Description of what the tool does */\n description: string;\n\n /** Price per execution in USDC */\n price: string;\n\n /** Tool category (e.g., \"defi\", \"nft\") */\n category?: string;\n\n /** Whether the tool is verified by Context Protocol */\n isVerified?: boolean;\n\n /**\n * Available MCP tool methods\n * Use items from this array as `toolName` when executing\n */\n mcpTools?: McpTool[];\n\n /** Creation timestamp */\n createdAt?: string;\n\n /** Last update timestamp */\n updatedAt?: string;\n}\n\n/**\n * Response from the tools search endpoint\n */\nexport interface SearchResponse {\n /** Array of matching tools */\n tools: Tool[];\n\n /** The search query that was used */\n query: string;\n\n /** Total number of results */\n count: number;\n}\n\n/**\n * Options for searching tools\n */\nexport interface SearchOptions {\n /** Search query (semantic search) */\n query?: string;\n\n /** Maximum number of results (1-50, default 10) */\n limit?: number;\n}\n\n/**\n * Options for executing a tool\n */\nexport interface ExecuteOptions {\n /** The UUID of the tool to execute (from search results) */\n toolId: string;\n\n /** The specific MCP tool name to call (from tool's mcpTools array) */\n toolName: string;\n\n /** Arguments to pass to the tool */\n args?: Record<string, unknown>;\n}\n\n/**\n * Successful execution response from the API\n */\nexport interface ExecuteApiSuccessResponse {\n success: true;\n\n /** The result data from the tool execution */\n result: unknown;\n\n /** Information about the executed tool */\n tool: {\n id: string;\n name: string;\n };\n\n /** Execution duration in milliseconds */\n durationMs: number;\n}\n\n/**\n * Error response from the API\n */\nexport interface ExecuteApiErrorResponse {\n /** Human-readable error message */\n error: string;\n\n /** Error code for programmatic handling */\n code?: ContextErrorCode;\n\n /** URL to help resolve the issue */\n helpUrl?: string;\n}\n\n/**\n * Raw API response from the execute endpoint\n */\nexport type ExecuteApiResponse = ExecuteApiSuccessResponse | ExecuteApiErrorResponse;\n\n/**\n * The resolved result returned to the user after SDK processing\n */\nexport interface ExecutionResult<T = unknown> {\n /** The data returned by the tool */\n result: T;\n\n /** Information about the executed tool */\n tool: {\n id: string;\n name: string;\n };\n\n /** Execution duration in milliseconds */\n durationMs: number;\n}\n\n/**\n * Specific error codes returned by the Context Protocol API\n */\nexport type ContextErrorCode =\n | \"unauthorized\"\n | \"no_wallet\"\n | \"insufficient_allowance\"\n | \"payment_failed\"\n | \"execution_failed\";\n\n/**\n * Error thrown by the Context Protocol client\n */\nexport class ContextError extends Error {\n constructor(\n message: string,\n public readonly code?: ContextErrorCode | string,\n public readonly statusCode?: number,\n public readonly helpUrl?: string\n ) {\n super(message);\n this.name = \"ContextError\";\n }\n}\n","import type { Tool, SearchResponse } from \"../types.js\";\nimport type { ContextClient } from \"../client.js\";\n\n/**\n * Discovery resource for searching and finding tools on the Context Protocol marketplace\n */\nexport class Discovery {\n constructor(private client: ContextClient) {}\n\n /**\n * Search for tools matching a query string\n *\n * @param query - The search query (e.g., \"gas prices\", \"nft metadata\")\n * @param limit - Maximum number of results (1-50, default 10)\n * @returns Array of matching tools\n *\n * @example\n * ```typescript\n * const tools = await client.discovery.search(\"gas prices\");\n * console.log(tools[0].name); // \"Gas Price Oracle\"\n * console.log(tools[0].mcpTools); // Available methods\n * ```\n */\n async search(query: string, limit?: number): Promise<Tool[]> {\n const params = new URLSearchParams();\n\n if (query) {\n params.set(\"q\", query);\n }\n\n if (limit !== undefined) {\n params.set(\"limit\", String(limit));\n }\n\n const queryString = params.toString();\n const endpoint = `/api/v1/tools/search${queryString ? `?${queryString}` : \"\"}`;\n\n const response = await this.client.fetch<SearchResponse>(endpoint);\n\n return response.tools;\n }\n\n /**\n * Get featured/popular tools (empty query search)\n *\n * @param limit - Maximum number of results (1-50, default 10)\n * @returns Array of featured tools\n *\n * @example\n * ```typescript\n * const featured = await client.discovery.getFeatured(5);\n * ```\n */\n async getFeatured(limit?: number): Promise<Tool[]> {\n return this.search(\"\", limit);\n }\n}\n","import type {\n ExecuteOptions,\n ExecuteApiResponse,\n ExecutionResult,\n} from \"../types.js\";\nimport { ContextError } from \"../types.js\";\nimport type { ContextClient } from \"../client.js\";\n\n/**\n * Tools resource for executing tools on the Context Protocol marketplace\n */\nexport class Tools {\n constructor(private client: ContextClient) {}\n\n /**\n * Execute a tool with the provided arguments\n *\n * @param options - Execution options\n * @param options.toolId - The UUID of the tool (from search results)\n * @param options.toolName - The specific MCP tool method to call (from tool's mcpTools array)\n * @param options.args - Arguments to pass to the tool\n * @returns The execution result with the tool's output data\n *\n * @throws {ContextError} With code `no_wallet` if wallet not set up\n * @throws {ContextError} With code `insufficient_allowance` if Auto Pay not enabled\n * @throws {ContextError} With code `payment_failed` if on-chain payment fails\n * @throws {ContextError} With code `execution_failed` if tool execution fails\n *\n * @example\n * ```typescript\n * // First, search for a tool\n * const tools = await client.discovery.search(\"gas prices\");\n * const tool = tools[0];\n *\n * // Execute a specific method from the tool's mcpTools\n * const result = await client.tools.execute({\n * toolId: tool.id,\n * toolName: tool.mcpTools[0].name, // e.g., \"get_gas_prices\"\n * args: { chainId: 1 }\n * });\n *\n * console.log(result.result); // The tool's output\n * console.log(result.durationMs); // Execution time\n * ```\n */\n async execute<T = unknown>(options: ExecuteOptions): Promise<ExecutionResult<T>> {\n const { toolId, toolName, args } = options;\n\n const response = await this.client.fetch<ExecuteApiResponse>(\n \"/api/v1/tools/execute\",\n {\n method: \"POST\",\n body: JSON.stringify({ toolId, toolName, args }),\n }\n );\n\n // Handle error response\n if (\"error\" in response) {\n throw new ContextError(\n response.error,\n response.code,\n 400,\n response.helpUrl\n );\n }\n\n // Handle success response\n if (response.success) {\n return {\n result: response.result as T,\n tool: response.tool,\n durationMs: response.durationMs,\n };\n }\n\n // Fallback - shouldn't reach here with valid API responses\n throw new ContextError(\"Unexpected response format from API\");\n }\n}\n","import type { ContextClientOptions } from \"./types.js\";\nimport { ContextError } from \"./types.js\";\nimport { Discovery } from \"./resources/discovery.js\";\nimport { Tools } from \"./resources/tools.js\";\n\n/**\n * The official TypeScript client for the Context Protocol.\n *\n * Use this client to discover and execute AI tools programmatically.\n *\n * @example\n * ```typescript\n * import { ContextClient } from \"@contextprotocol/client\";\n *\n * const client = new ContextClient({\n * apiKey: \"sk_live_...\"\n * });\n *\n * // Discover tools\n * const tools = await client.discovery.search(\"gas prices\");\n *\n * // Execute a tool method\n * const result = await client.tools.execute({\n * toolId: tools[0].id,\n * toolName: tools[0].mcpTools[0].name,\n * args: { chainId: 1 }\n * });\n * ```\n */\nexport class ContextClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n /**\n * Discovery resource for searching tools\n */\n public readonly discovery: Discovery;\n\n /**\n * Tools resource for executing tools\n */\n public readonly tools: Tools;\n\n /**\n * Creates a new Context Protocol client\n *\n * @param options - Client configuration options\n * @param options.apiKey - Your Context Protocol API key (format: sk_live_...)\n * @param options.baseUrl - Optional base URL override (defaults to https://ctxprotocol.com)\n */\n constructor(options: ContextClientOptions) {\n if (!options.apiKey) {\n throw new ContextError(\"API key is required\");\n }\n\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl ?? \"https://ctxprotocol.com\").replace(/\\/$/, \"\");\n\n // Initialize resources\n this.discovery = new Discovery(this);\n this.tools = new Tools(this);\n }\n\n /**\n * Internal method for making authenticated HTTP requests\n * All requests include the Authorization header with the API key\n *\n * @internal\n */\n async fetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}: ${response.statusText}`;\n let errorCode: string | undefined;\n let helpUrl: string | undefined;\n\n try {\n const errorBody = await response.json();\n if (errorBody.error) {\n errorMessage = errorBody.error;\n errorCode = errorBody.code;\n helpUrl = errorBody.helpUrl;\n }\n } catch {\n // Use default error message if JSON parsing fails\n }\n\n throw new ContextError(errorMessage, errorCode, response.status, helpUrl);\n }\n\n return response.json() as Promise<T>;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/client/types.ts","../../src/client/resources/discovery.ts","../../src/client/resources/tools.ts","../../src/client/client.ts"],"names":[],"mappings":";;;AAmMO,IAAM,YAAA,GAAN,MAAM,aAAA,SAAqB,KAAA,CAAM;AAAA,EACtC,WAAA,CACE,OAAA,EACgB,IAAA,EACA,UAAA,EACA,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJG,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,aAAA,CAAa,SAAS,CAAA;AAAA,EACpD;AACF;;;ACxMO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAAoB,MAAA,EAAuB;AAAvB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB5C,MAAM,MAAA,CAAO,KAAA,EAAe,KAAA,EAAiC;AAC3D,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AAEnC,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAA,CAAO,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IACvB;AAEA,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IACnC;AAEA,IAAA,MAAM,WAAA,GAAc,OAAO,QAAA,EAAS;AACpC,IAAA,MAAM,WAAW,CAAA,oBAAA,EAAuB,WAAA,GAAc,CAAA,CAAA,EAAI,WAAW,KAAK,EAAE,CAAA,CAAA;AAE5E,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,OAAuB,QAAQ,CAAA;AAElE,IAAA,OAAO,QAAA,CAAS,KAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,YAAY,KAAA,EAAiC;AACjD,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,EAAA,EAAI,KAAK,CAAA;AAAA,EAC9B;AACF;;;AC7CO,IAAM,QAAN,MAAY;AAAA,EACjB,YAAoB,MAAA,EAAuB;AAAvB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiC5C,MAAM,QAAqB,OAAA,EAAsD;AAC/E,IAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAK,GAAI,OAAA;AAEnC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,MAAA;AAAA,MACjC,uBAAA;AAAA,MACA;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAM;AAAA;AACjD,KACF;AAGA,IAAA,IAAI,WAAW,QAAA,EAAU;AACvB,MAAA,MAAM,IAAI,YAAA;AAAA,QACR,QAAA,CAAS,KAAA;AAAA,QACT,QAAA,CAAS,IAAA;AAAA,QACT,MAAA;AAAA;AAAA,QACA,QAAA,CAAS;AAAA,OACX;AAAA,IACF;AAGA,IAAA,IAAI,SAAS,OAAA,EAAS;AACpB,MAAA,OAAO;AAAA,QACL,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,MAAM,QAAA,CAAS,IAAA;AAAA,QACf,YAAY,QAAA,CAAS;AAAA,OACvB;AAAA,IACF;AAGA,IAAA,MAAM,IAAI,aAAa,qCAAqC,CAAA;AAAA,EAC9D;AACF;;;ACjDO,IAAM,gBAAN,MAAoB;AAAA,EACR,MAAA;AAAA,EACA,OAAA;AAAA,EACT,OAAA,GAAU,KAAA;AAAA;AAAA;AAAA;AAAA,EAKF,SAAA;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShB,YAAY,OAAA,EAA+B;AACzC,IAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,MAAA,MAAM,IAAI,aAAa,qBAAqB,CAAA;AAAA,IAC9C;AAEA,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,OAAA,IAAW,yBAAA,EAA2B,OAAA,CAAQ,OAAO,EAAE,CAAA;AAG/E,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,SAAA,CAAU,IAAI,CAAA;AACnC,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,KAAA,CAAM,IAAI,CAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MAAA,CAAU,QAAA,EAAkB,OAAA,GAAuB,EAAC,EAAe;AACvE,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,MAAM,IAAI,aAAa,wBAAwB,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAO,GAAG,QAAQ,CAAA,CAAA;AACtC,IAAA,MAAM,UAAA,GAAa,CAAA;AACnB,IAAA,MAAM,SAAA,GAAY,GAAA;AAElB,IAAA,IAAI,SAAA;AAEJ,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,UAAA,EAAY,OAAA,EAAA,EAAW;AACtD,MAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,MAAA,MAAM,UAAU,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAE9D,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,UAChC,GAAG,OAAA;AAAA,UACH,QAAQ,UAAA,CAAW,MAAA;AAAA,UACnB,OAAA,EAAS;AAAA,YACP,cAAA,EAAgB,kBAAA;AAAA,YAChB,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,YACpC,GAAG,OAAA,CAAQ;AAAA;AACb,SACD,CAAA;AAED,QAAA,YAAA,CAAa,OAAO,CAAA;AAEpB,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAEhB,UAAA,IAAI,QAAA,CAAS,MAAA,IAAU,GAAA,IAAO,OAAA,GAAU,UAAA,EAAY;AAClD,YAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,GAAA,GAAO,CAAA,IAAK,SAAS,GAAM,CAAA;AAClD,YAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,KAAK,CAAC,CAAA;AACzD,YAAA;AAAA,UACF;AAEA,UAAA,IAAI,eAAe,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA,CAAA;AAClE,UAAA,IAAI,SAAA;AACJ,UAAA,IAAI,OAAA;AAEJ,UAAA,IAAI;AACF,YAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,EAAK;AACtC,YAAA,IAAI,UAAU,KAAA,EAAO;AACnB,cAAA,YAAA,GAAe,SAAA,CAAU,KAAA;AACzB,cAAA,SAAA,GAAY,SAAA,CAAU,IAAA;AACtB,cAAA,OAAA,GAAU,SAAA,CAAU,OAAA;AAAA,YACtB;AAAA,UACF,CAAA,CAAA,MAAQ;AAAA,UAER;AAEA,UAAA,MAAM,IAAI,YAAA,CAAa,YAAA,EAAc,SAAA,EAAW,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA,QAC1E;AAEA,QAAA,OAAO,SAAS,IAAA,EAAK;AAAA,MACvB,SAAS,KAAA,EAAO;AACd,QAAA,YAAA,CAAa,OAAO,CAAA;AAEpB,QAAA,IAAI,iBAAiB,YAAA,EAAc;AACjC,UAAA,MAAM,KAAA;AAAA,QACR;AAEA,QAAA,SAAA,GAAY,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAGpE,QAAA,MAAM,cACJ,SAAA,CAAU,IAAA,KAAS,YAAA,IACnB,SAAA,CAAU,QAAQ,QAAA,CAAS,cAAc,CAAA,IACzC,SAAA,CAAU,QAAQ,QAAA,CAAS,YAAY,KACvC,SAAA,CAAU,OAAA,CAAQ,SAAS,WAAW,CAAA;AAExC,QAAA,IAAI,WAAA,IAAe,UAAU,UAAA,EAAY;AACvC,UAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,GAAA,GAAO,CAAA,IAAK,SAAS,GAAM,CAAA;AAClD,UAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,KAAK,CAAC,CAAA;AACzD,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,SAAA,CAAU,SAAS,YAAA,EAAc;AACnC,UAAA,MAAM,IAAI,YAAA;AAAA,YACR,CAAA,wBAAA,EAA2B,YAAY,GAAI,CAAA,CAAA,CAAA;AAAA,YAC3C,MAAA;AAAA,YACA;AAAA,WACF;AAAA,QACF;AAEA,QAAA,MAAM,IAAI,YAAA;AAAA,UACR,SAAA,CAAU,OAAA;AAAA,UACV,MAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,IAAa,IAAI,YAAA,CAAa,8BAA8B,CAAA;AAAA,EACpE;AACF","file":"index.cjs","sourcesContent":["/**\n * Configuration options for initializing the ContextClient\n */\nexport interface ContextClientOptions {\n /**\n * Your Context Protocol API key\n * @example \"sk_live_abc123...\"\n */\n apiKey: string;\n\n /**\n * Base URL for the Context Protocol API\n * @default \"https://ctxprotocol.com\"\n */\n baseUrl?: string;\n}\n\n/**\n * An individual MCP tool exposed by a tool listing\n */\nexport interface McpTool {\n /** Name of the MCP tool method */\n name: string;\n\n /** Description of what this method does */\n description: string;\n\n /**\n * JSON Schema for the input arguments this tool accepts.\n * Used by LLMs to generate correct arguments.\n */\n inputSchema?: Record<string, unknown>;\n\n /**\n * JSON Schema for the output this tool returns.\n * Used by LLMs to understand the response structure.\n */\n outputSchema?: Record<string, unknown>;\n}\n\n/**\n * Represents a tool available on the Context Protocol marketplace\n */\nexport interface Tool {\n /** Unique identifier for the tool (UUID) */\n id: string;\n\n /** Human-readable name of the tool */\n name: string;\n\n /** Description of what the tool does */\n description: string;\n\n /** Price per execution in USDC */\n price: string;\n\n /** Tool category (e.g., \"defi\", \"nft\") */\n category?: string;\n\n /** Whether the tool is verified by Context Protocol */\n isVerified?: boolean;\n\n /** Tool type - currently always \"mcp\" */\n kind?: string;\n\n /**\n * Available MCP tool methods\n * Use items from this array as `toolName` when executing\n */\n mcpTools?: McpTool[];\n\n // Trust metrics (Level 2 - Reputation Ledger)\n /** Total number of queries processed */\n totalQueries?: number;\n\n /** Success rate percentage (0-100) */\n successRate?: string;\n\n /** Uptime percentage (0-100) */\n uptimePercent?: string;\n\n /** Total USDC staked by the developer */\n totalStaked?: string;\n\n /** Whether the tool has \"Proven\" status (100+ queries, >95% success, >98% uptime) */\n isProven?: boolean;\n}\n\n/**\n * Response from the tools search endpoint\n */\nexport interface SearchResponse {\n /** Array of matching tools */\n tools: Tool[];\n\n /** The search query that was used */\n query: string;\n\n /** Total number of results */\n count: number;\n}\n\n/**\n * Options for searching tools\n */\nexport interface SearchOptions {\n /** Search query (semantic search) */\n query?: string;\n\n /** Maximum number of results (1-50, default 10) */\n limit?: number;\n}\n\n/**\n * Options for executing a tool\n */\nexport interface ExecuteOptions {\n /** The UUID of the tool to execute (from search results) */\n toolId: string;\n\n /** The specific MCP tool name to call (from tool's mcpTools array) */\n toolName: string;\n\n /** Arguments to pass to the tool */\n args?: Record<string, unknown>;\n}\n\n/**\n * Successful execution response from the API\n */\nexport interface ExecuteApiSuccessResponse {\n success: true;\n\n /** The result data from the tool execution */\n result: unknown;\n\n /** Information about the executed tool */\n tool: {\n id: string;\n name: string;\n };\n\n /** Execution duration in milliseconds */\n durationMs: number;\n}\n\n/**\n * Error response from the API\n */\nexport interface ExecuteApiErrorResponse {\n /** Human-readable error message */\n error: string;\n\n /** Error code for programmatic handling */\n code?: ContextErrorCode;\n\n /** URL to help resolve the issue */\n helpUrl?: string;\n}\n\n/**\n * Raw API response from the execute endpoint\n */\nexport type ExecuteApiResponse = ExecuteApiSuccessResponse | ExecuteApiErrorResponse;\n\n/**\n * The resolved result returned to the user after SDK processing\n */\nexport interface ExecutionResult<T = unknown> {\n /** The data returned by the tool */\n result: T;\n\n /** Information about the executed tool */\n tool: {\n id: string;\n name: string;\n };\n\n /** Execution duration in milliseconds */\n durationMs: number;\n}\n\n/**\n * Specific error codes returned by the Context Protocol API\n */\nexport type ContextErrorCode =\n | \"unauthorized\"\n | \"no_wallet\"\n | \"insufficient_allowance\"\n | \"payment_failed\"\n | \"execution_failed\";\n\n/**\n * Error thrown by the Context Protocol client\n */\nexport class ContextError extends Error {\n constructor(\n message: string,\n public readonly code?: ContextErrorCode | string,\n public readonly statusCode?: number,\n public readonly helpUrl?: string\n ) {\n super(message);\n this.name = \"ContextError\";\n Object.setPrototypeOf(this, ContextError.prototype);\n }\n}\n","import type { Tool, SearchResponse } from \"../types.js\";\nimport type { ContextClient } from \"../client.js\";\n\n/**\n * Discovery resource for searching and finding tools on the Context Protocol marketplace\n */\nexport class Discovery {\n constructor(private client: ContextClient) {}\n\n /**\n * Search for tools matching a query string\n *\n * @param query - The search query (e.g., \"gas prices\", \"nft metadata\")\n * @param limit - Maximum number of results (1-50, default 10)\n * @returns Array of matching tools\n *\n * @example\n * ```typescript\n * const tools = await client.discovery.search(\"gas prices\");\n * console.log(tools[0].name); // \"Gas Price Oracle\"\n * console.log(tools[0].mcpTools); // Available methods\n * ```\n */\n async search(query: string, limit?: number): Promise<Tool[]> {\n const params = new URLSearchParams();\n\n if (query) {\n params.set(\"q\", query);\n }\n\n if (limit !== undefined) {\n params.set(\"limit\", String(limit));\n }\n\n const queryString = params.toString();\n const endpoint = `/api/v1/tools/search${queryString ? `?${queryString}` : \"\"}`;\n\n const response = await this.client._fetch<SearchResponse>(endpoint);\n\n return response.tools;\n }\n\n /**\n * Get featured/popular tools (empty query search)\n *\n * @param limit - Maximum number of results (1-50, default 10)\n * @returns Array of featured tools\n *\n * @example\n * ```typescript\n * const featured = await client.discovery.getFeatured(5);\n * ```\n */\n async getFeatured(limit?: number): Promise<Tool[]> {\n return this.search(\"\", limit);\n }\n}\n","import type {\n ExecuteOptions,\n ExecuteApiResponse,\n ExecutionResult,\n} from \"../types.js\";\nimport { ContextError } from \"../types.js\";\nimport type { ContextClient } from \"../client.js\";\n\n/**\n * Tools resource for executing tools on the Context Protocol marketplace\n */\nexport class Tools {\n constructor(private client: ContextClient) {}\n\n /**\n * Execute a tool with the provided arguments\n *\n * @param options - Execution options\n * @param options.toolId - The UUID of the tool (from search results)\n * @param options.toolName - The specific MCP tool method to call (from tool's mcpTools array)\n * @param options.args - Arguments to pass to the tool\n * @returns The execution result with the tool's output data\n *\n * @throws {ContextError} With code `no_wallet` if wallet not set up\n * @throws {ContextError} With code `insufficient_allowance` if Auto Pay not enabled\n * @throws {ContextError} With code `payment_failed` if on-chain payment fails\n * @throws {ContextError} With code `execution_failed` if tool execution fails\n *\n * @example\n * ```typescript\n * // First, search for a tool\n * const tools = await client.discovery.search(\"gas prices\");\n * const tool = tools[0];\n *\n * // Execute a specific method from the tool's mcpTools\n * const result = await client.tools.execute({\n * toolId: tool.id,\n * toolName: tool.mcpTools[0].name, // e.g., \"get_gas_prices\"\n * args: { chainId: 1 }\n * });\n *\n * console.log(result.result); // The tool's output\n * console.log(result.durationMs); // Execution time\n * ```\n */\n async execute<T = unknown>(options: ExecuteOptions): Promise<ExecutionResult<T>> {\n const { toolId, toolName, args } = options;\n\n const response = await this.client._fetch<ExecuteApiResponse>(\n \"/api/v1/tools/execute\",\n {\n method: \"POST\",\n body: JSON.stringify({ toolId, toolName, args }),\n }\n );\n\n // Handle error response\n if (\"error\" in response) {\n throw new ContextError(\n response.error,\n response.code,\n undefined, // Don't hardcode - this was a 200 OK with error body\n response.helpUrl\n );\n }\n\n // Handle success response\n if (response.success) {\n return {\n result: response.result as T,\n tool: response.tool,\n durationMs: response.durationMs,\n };\n }\n\n // Fallback - shouldn't reach here with valid API responses\n throw new ContextError(\"Unexpected response format from API\");\n }\n}\n","import type { ContextClientOptions } from \"./types.js\";\nimport { ContextError } from \"./types.js\";\nimport { Discovery } from \"./resources/discovery.js\";\nimport { Tools } from \"./resources/tools.js\";\n\n/**\n * The official TypeScript client for the Context Protocol.\n *\n * Use this client to discover and execute AI tools programmatically.\n *\n * @example\n * ```typescript\n * import { ContextClient } from \"@contextprotocol/client\";\n *\n * const client = new ContextClient({\n * apiKey: \"sk_live_...\"\n * });\n *\n * // Discover tools\n * const tools = await client.discovery.search(\"gas prices\");\n *\n * // Execute a tool method\n * const result = await client.tools.execute({\n * toolId: tools[0].id,\n * toolName: tools[0].mcpTools[0].name,\n * args: { chainId: 1 }\n * });\n * ```\n */\nexport class ContextClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private _closed = false;\n\n /**\n * Discovery resource for searching tools\n */\n public readonly discovery: Discovery;\n\n /**\n * Tools resource for executing tools\n */\n public readonly tools: Tools;\n\n /**\n * Creates a new Context Protocol client\n *\n * @param options - Client configuration options\n * @param options.apiKey - Your Context Protocol API key (format: sk_live_...)\n * @param options.baseUrl - Optional base URL override (defaults to https://ctxprotocol.com)\n */\n constructor(options: ContextClientOptions) {\n if (!options.apiKey) {\n throw new ContextError(\"API key is required\");\n }\n\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl ?? \"https://ctxprotocol.com\").replace(/\\/$/, \"\");\n\n // Initialize resources\n this.discovery = new Discovery(this);\n this.tools = new Tools(this);\n }\n\n /**\n * Close the client and clean up resources.\n * After calling close(), any in-flight requests may be aborted.\n */\n close(): void {\n this._closed = true;\n }\n\n /**\n * Internal method for making authenticated HTTP requests\n * Includes timeout (30s) and retry with exponential backoff for transient errors\n *\n * @internal\n */\n async _fetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n if (this._closed) {\n throw new ContextError(\"Client has been closed\");\n }\n\n const url = `${this.baseUrl}${endpoint}`;\n const maxRetries = 3;\n const timeoutMs = 30_000;\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n // Retry on 5xx server errors\n if (response.status >= 500 && attempt < maxRetries) {\n const delay = Math.min(1000 * 2 ** attempt, 10_000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n\n let errorMessage = `HTTP ${response.status}: ${response.statusText}`;\n let errorCode: string | undefined;\n let helpUrl: string | undefined;\n\n try {\n const errorBody = await response.json();\n if (errorBody.error) {\n errorMessage = errorBody.error;\n errorCode = errorBody.code;\n helpUrl = errorBody.helpUrl;\n }\n } catch {\n // Use default error message if JSON parsing fails\n }\n\n throw new ContextError(errorMessage, errorCode, response.status, helpUrl);\n }\n\n return response.json() as Promise<T>;\n } catch (error) {\n clearTimeout(timeout);\n\n if (error instanceof ContextError) {\n throw error;\n }\n\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Retry on network errors and timeouts\n const isRetryable =\n lastError.name === \"AbortError\" ||\n lastError.message.includes(\"fetch failed\") ||\n lastError.message.includes(\"ECONNRESET\") ||\n lastError.message.includes(\"ETIMEDOUT\");\n\n if (isRetryable && attempt < maxRetries) {\n const delay = Math.min(1000 * 2 ** attempt, 10_000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n\n if (lastError.name === \"AbortError\") {\n throw new ContextError(\n `Request timed out after ${timeoutMs / 1000}s`,\n undefined,\n 408\n );\n }\n\n throw new ContextError(\n lastError.message,\n undefined,\n undefined\n );\n }\n }\n\n throw lastError ?? new ContextError(\"Request failed after retries\");\n }\n}\n"]}
|
package/dist/client/index.d.cts
CHANGED
|
@@ -48,15 +48,23 @@ interface Tool {
|
|
|
48
48
|
category?: string;
|
|
49
49
|
/** Whether the tool is verified by Context Protocol */
|
|
50
50
|
isVerified?: boolean;
|
|
51
|
+
/** Tool type - currently always "mcp" */
|
|
52
|
+
kind?: string;
|
|
51
53
|
/**
|
|
52
54
|
* Available MCP tool methods
|
|
53
55
|
* Use items from this array as `toolName` when executing
|
|
54
56
|
*/
|
|
55
57
|
mcpTools?: McpTool[];
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
|
|
58
|
+
/** Total number of queries processed */
|
|
59
|
+
totalQueries?: number;
|
|
60
|
+
/** Success rate percentage (0-100) */
|
|
61
|
+
successRate?: string;
|
|
62
|
+
/** Uptime percentage (0-100) */
|
|
63
|
+
uptimePercent?: string;
|
|
64
|
+
/** Total USDC staked by the developer */
|
|
65
|
+
totalStaked?: string;
|
|
66
|
+
/** Whether the tool has "Proven" status (100+ queries, >95% success, >98% uptime) */
|
|
67
|
+
isProven?: boolean;
|
|
60
68
|
}
|
|
61
69
|
/**
|
|
62
70
|
* Response from the tools search endpoint
|
|
@@ -249,6 +257,7 @@ declare class Tools {
|
|
|
249
257
|
declare class ContextClient {
|
|
250
258
|
private readonly apiKey;
|
|
251
259
|
private readonly baseUrl;
|
|
260
|
+
private _closed;
|
|
252
261
|
/**
|
|
253
262
|
* Discovery resource for searching tools
|
|
254
263
|
*/
|
|
@@ -265,13 +274,18 @@ declare class ContextClient {
|
|
|
265
274
|
* @param options.baseUrl - Optional base URL override (defaults to https://ctxprotocol.com)
|
|
266
275
|
*/
|
|
267
276
|
constructor(options: ContextClientOptions);
|
|
277
|
+
/**
|
|
278
|
+
* Close the client and clean up resources.
|
|
279
|
+
* After calling close(), any in-flight requests may be aborted.
|
|
280
|
+
*/
|
|
281
|
+
close(): void;
|
|
268
282
|
/**
|
|
269
283
|
* Internal method for making authenticated HTTP requests
|
|
270
|
-
*
|
|
284
|
+
* Includes timeout (30s) and retry with exponential backoff for transient errors
|
|
271
285
|
*
|
|
272
286
|
* @internal
|
|
273
287
|
*/
|
|
274
|
-
|
|
288
|
+
_fetch<T>(endpoint: string, options?: RequestInit): Promise<T>;
|
|
275
289
|
}
|
|
276
290
|
|
|
277
291
|
export { ContextClient, type ContextClientOptions, ContextError, type ContextErrorCode, Discovery, type ExecuteApiErrorResponse, type ExecuteApiResponse, type ExecuteApiSuccessResponse, type ExecuteOptions, type ExecutionResult, type McpTool, type SearchOptions, type SearchResponse, type Tool, Tools };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -48,15 +48,23 @@ interface Tool {
|
|
|
48
48
|
category?: string;
|
|
49
49
|
/** Whether the tool is verified by Context Protocol */
|
|
50
50
|
isVerified?: boolean;
|
|
51
|
+
/** Tool type - currently always "mcp" */
|
|
52
|
+
kind?: string;
|
|
51
53
|
/**
|
|
52
54
|
* Available MCP tool methods
|
|
53
55
|
* Use items from this array as `toolName` when executing
|
|
54
56
|
*/
|
|
55
57
|
mcpTools?: McpTool[];
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
|
|
58
|
+
/** Total number of queries processed */
|
|
59
|
+
totalQueries?: number;
|
|
60
|
+
/** Success rate percentage (0-100) */
|
|
61
|
+
successRate?: string;
|
|
62
|
+
/** Uptime percentage (0-100) */
|
|
63
|
+
uptimePercent?: string;
|
|
64
|
+
/** Total USDC staked by the developer */
|
|
65
|
+
totalStaked?: string;
|
|
66
|
+
/** Whether the tool has "Proven" status (100+ queries, >95% success, >98% uptime) */
|
|
67
|
+
isProven?: boolean;
|
|
60
68
|
}
|
|
61
69
|
/**
|
|
62
70
|
* Response from the tools search endpoint
|
|
@@ -249,6 +257,7 @@ declare class Tools {
|
|
|
249
257
|
declare class ContextClient {
|
|
250
258
|
private readonly apiKey;
|
|
251
259
|
private readonly baseUrl;
|
|
260
|
+
private _closed;
|
|
252
261
|
/**
|
|
253
262
|
* Discovery resource for searching tools
|
|
254
263
|
*/
|
|
@@ -265,13 +274,18 @@ declare class ContextClient {
|
|
|
265
274
|
* @param options.baseUrl - Optional base URL override (defaults to https://ctxprotocol.com)
|
|
266
275
|
*/
|
|
267
276
|
constructor(options: ContextClientOptions);
|
|
277
|
+
/**
|
|
278
|
+
* Close the client and clean up resources.
|
|
279
|
+
* After calling close(), any in-flight requests may be aborted.
|
|
280
|
+
*/
|
|
281
|
+
close(): void;
|
|
268
282
|
/**
|
|
269
283
|
* Internal method for making authenticated HTTP requests
|
|
270
|
-
*
|
|
284
|
+
* Includes timeout (30s) and retry with exponential backoff for transient errors
|
|
271
285
|
*
|
|
272
286
|
* @internal
|
|
273
287
|
*/
|
|
274
|
-
|
|
288
|
+
_fetch<T>(endpoint: string, options?: RequestInit): Promise<T>;
|
|
275
289
|
}
|
|
276
290
|
|
|
277
291
|
export { ContextClient, type ContextClientOptions, ContextError, type ContextErrorCode, Discovery, type ExecuteApiErrorResponse, type ExecuteApiResponse, type ExecuteApiSuccessResponse, type ExecuteOptions, type ExecutionResult, type McpTool, type SearchOptions, type SearchResponse, type Tool, Tools };
|