@ctxprotocol/sdk 0.1.3 → 0.4.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/dist/index.d.ts CHANGED
@@ -1,277 +1,262 @@
1
+ export { ContextClient, ContextClientOptions, ContextError, ContextErrorCode, Discovery, ExecuteApiErrorResponse, ExecuteApiResponse, ExecuteApiSuccessResponse, ExecuteOptions, ExecutionResult, McpTool, SearchOptions, SearchResponse, Tool, Tools } from './client/index.js';
2
+
1
3
  /**
2
- * Configuration options for initializing the ContextClient
4
+ * Wallet context types for portfolio tracking.
5
+ *
6
+ * These types represent wallet and token holdings that can be
7
+ * injected into MCP tools for personalized analysis.
8
+ *
9
+ * @packageDocumentation
3
10
  */
4
- interface ContextClientOptions {
5
- /**
6
- * Your Context Protocol API key
7
- * @example "sk_live_abc123..."
8
- */
9
- apiKey: string;
10
- /**
11
- * Base URL for the Context Protocol API
12
- * @default "https://ctxprotocol.com"
13
- */
14
- baseUrl?: string;
15
- }
16
11
  /**
17
- * An individual MCP tool exposed by a tool listing
12
+ * Base wallet context - address and chain info
18
13
  */
19
- interface McpTool {
20
- /** Name of the MCP tool method */
21
- name: string;
22
- /** Description of what this method does */
23
- description: string;
24
- /**
25
- * JSON Schema for the input arguments this tool accepts.
26
- * Used by LLMs to generate correct arguments.
27
- */
28
- inputSchema?: Record<string, unknown>;
29
- /**
30
- * JSON Schema for the output this tool returns.
31
- * Used by LLMs to understand the response structure.
32
- */
33
- outputSchema?: Record<string, unknown>;
14
+ interface WalletContext {
15
+ /** Wallet address (checksummed) */
16
+ address: string;
17
+ /** Chain ID (137 for Polygon, 1 for Ethereum, etc.) */
18
+ chainId: number;
19
+ /** Native token balance in wei (string for precision) */
20
+ nativeBalance?: string;
34
21
  }
35
22
  /**
36
- * Represents a tool available on the Context Protocol marketplace
23
+ * ERC20 token holdings
37
24
  */
38
- interface Tool {
39
- /** Unique identifier for the tool (UUID) */
40
- id: string;
41
- /** Human-readable name of the tool */
42
- name: string;
43
- /** Description of what the tool does */
44
- description: string;
45
- /** Price per execution in USDC */
46
- price: string;
47
- /** Tool category (e.g., "defi", "nft") */
48
- category?: string;
49
- /** Whether the tool is verified by Context Protocol */
50
- isVerified?: boolean;
51
- /**
52
- * Available MCP tool methods
53
- * Use items from this array as `toolName` when executing
54
- */
55
- mcpTools?: McpTool[];
56
- /** Creation timestamp */
57
- createdAt?: string;
58
- /** Last update timestamp */
59
- updatedAt?: string;
25
+ interface ERC20TokenBalance {
26
+ /** Token contract address */
27
+ address: string;
28
+ /** Token symbol (e.g., "USDC") */
29
+ symbol: string;
30
+ /** Token decimals */
31
+ decimals: number;
32
+ /** Balance in smallest unit (string for precision) */
33
+ balance: string;
60
34
  }
61
35
  /**
62
- * Response from the tools search endpoint
36
+ * Collection of ERC20 token balances
63
37
  */
64
- interface SearchResponse {
65
- /** Array of matching tools */
66
- tools: Tool[];
67
- /** The search query that was used */
68
- query: string;
69
- /** Total number of results */
70
- count: number;
38
+ interface ERC20Context {
39
+ /** Array of token balances */
40
+ tokens: ERC20TokenBalance[];
71
41
  }
42
+
72
43
  /**
73
- * Options for searching tools
44
+ * Polymarket context types for portfolio tracking.
45
+ *
46
+ * These types represent Polymarket positions and orders that can be
47
+ * injected into MCP tools for personalized portfolio analysis.
48
+ *
49
+ * @packageDocumentation
74
50
  */
75
- interface SearchOptions {
76
- /** Search query (semantic search) */
77
- query?: string;
78
- /** Maximum number of results (1-50, default 10) */
79
- limit?: number;
80
- }
81
51
  /**
82
- * Options for executing a tool
52
+ * A single Polymarket position
83
53
  */
84
- interface ExecuteOptions {
85
- /** The UUID of the tool to execute (from search results) */
86
- toolId: string;
87
- /** The specific MCP tool name to call (from tool's mcpTools array) */
88
- toolName: string;
89
- /** Arguments to pass to the tool */
90
- args?: Record<string, unknown>;
54
+ interface PolymarketPosition {
55
+ /** The market's condition ID */
56
+ conditionId: string;
57
+ /** The specific outcome token ID */
58
+ tokenId: string;
59
+ /** Which outcome this position is for */
60
+ outcome: "YES" | "NO";
61
+ /** Number of shares held */
62
+ shares: number;
63
+ /** Average entry price (0-1 scale) */
64
+ avgEntryPrice: number;
65
+ /** Market question/title for display */
66
+ marketTitle?: string;
91
67
  }
92
68
  /**
93
- * Successful execution response from the API
69
+ * An open order on Polymarket
94
70
  */
95
- interface ExecuteApiSuccessResponse {
96
- success: true;
97
- /** The result data from the tool execution */
98
- result: unknown;
99
- /** Information about the executed tool */
100
- tool: {
101
- id: string;
102
- name: string;
103
- };
104
- /** Execution duration in milliseconds */
105
- durationMs: number;
71
+ interface PolymarketOrder {
72
+ /** Order ID */
73
+ orderId: string;
74
+ /** The market's condition ID */
75
+ conditionId: string;
76
+ /** Order side */
77
+ side: "BUY" | "SELL";
78
+ /** Which outcome this order is for */
79
+ outcome: "YES" | "NO";
80
+ /** Limit price (0-1 scale) */
81
+ price: number;
82
+ /** Order size in shares */
83
+ size: number;
84
+ /** Amount already filled */
85
+ filled: number;
106
86
  }
107
87
  /**
108
- * Error response from the API
88
+ * Complete Polymarket portfolio context.
89
+ * This is what gets passed to MCP tools for personalized analysis.
109
90
  */
110
- interface ExecuteApiErrorResponse {
111
- /** Human-readable error message */
112
- error: string;
113
- /** Error code for programmatic handling */
114
- code?: ContextErrorCode;
115
- /** URL to help resolve the issue */
116
- helpUrl?: string;
91
+ interface PolymarketContext {
92
+ /** The wallet address this context is for */
93
+ walletAddress: string;
94
+ /** All open positions */
95
+ positions: PolymarketPosition[];
96
+ /** All open orders */
97
+ openOrders: PolymarketOrder[];
98
+ /** Total portfolio value in USD (sum of position values) */
99
+ totalValue?: number;
100
+ /** When this context was fetched (ISO 8601 string) */
101
+ fetchedAt: string;
117
102
  }
103
+
118
104
  /**
119
- * Raw API response from the execute endpoint
105
+ * Hyperliquid context types for portfolio tracking.
106
+ *
107
+ * These types represent Hyperliquid perpetual positions, orders, and account
108
+ * data that can be injected into MCP tools for personalized portfolio analysis.
109
+ *
110
+ * @packageDocumentation
120
111
  */
121
- type ExecuteApiResponse = ExecuteApiSuccessResponse | ExecuteApiErrorResponse;
122
112
  /**
123
- * The resolved result returned to the user after SDK processing
113
+ * Hyperliquid Perpetual Position
124
114
  */
125
- interface ExecutionResult<T = unknown> {
126
- /** The data returned by the tool */
127
- result: T;
128
- /** Information about the executed tool */
129
- tool: {
130
- id: string;
131
- name: string;
115
+ interface HyperliquidPerpPosition {
116
+ /** Asset symbol (e.g., "ETH", "BTC") */
117
+ coin: string;
118
+ /** Position size (positive = long, negative = short) */
119
+ size: number;
120
+ /** Entry price */
121
+ entryPrice: number;
122
+ /** Current mark price */
123
+ markPrice?: number;
124
+ /** Unrealized PnL in USD */
125
+ unrealizedPnl: number;
126
+ /** Liquidation price */
127
+ liquidationPrice: number;
128
+ /** Position value in USD */
129
+ positionValue: number;
130
+ /** Leverage info */
131
+ leverage: {
132
+ type: "cross" | "isolated";
133
+ value: number;
134
+ };
135
+ /** Margin used for this position */
136
+ marginUsed: number;
137
+ /** Return on equity percentage */
138
+ returnOnEquity: number;
139
+ /** Cumulative funding paid/received */
140
+ cumFunding: {
141
+ allTime: number;
142
+ sinceOpen: number;
132
143
  };
133
- /** Execution duration in milliseconds */
134
- durationMs: number;
135
144
  }
136
145
  /**
137
- * Specific error codes returned by the Context Protocol API
146
+ * Hyperliquid Open Order
138
147
  */
139
- type ContextErrorCode = "unauthorized" | "no_wallet" | "insufficient_allowance" | "payment_failed" | "execution_failed";
148
+ interface HyperliquidOrder {
149
+ /** Order ID */
150
+ oid: number;
151
+ /** Asset symbol */
152
+ coin: string;
153
+ /** Order side: "B" = Buy, "A" = Ask/Sell */
154
+ side: "B" | "A";
155
+ /** Limit price */
156
+ limitPrice: number;
157
+ /** Order size */
158
+ size: number;
159
+ /** Original order size */
160
+ originalSize: number;
161
+ /** Order type */
162
+ orderType: "Limit" | "Market" | "Stop" | "TakeProfit";
163
+ /** Is reduce-only order */
164
+ reduceOnly: boolean;
165
+ /** Is trigger order */
166
+ isTrigger: boolean;
167
+ /** Trigger price (if trigger order) */
168
+ triggerPrice?: number;
169
+ /** Order timestamp */
170
+ timestamp: number;
171
+ }
140
172
  /**
141
- * Error thrown by the Context Protocol client
173
+ * Hyperliquid Spot Balance
142
174
  */
143
- declare class ContextError extends Error {
144
- readonly code?: (ContextErrorCode | string) | undefined;
145
- readonly statusCode?: number | undefined;
146
- readonly helpUrl?: string | undefined;
147
- constructor(message: string, code?: (ContextErrorCode | string) | undefined, statusCode?: number | undefined, helpUrl?: string | undefined);
175
+ interface HyperliquidSpotBalance {
176
+ /** Token symbol */
177
+ token: string;
178
+ /** Token balance */
179
+ balance: number;
180
+ /** USD value */
181
+ usdValue?: number;
148
182
  }
149
-
150
183
  /**
151
- * Discovery resource for searching and finding tools on the Context Protocol marketplace
184
+ * Hyperliquid Account Summary
152
185
  */
153
- declare class Discovery {
154
- private client;
155
- constructor(client: ContextClient);
156
- /**
157
- * Search for tools matching a query string
158
- *
159
- * @param query - The search query (e.g., "gas prices", "nft metadata")
160
- * @param limit - Maximum number of results (1-50, default 10)
161
- * @returns Array of matching tools
162
- *
163
- * @example
164
- * ```typescript
165
- * const tools = await client.discovery.search("gas prices");
166
- * console.log(tools[0].name); // "Gas Price Oracle"
167
- * console.log(tools[0].mcpTools); // Available methods
168
- * ```
169
- */
170
- search(query: string, limit?: number): Promise<Tool[]>;
171
- /**
172
- * Get featured/popular tools (empty query search)
173
- *
174
- * @param limit - Maximum number of results (1-50, default 10)
175
- * @returns Array of featured tools
176
- *
177
- * @example
178
- * ```typescript
179
- * const featured = await client.discovery.getFeatured(5);
180
- * ```
181
- */
182
- getFeatured(limit?: number): Promise<Tool[]>;
186
+ interface HyperliquidAccountSummary {
187
+ /** Total account value in USD */
188
+ accountValue: number;
189
+ /** Total margin used */
190
+ totalMarginUsed: number;
191
+ /** Total notional position value */
192
+ totalNotionalPosition: number;
193
+ /** Withdrawable amount */
194
+ withdrawable: number;
195
+ /** Cross margin summary */
196
+ crossMargin: {
197
+ accountValue: number;
198
+ totalMarginUsed: number;
199
+ };
183
200
  }
184
-
185
201
  /**
186
- * Tools resource for executing tools on the Context Protocol marketplace
202
+ * Complete Hyperliquid portfolio context.
203
+ * This is what gets passed to MCP tools for personalized analysis.
187
204
  */
188
- declare class Tools {
189
- private client;
190
- constructor(client: ContextClient);
191
- /**
192
- * Execute a tool with the provided arguments
193
- *
194
- * @param options - Execution options
195
- * @param options.toolId - The UUID of the tool (from search results)
196
- * @param options.toolName - The specific MCP tool method to call (from tool's mcpTools array)
197
- * @param options.args - Arguments to pass to the tool
198
- * @returns The execution result with the tool's output data
199
- *
200
- * @throws {ContextError} With code `no_wallet` if wallet not set up
201
- * @throws {ContextError} With code `insufficient_allowance` if Auto Pay not enabled
202
- * @throws {ContextError} With code `payment_failed` if on-chain payment fails
203
- * @throws {ContextError} With code `execution_failed` if tool execution fails
204
- *
205
- * @example
206
- * ```typescript
207
- * // First, search for a tool
208
- * const tools = await client.discovery.search("gas prices");
209
- * const tool = tools[0];
210
- *
211
- * // Execute a specific method from the tool's mcpTools
212
- * const result = await client.tools.execute({
213
- * toolId: tool.id,
214
- * toolName: tool.mcpTools[0].name, // e.g., "get_gas_prices"
215
- * args: { chainId: 1 }
216
- * });
217
- *
218
- * console.log(result.result); // The tool's output
219
- * console.log(result.durationMs); // Execution time
220
- * ```
221
- */
222
- execute<T = unknown>(options: ExecuteOptions): Promise<ExecutionResult<T>>;
205
+ interface HyperliquidContext {
206
+ /** The wallet address this context is for */
207
+ walletAddress: string;
208
+ /** Perpetual positions */
209
+ perpPositions: HyperliquidPerpPosition[];
210
+ /** Open orders */
211
+ openOrders: HyperliquidOrder[];
212
+ /** Spot balances */
213
+ spotBalances: HyperliquidSpotBalance[];
214
+ /** Account summary */
215
+ accountSummary: HyperliquidAccountSummary;
216
+ /** When this context was fetched (ISO 8601 string) */
217
+ fetchedAt: string;
223
218
  }
224
219
 
225
220
  /**
226
- * The official TypeScript client for the Context Protocol.
221
+ * Context types for portfolio and protocol data injection.
227
222
  *
228
- * Use this client to discover and execute AI tools programmatically.
223
+ * These types allow MCP tools to receive personalized user context
224
+ * (wallet addresses, positions, balances) for analysis.
229
225
  *
230
226
  * @example
231
227
  * ```typescript
232
- * import { ContextClient } from "@contextprotocol/client";
228
+ * import type { PolymarketContext, UserContext } from "@ctxprotocol/sdk";
233
229
  *
234
- * const client = new ContextClient({
235
- * apiKey: "sk_live_..."
236
- * });
230
+ * // Build context for a user's portfolio
231
+ * const context: UserContext = {
232
+ * wallet: { address: "0x...", chainId: 137 },
233
+ * polymarket: {
234
+ * walletAddress: "0x...",
235
+ * positions: [...],
236
+ * openOrders: [],
237
+ * fetchedAt: new Date().toISOString(),
238
+ * },
239
+ * };
240
+ * ```
237
241
  *
238
- * // Discover tools
239
- * const tools = await client.discovery.search("gas prices");
242
+ * @packageDocumentation
243
+ */
244
+
245
+ /**
246
+ * Composite context for tools that need multiple data sources.
240
247
  *
241
- * // Execute a tool method
242
- * const result = await client.tools.execute({
243
- * toolId: tools[0].id,
244
- * toolName: tools[0].mcpTools[0].name,
245
- * args: { chainId: 1 }
246
- * });
247
- * ```
248
+ * This is the unified structure that can be passed to MCP tools
249
+ * to provide comprehensive user context.
248
250
  */
249
- declare class ContextClient {
250
- private readonly apiKey;
251
- private readonly baseUrl;
252
- /**
253
- * Discovery resource for searching tools
254
- */
255
- readonly discovery: Discovery;
256
- /**
257
- * Tools resource for executing tools
258
- */
259
- readonly tools: Tools;
260
- /**
261
- * Creates a new Context Protocol client
262
- *
263
- * @param options - Client configuration options
264
- * @param options.apiKey - Your Context Protocol API key (format: sk_live_...)
265
- * @param options.baseUrl - Optional base URL override (defaults to https://ctxprotocol.com)
266
- */
267
- constructor(options: ContextClientOptions);
268
- /**
269
- * Internal method for making authenticated HTTP requests
270
- * All requests include the Authorization header with the API key
271
- *
272
- * @internal
273
- */
274
- fetch<T>(endpoint: string, options?: RequestInit): Promise<T>;
251
+ interface UserContext {
252
+ /** Base wallet information */
253
+ wallet?: WalletContext;
254
+ /** ERC20 token holdings */
255
+ erc20?: ERC20Context;
256
+ /** Polymarket positions and orders */
257
+ polymarket?: PolymarketContext;
258
+ /** Hyperliquid perpetual positions and account data */
259
+ hyperliquid?: HyperliquidContext;
275
260
  }
276
261
 
277
- 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 };
262
+ export type { ERC20Context, ERC20TokenBalance, HyperliquidAccountSummary, HyperliquidContext, HyperliquidOrder, HyperliquidPerpPosition, HyperliquidSpotBalance, PolymarketContext, PolymarketOrder, PolymarketPosition, UserContext, WalletContext };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/types.ts
1
+ // src/client/types.ts
2
2
  var ContextError = class extends Error {
3
3
  constructor(message, code, statusCode, helpUrl) {
4
4
  super(message);
@@ -9,7 +9,7 @@ var ContextError = class extends Error {
9
9
  }
10
10
  };
11
11
 
12
- // src/resources/discovery.ts
12
+ // src/client/resources/discovery.ts
13
13
  var Discovery = class {
14
14
  constructor(client) {
15
15
  this.client = client;
@@ -57,7 +57,7 @@ var Discovery = class {
57
57
  }
58
58
  };
59
59
 
60
- // src/resources/tools.ts
60
+ // src/client/resources/tools.ts
61
61
  var Tools = class {
62
62
  constructor(client) {
63
63
  this.client = client;
@@ -121,7 +121,7 @@ var Tools = class {
121
121
  }
122
122
  };
123
123
 
124
- // src/client.ts
124
+ // src/client/client.ts
125
125
  var ContextClient = class {
126
126
  apiKey;
127
127
  baseUrl;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/resources/discovery.ts","../src/resources/tools.ts","../src/client.ts"],"names":[],"mappings":";AAsLO,IAAM,YAAA,GAAN,cAA2B,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;AAAA,EACd;AACF;;;AC1LO,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,MAAsB,QAAQ,CAAA;AAEjE,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,KAAA;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,GAAA;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;AAAA;AAAA;AAAA,EAKD,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;AAAA;AAAA,EAQA,MAAM,KAAA,CAAS,QAAA,EAAkB,OAAA,GAAuB,EAAC,EAAe;AACtE,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAO,GAAG,QAAQ,CAAA,CAAA;AAEtC,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,GAAG,OAAA;AAAA,MACH,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,QACpC,GAAG,OAAA,CAAQ;AAAA;AACb,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,eAAe,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA,CAAA;AAClE,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,OAAA;AAEJ,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,EAAK;AACtC,QAAA,IAAI,UAAU,KAAA,EAAO;AACnB,UAAA,YAAA,GAAe,SAAA,CAAU,KAAA;AACzB,UAAA,SAAA,GAAY,SAAA,CAAU,IAAA;AACtB,UAAA,OAAA,GAAU,SAAA,CAAU,OAAA;AAAA,QACtB;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,MAAM,IAAI,YAAA,CAAa,YAAA,EAAc,SAAA,EAAW,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA,IAC1E;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AACF","file":"index.js","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":";AAsLO,IAAM,YAAA,GAAN,cAA2B,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;AAAA,EACd;AACF;;;AC1LO,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,MAAsB,QAAQ,CAAA;AAEjE,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,KAAA;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,GAAA;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;AAAA;AAAA;AAAA,EAKD,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;AAAA;AAAA,EAQA,MAAM,KAAA,CAAS,QAAA,EAAkB,OAAA,GAAuB,EAAC,EAAe;AACtE,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAO,GAAG,QAAQ,CAAA,CAAA;AAEtC,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,GAAG,OAAA;AAAA,MACH,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,QACpC,GAAG,OAAA,CAAQ;AAAA;AACb,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,eAAe,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA,CAAA;AAClE,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,OAAA;AAEJ,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,EAAK;AACtC,QAAA,IAAI,UAAU,KAAA,EAAO;AACnB,UAAA,YAAA,GAAe,SAAA,CAAU,KAAA;AACzB,UAAA,SAAA,GAAY,SAAA,CAAU,IAAA;AACtB,UAAA,OAAA,GAAU,SAAA,CAAU,OAAA;AAAA,QACtB;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,MAAM,IAAI,YAAA,CAAa,YAAA,EAAc,SAAA,EAAW,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA,IAC1E;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AACF","file":"index.js","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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctxprotocol/sdk",
3
- "version": "0.1.3",
3
+ "version": "0.4.0",
4
4
  "description": "Official TypeScript SDK for the Context Protocol - Discover and execute AI tools programmatically",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -16,6 +16,16 @@
16
16
  "types": "./dist/index.d.cts",
17
17
  "default": "./dist/index.cjs"
18
18
  }
19
+ },
20
+ "./client": {
21
+ "import": {
22
+ "types": "./dist/client/index.d.ts",
23
+ "default": "./dist/client/index.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/client/index.d.cts",
27
+ "default": "./dist/client/index.cjs"
28
+ }
19
29
  }
20
30
  },
21
31
  "files": [
@@ -47,6 +57,7 @@
47
57
  "bugs": {
48
58
  "url": "https://github.com/ctxprotocol/sdk/issues"
49
59
  },
60
+ "dependencies": {},
50
61
  "devDependencies": {
51
62
  "tsup": "^8.3.5",
52
63
  "typescript": "^5.7.2"
@@ -54,4 +65,4 @@
54
65
  "engines": {
55
66
  "node": ">=18.0.0"
56
67
  }
57
- }
68
+ }