opentool 0.5.0 → 0.6.1

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.
Files changed (60) hide show
  1. package/README.md +87 -22
  2. package/dist/ai/index.d.ts +237 -0
  3. package/dist/ai/index.js +759 -0
  4. package/dist/ai/index.js.map +1 -0
  5. package/dist/cli/index.d.ts +38 -5
  6. package/dist/cli/index.js +2218 -67
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/index-D3DaM5Rs.d.ts +1693 -0
  9. package/dist/index.d.ts +33 -5
  10. package/dist/index.js +3258 -25
  11. package/dist/index.js.map +1 -1
  12. package/dist/payment/index.d.ts +2 -0
  13. package/dist/payment/index.js +969 -0
  14. package/dist/payment/index.js.map +1 -0
  15. package/dist/{types/metadata.d.ts → validate-DiIOFUU5.d.ts} +262 -415
  16. package/dist/wallets/index.d.ts +117 -0
  17. package/dist/wallets/index.js +337 -0
  18. package/dist/wallets/index.js.map +1 -0
  19. package/package.json +35 -4
  20. package/dist/cli/build.d.ts +0 -23
  21. package/dist/cli/build.d.ts.map +0 -1
  22. package/dist/cli/build.js +0 -223
  23. package/dist/cli/build.js.map +0 -1
  24. package/dist/cli/dev.d.ts +0 -6
  25. package/dist/cli/dev.d.ts.map +0 -1
  26. package/dist/cli/dev.js +0 -123
  27. package/dist/cli/dev.js.map +0 -1
  28. package/dist/cli/generate-metadata.d.ts +0 -15
  29. package/dist/cli/generate-metadata.d.ts.map +0 -1
  30. package/dist/cli/generate-metadata.js +0 -90
  31. package/dist/cli/generate-metadata.js.map +0 -1
  32. package/dist/cli/index.d.ts.map +0 -1
  33. package/dist/cli/shared/metadata.d.ts +0 -19
  34. package/dist/cli/shared/metadata.d.ts.map +0 -1
  35. package/dist/cli/shared/metadata.js +0 -283
  36. package/dist/cli/shared/metadata.js.map +0 -1
  37. package/dist/cli/validate.d.ts +0 -12
  38. package/dist/cli/validate.d.ts.map +0 -1
  39. package/dist/cli/validate.js +0 -237
  40. package/dist/cli/validate.js.map +0 -1
  41. package/dist/index.d.ts.map +0 -1
  42. package/dist/runtime/index.d.ts +0 -12
  43. package/dist/runtime/index.d.ts.map +0 -1
  44. package/dist/runtime/index.js +0 -241
  45. package/dist/runtime/index.js.map +0 -1
  46. package/dist/types/index.d.ts +0 -33
  47. package/dist/types/index.d.ts.map +0 -1
  48. package/dist/types/index.js +0 -3
  49. package/dist/types/index.js.map +0 -1
  50. package/dist/types/metadata.d.ts.map +0 -1
  51. package/dist/types/metadata.js +0 -108
  52. package/dist/types/metadata.js.map +0 -1
  53. package/dist/utils/esbuild.d.ts +0 -13
  54. package/dist/utils/esbuild.d.ts.map +0 -1
  55. package/dist/utils/esbuild.js +0 -95
  56. package/dist/utils/esbuild.js.map +0 -1
  57. package/dist/utils/module-loader.d.ts +0 -3
  58. package/dist/utils/module-loader.d.ts.map +0 -1
  59. package/dist/utils/module-loader.js +0 -49
  60. package/dist/utils/module-loader.js.map +0 -1
package/README.md CHANGED
@@ -3,20 +3,50 @@
3
3
  [![npm version](https://badge.fury.io/js/opentool.svg)](https://badge.fury.io/js/opentool)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- ## OpenPond Hosting launching August 2025
6
+ A comprehensive TypeScript framework for building, deploying, and monetizing serverless MCP (Model Context Protocol) tools with integrated AI, blockchain wallets, and crypto payments.
7
7
 
8
- (current openpond.ai site hasn't been updated yet)
8
+ **For LLMs/AI Code Generation:** [`dist/opentool-context.ts`](./scripts/build-context.ts)
9
9
 
10
- A TypeScript framework for building serverless MCP (Model Context Protocol) tools that automatically deploy to AWS Lambda using [OpenPond](https://openpond.ai) hosting.
10
+ ## Overview
11
+
12
+ OpenTool is a complete platform for creating intelligent, payment-enabled tools that run on AWS Lambda. It combines:
13
+
14
+ - **MCP Protocol** - Full Model Context Protocol implementation with stdio and HTTP transports
15
+ - **AI Integration** - Built-in AI client with text generation, streaming, and tool calling capabilities
16
+ - **Wallet System** - Multi-chain blockchain wallet support with Turnkey and private key providers
17
+ - **Payment Infrastructure** - Crypto payment integration for monetizing tools on-chain
18
+ - **Serverless Deployment** - Automatic AWS Lambda deployment via [OpenPond](https://openpond.ai)
19
+ - **Type Safety** - Full TypeScript support with Zod schema validation
11
20
 
12
21
  ## Features
13
22
 
14
- - **Serverless-first**: Tools automatically deploy to AWS Lambda
15
- - **Type-safe**: Full TypeScript support with Zod schema validation
16
- - **CLI Tools**: Build, develop, and validate your tools
17
- - **MCP Compatible**: Works with any MCP client
18
- - **Automatic Detection**: Detected by OpenPond hosting platform
19
- - **Local Development**: Test your tools locally before deployment
23
+ ### Core Framework
24
+
25
+ - **Serverless-first**: Tools automatically deploy to AWS Lambda with Function URLs
26
+ - **Type-safe**: Full TypeScript support with Zod schema validation and automatic JSON schema generation
27
+ - **CLI Tools**: Build, develop, validate, and generate metadata with comprehensive CLI
28
+ - **Hot Reloading**: Development server with optional watch mode for rapid iteration
29
+ - **MCP Compatible**: Works with any MCP client (Claude Desktop, MCP Inspector, etc.)
30
+
31
+ ### AI Capabilities
32
+
33
+ - **Multi-Model Support**: OpenAI, Anthropic, and compatible providers
34
+ - **Text Generation**: Simple and streaming text generation with tool calling
35
+ - **Built-in Tools**: Web search and custom tool integration
36
+ - **Model Management**: Automatic model normalization and capability detection
37
+
38
+ ### Blockchain & Payments
39
+
40
+ - **Multi-Chain Wallets**: Support for Ethereum, Base, Optimism, Arbitrum, Polygon, and more
41
+ - **Provider Flexibility**: Private key or Turnkey-managed signing
42
+ - **Crypto Payments**: On-chain payment integration with ERC-20 token support
43
+ - **Token Registry**: Built-in registry for common tokens (USDC, USDT, DAI, etc.)
44
+
45
+ ### Discovery & Metadata
46
+
47
+ - **Three-Tier Metadata**: Smart defaults, enhanced metadata, and per-tool overrides
48
+ - **On-Chain Registration**: Metadata formatted for blockchain discovery
49
+ - **Rich Annotations**: Icons, categories, tags, and custom branding
20
50
 
21
51
  ## Installation
22
52
 
@@ -47,8 +77,18 @@ export const schema = z.object({
47
77
  name: z.string().describe("The name of the user to greet"),
48
78
  });
49
79
 
50
- export async function TOOL({ name }: z.infer<typeof schema>) {
51
- return `Hello, ${name}! 👋`;
80
+ export const metadata = {
81
+ name: "greet",
82
+ description: "Simple greeting tool",
83
+ };
84
+
85
+ export async function POST(request: Request) {
86
+ const payload = await request.json();
87
+ const { name } = schema.parse(payload);
88
+
89
+ return Response.json({
90
+ message: `Hello, ${name}!`,
91
+ });
52
92
  }
53
93
  ```
54
94
 
@@ -62,6 +102,19 @@ npx opentool validate
62
102
  npx opentool dev
63
103
  ```
64
104
 
105
+ ### MCP Inspector
106
+
107
+ The `examples/full-metadata` project includes an `inspector.json` preset so you can exercise MCP tools with the official MCP Inspector:
108
+
109
+ ```bash
110
+ cd examples/full-metadata
111
+ npx mcp-inspector --config inspector.json --server opentool-dev
112
+ ```
113
+
114
+ Before starting the inspector, copy `examples/full-metadata/.env.example` to `examples/full-metadata/.env` and populate the Turnkey, 0x, and Alchemy secrets with your own credentials. The actual `.env` file is git-ignored so you can keep real keys out of version control.
115
+
116
+ The inspector spawns `opentool dev --stdio --no-watch --input tools`, so you don’t need a second terminal. Only tools that export `mcp = { enabled: true }` (for example `mcp_ping`) appear in the inspector’s tool list; HTTP-only tools like `calculate` and `hello` keep responding on the local HTTP port.
117
+
65
118
  ### 4. Build for deployment
66
119
 
67
120
  ```bash
@@ -134,11 +187,11 @@ This command generates the `metadata.json` file that contains all the informatio
134
187
 
135
188
  ## Tool Definition
136
189
 
137
- Each tool is defined by exporting three things:
190
+ Each tool is defined by exporting:
138
191
 
139
192
  1. **schema**: Zod schema for input validation
140
193
  2. **metadata**: Tool information and MCP annotations
141
- 3. **TOOL**: Async function that implements the tool logic
194
+ 3. **HTTP handler**: Async function that implements the tool logic (e.g., POST, GET, PUT, DELETE)
142
195
 
143
196
  ```typescript
144
197
  import { z } from "zod";
@@ -147,23 +200,36 @@ export const schema = z.object({
147
200
  // Define your input parameters here
148
201
  });
149
202
 
150
- export async function TOOL(params: z.infer<typeof schema>) {
203
+ export const metadata = {
204
+ name: "my_tool",
205
+ description: "Description of what this tool does",
206
+ };
207
+
208
+ export async function POST(request: Request) {
209
+ const payload = await request.json();
210
+ const params = schema.parse(payload);
211
+
151
212
  // Implement your tool logic here
152
- // Just return a string - it will be wrapped in MCP format automatically
153
- return "Tool response";
213
+ return Response.json({
214
+ result: "Tool response",
215
+ });
154
216
  }
155
217
  ```
156
218
 
157
219
  ## Error Handling
158
220
 
159
- Simply throw errors in your TOOL function - they will be automatically converted to MCP error responses:
221
+ Return appropriate HTTP status codes and error messages in your response:
160
222
 
161
223
  ```typescript
162
- export async function TOOL(params: z.infer<typeof schema>) {
224
+ export async function POST(request: Request) {
225
+ const payload = await request.json();
226
+ const params = schema.parse(payload);
227
+
163
228
  if (someCondition) {
164
- throw new Error("Something went wrong");
229
+ return Response.json({ error: "Something went wrong" }, { status: 400 });
165
230
  }
166
- return "Success";
231
+
232
+ return Response.json({ result: "Success" });
167
233
  }
168
234
  ```
169
235
 
@@ -223,7 +289,7 @@ npm run examples:metadata # Regenerate metadata.json without rebuilding tools
223
289
  OpenTool features a sophisticated **three-tier metadata system**:
224
290
 
225
291
  1. **Smart Defaults** - Zero configuration, automatic generation from `package.json`
226
- 2. **Enhanced Metadata** - Optional `metadata.ts` for custom branding and crypto payments
292
+ 2. **Enhanced Metadata** - Optional `metadata.ts` for custom branding and crypto payments
227
293
  3. **Full Control** - Tool-level overrides for rich discovery metadata
228
294
 
229
295
  See [`METADATA.md`](./METADATA.md) for the complete guide to configuring metadata for on-chain registration and payments.
@@ -236,7 +302,6 @@ See [`METADATA.md`](./METADATA.md) for the complete guide to configuring metadat
236
302
 
237
303
  We welcome contributions! Please see our [Contributing Guide](https://github.com/openpond/opentool/blob/master/CONTRIBUTING.md) for details.
238
304
 
239
-
240
305
  ## License
241
306
 
242
307
  MIT © [OpenTool](https://opentool.dev)
@@ -0,0 +1,237 @@
1
+ type ChatMessageRole = "system" | "user" | "assistant" | "tool";
2
+ interface ChatMessageContentPartText {
3
+ type: "text";
4
+ text: string;
5
+ }
6
+ interface ChatMessageContentPartImageUrl {
7
+ type: "image_url";
8
+ image_url: {
9
+ url: string;
10
+ detail?: "auto" | "high" | "low";
11
+ };
12
+ }
13
+ type ChatMessageContentPart = ChatMessageContentPartText | ChatMessageContentPartImageUrl | Record<string, unknown>;
14
+ interface ChatMessage {
15
+ role: ChatMessageRole;
16
+ content: string | ChatMessageContentPart[];
17
+ name?: string;
18
+ tool_call_id?: string;
19
+ }
20
+ interface JsonSchema {
21
+ type?: string;
22
+ title?: string;
23
+ description?: string;
24
+ properties?: Record<string, JsonSchema>;
25
+ required?: string[];
26
+ items?: JsonSchema | JsonSchema[];
27
+ enum?: Array<string | number | boolean | null>;
28
+ additionalProperties?: boolean | JsonSchema;
29
+ [key: string]: unknown;
30
+ }
31
+ interface FunctionToolDefinition {
32
+ type: "function";
33
+ function: {
34
+ name: string;
35
+ description?: string;
36
+ parameters?: JsonSchema;
37
+ };
38
+ }
39
+ type ToolDefinition = FunctionToolDefinition;
40
+ type ToolChoice = "auto" | "required" | "none" | {
41
+ type: "function";
42
+ function: {
43
+ name: string;
44
+ };
45
+ };
46
+ interface GenerationParameters {
47
+ temperature?: number;
48
+ topP?: number;
49
+ maxTokens?: number;
50
+ stop?: string | string[];
51
+ frequencyPenalty?: number;
52
+ presencePenalty?: number;
53
+ responseFormat?: "json_object" | "text" | {
54
+ type: "json_schema";
55
+ json_schema: JsonSchema;
56
+ };
57
+ }
58
+ interface ToolExecutionPolicy {
59
+ enableTools?: boolean;
60
+ maxSteps?: number;
61
+ toolSources?: "internal" | "public" | "both";
62
+ webSearch?: WebSearchOptions | false;
63
+ }
64
+ interface WebSearchOptions {
65
+ limit?: number;
66
+ includeImages?: boolean;
67
+ }
68
+ interface AIRequestMetadata {
69
+ requestId?: string;
70
+ sessionId?: string;
71
+ tags?: string[];
72
+ openpond?: Record<string, unknown>;
73
+ [key: string]: unknown;
74
+ }
75
+ interface GenerateTextOptions {
76
+ messages: ChatMessage[];
77
+ model?: string;
78
+ generation?: GenerationParameters;
79
+ tools?: ToolDefinition[];
80
+ toolChoice?: ToolChoice;
81
+ toolExecution?: ToolExecutionPolicy;
82
+ metadata?: AIRequestMetadata;
83
+ timeoutMs?: number;
84
+ abortSignal?: AbortSignal;
85
+ headers?: Record<string, string>;
86
+ }
87
+ interface AIClientConfig {
88
+ baseUrl?: string;
89
+ apiKey?: string;
90
+ defaultModel?: string;
91
+ defaultHeaders?: Record<string, string>;
92
+ fetchImplementation?: typeof fetch;
93
+ timeoutMs?: number;
94
+ }
95
+ interface ResolvedAIClientConfig {
96
+ baseUrl: string;
97
+ apiKey?: string;
98
+ defaultModel: string;
99
+ defaultHeaders: Record<string, string>;
100
+ fetchImplementation: typeof fetch;
101
+ timeoutMs: number;
102
+ }
103
+ interface ChatCompletionResponse {
104
+ id: string;
105
+ object: string;
106
+ created: number;
107
+ model: string;
108
+ choices: ChatCompletionChoice[];
109
+ usage?: ChatCompletionUsage;
110
+ system_fingerprint?: string;
111
+ }
112
+ interface ChatCompletionChoice {
113
+ index: number;
114
+ message: ChatMessage;
115
+ finish_reason?: string;
116
+ logprobs?: ChatCompletionLogProbs;
117
+ }
118
+ interface ChatCompletionUsage {
119
+ prompt_tokens: number;
120
+ completion_tokens: number;
121
+ total_tokens: number;
122
+ [key: string]: unknown;
123
+ }
124
+ interface ChatCompletionLogProbs {
125
+ content?: Array<{
126
+ token: string;
127
+ logprob: number;
128
+ bytes?: number[];
129
+ }>;
130
+ }
131
+ interface GenerateTextResult {
132
+ id: string;
133
+ model: string;
134
+ message: ChatMessage;
135
+ finishReason?: string;
136
+ usage?: ChatCompletionUsage;
137
+ raw: ChatCompletionResponse;
138
+ }
139
+ interface StreamingEventHandlers {
140
+ onTextDelta?: (delta: string) => void;
141
+ onToolCallDelta?: (toolCall: unknown) => void;
142
+ onReasoningDelta?: (delta: string) => void;
143
+ onUsage?: (usage: ChatCompletionUsage) => void;
144
+ onError?: (error: unknown) => void;
145
+ onDone?: () => void;
146
+ }
147
+ interface StreamTextOptions extends GenerateTextOptions {
148
+ handlers?: StreamingEventHandlers;
149
+ sendReasoning?: boolean;
150
+ includeUsage?: boolean;
151
+ }
152
+ interface StreamTextResult {
153
+ abort: () => void;
154
+ finished: Promise<void>;
155
+ }
156
+
157
+ interface ErrorInit {
158
+ cause?: unknown;
159
+ }
160
+ declare class AIError extends Error {
161
+ constructor(message: string, options?: ErrorInit);
162
+ }
163
+ interface ResponseErrorDetails {
164
+ status: number;
165
+ statusText: string;
166
+ body?: unknown;
167
+ headers?: Record<string, string>;
168
+ }
169
+ declare class AIFetchError extends AIError {
170
+ constructor(message: string, options?: ErrorInit);
171
+ }
172
+ declare class AIResponseError extends AIError {
173
+ readonly status: number;
174
+ readonly statusText: string;
175
+ readonly body?: unknown;
176
+ readonly headers: Record<string, string>;
177
+ constructor(details: ResponseErrorDetails, message?: string);
178
+ }
179
+ declare class AIAbortError extends AIError {
180
+ constructor(message?: string);
181
+ }
182
+
183
+ type ModelProvider = "openai" | "anthropic" | "google" | "deepseek" | "custom";
184
+ interface ModelConfig {
185
+ name: string;
186
+ label: string;
187
+ provider: ModelProvider;
188
+ supportsStreaming: boolean;
189
+ supportsTools: boolean;
190
+ reasoning?: boolean;
191
+ aliases?: string[];
192
+ default?: boolean;
193
+ }
194
+ declare function listModels(): ModelConfig[];
195
+ declare function getModelConfig(modelName?: string): ModelConfig | undefined;
196
+ declare function normalizeModelName(modelName?: string): string;
197
+ declare function isStreamingSupported(modelName?: string): boolean;
198
+ declare function isToolCallingSupported(modelName?: string): boolean;
199
+
200
+ interface AIClient {
201
+ readonly config: ResolvedAIClientConfig;
202
+ generateText(options: GenerateTextOptions): Promise<GenerateTextResult>;
203
+ streamText(options: StreamTextOptions): Promise<StreamTextResult>;
204
+ listModels: typeof listModels;
205
+ }
206
+ declare function createAIClient(config?: AIClientConfig): AIClient;
207
+ declare function generateText(options: GenerateTextOptions, clientConfig?: AIClientConfig): Promise<GenerateTextResult>;
208
+ declare function streamText(options: StreamTextOptions, clientConfig?: AIClientConfig): Promise<StreamTextResult>;
209
+
210
+ declare const DEFAULT_BASE_URL = "https://gateway.openpond.dev";
211
+ declare const DEFAULT_TIMEOUT_MS = 60000;
212
+ declare const DEFAULT_MODEL = "openai/gpt-5-mini";
213
+ declare function resolveConfig(config?: AIClientConfig): ResolvedAIClientConfig;
214
+
215
+ declare const WEBSEARCH_TOOL_NAME = "websearch";
216
+ declare const WEBSEARCH_TOOL_DEFINITION: ToolDefinition;
217
+ declare function resolveToolset(tools: ToolDefinition[] | undefined, policy: ToolExecutionPolicy | undefined): ToolDefinition[] | undefined;
218
+
219
+ interface FlattenMessageContentOptions {
220
+ /**
221
+ * String used to join individual text segments when the content array contains multiple text parts.
222
+ * Defaults to an empty string.
223
+ */
224
+ separator?: string;
225
+ /**
226
+ * When true, JSON stringifies non-text segments instead of discarding them.
227
+ * Defaults to false (skip non-text parts).
228
+ */
229
+ includeUnknown?: boolean;
230
+ }
231
+ declare function flattenMessageContent(content: ChatMessage["content"], options?: FlattenMessageContentOptions): string | undefined;
232
+ interface EnsureTextContentOptions extends FlattenMessageContentOptions {
233
+ errorMessage?: string;
234
+ }
235
+ declare function ensureTextContent(message: ChatMessage, options?: EnsureTextContentOptions): string;
236
+
237
+ export { AIAbortError, type AIClientConfig, AIError, AIFetchError, type AIRequestMetadata, AIResponseError, type ChatCompletionChoice, type ChatCompletionLogProbs, type ChatCompletionResponse, type ChatCompletionUsage, type ChatMessage, type ChatMessageContentPart, type ChatMessageContentPartImageUrl, type ChatMessageContentPartText, type ChatMessageRole, DEFAULT_BASE_URL, DEFAULT_MODEL, DEFAULT_TIMEOUT_MS, type FunctionToolDefinition, type GenerateTextOptions, type GenerateTextResult, type GenerationParameters, type JsonSchema, type ResolvedAIClientConfig, type ResponseErrorDetails, type StreamTextOptions, type StreamTextResult, type StreamingEventHandlers, type ToolChoice, type ToolDefinition, type ToolExecutionPolicy, WEBSEARCH_TOOL_DEFINITION, WEBSEARCH_TOOL_NAME, type WebSearchOptions, createAIClient, ensureTextContent, flattenMessageContent, generateText, getModelConfig, isStreamingSupported, isToolCallingSupported, listModels, normalizeModelName, resolveConfig, resolveToolset, streamText };