opentool 0.6.5 → 0.7.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.
package/README.md CHANGED
@@ -11,30 +11,6 @@ Build serverless TypeScript tools that work with AI assistants, handle crypto pa
11
11
 
12
12
  OpenTool lets you write simple TypeScript functions that can be called by other agents, monetized with crypto payments, and deployed as serverless functions. It handles the boring stuff like:
13
13
 
14
- - Type validation with Zod schemas
15
- - AI client integration (OpenAI, Anthropic, etc.)
16
- - Multi-chain wallet support (Ethereum, Base, Arbitrum, etc.)
17
- - Automatic AWS Lambda deployment via [OpenPond](https://openpond.ai)
18
- - Payment infrastructure for on-chain tool monetization
19
-
20
- ## Recent Updates
21
-
22
- - **Selective MCP mode** - tools now support `mcp = { enabled: true }` to enable MCP clients on a per-tool basis
23
- - **Context bundling** - generates consolidated context files for AI code generation (see `dist/opentool-context.ts`)
24
- - **Default bundling enabled** - tools now bundle by default for cleaner deployments
25
- - **Improved CLI** - better validation and metadata generation commands
26
-
27
- ## Features
28
-
29
- - **TypeScript-first** with Zod validation and auto-generated JSON schemas
30
- - **Serverless by default** - deploys to AWS Lambda with Function URLs
31
- - **MCP support** - works with Claude Desktop, MCP Inspector, or any MCP client
32
- - **Built-in AI client** for OpenAI, Anthropic, and compatible providers
33
- - **Multi-chain wallets** - Ethereum, Base, Arbitrum, Polygon, etc.
34
- - **Crypto payments** - monetize tools with ERC-20 tokens (USDC, USDT, DAI)
35
- - **CLI tools** for building, validating, and local dev with watch mode
36
- - **Context bundling** - generates consolidated context files for AI code generation
37
-
38
14
  ## Installation
39
15
 
40
16
  ```bash
@@ -89,7 +65,36 @@ npx opentool validate
89
65
  npx opentool dev
90
66
  ```
91
67
 
92
- ### 4. Enable MCP mode (optional)
68
+ ### 4. x402
69
+
70
+ Include the definePayment function from the opentool package to define your payment config.
71
+
72
+ ```typescript
73
+ import { generateText } from "opentool/ai";
74
+ import { definePayment } from "opentool/payment";
75
+
76
+ export const payment = definePayment({
77
+ amount: "0.50",
78
+ currency: "USDC",
79
+ payTo: "0x...",
80
+ message: "Premium analytics require payment before access.",
81
+ acceptedMethods: ["x402", "402"],
82
+ acceptedCurrencies: ["USDC"],
83
+ chains: ["base"],
84
+ facilitator: "opentool",
85
+ });
86
+
87
+ export async function POST(request: Request) {
88
+ const payload = await request.json();
89
+ const { symbol } = schema.parse(payload);
90
+ const report = await generateText("Premium Content " + symbol);
91
+ return Response.json({
92
+ message: `Premium analytics for ${symbol}`,
93
+ });
94
+ }
95
+ ```
96
+
97
+ ### 4. MCP
93
98
 
94
99
  By default, tools are HTTP-only. Want them accessible via MCP clients like Claude Desktop? Just add this to your tool file:
95
100
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { h as Metadata, I as InternalToolDefinition } from '../validate-BLlooEBK.js';
3
- export { G as GenerateMetadataOptions, i as GenerateMetadataResult, V as ValidateOptions, g as generateMetadata, a as generateMetadataCommand, l as loadAndValidateTools, v as validateCommand, j as validateFullCommand } from '../validate-BLlooEBK.js';
2
+ import { h as Metadata, I as InternalToolDefinition } from '../validate-CqB2Juma.js';
3
+ export { G as GenerateMetadataOptions, i as GenerateMetadataResult, V as ValidateOptions, g as generateMetadata, a as generateMetadataCommand, l as loadAndValidateTools, v as validateCommand, j as validateFullCommand } from '../validate-CqB2Juma.js';
4
4
  import 'zod';
5
- import '../index-D3DaM5Rs.js';
5
+ import '../index-D_bCF2Bf.js';
6
6
 
7
7
  interface BuildOptions {
8
8
  input: string;
package/dist/cli/index.js CHANGED
@@ -7,7 +7,7 @@ import { build } from 'esbuild';
7
7
  import { z } from 'zod';
8
8
  import { createRequire } from 'module';
9
9
  import { fileURLToPath, pathToFileURL } from 'url';
10
- import { zodToJsonSchema } from 'zod-to-json-schema';
10
+ import { zodToJsonSchema } from '@alcyone-labs/zod-to-json-schema';
11
11
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
12
12
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
13
  import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
@@ -95,7 +95,7 @@ var PaymentConfigSchema = z.object({
95
95
  plain402: z.boolean().optional(),
96
96
  acceptedMethods: z.array(z.union([z.literal("x402"), z.literal("402")])).optional(),
97
97
  acceptedCurrencies: z.array(z.string()).optional(),
98
- chainIds: z.array(z.number().int()).optional(),
98
+ chains: z.array(z.union([z.string(), z.number()])).optional(),
99
99
  facilitator: z.string().optional()
100
100
  }).strict();
101
101
  var DiscoveryMetadataSchema = z.object({
@@ -103,9 +103,9 @@ var DiscoveryMetadataSchema = z.object({
103
103
  category: z.string().optional(),
104
104
  useCases: z.array(z.string()).optional(),
105
105
  capabilities: z.array(z.string()).optional(),
106
- requirements: z.record(z.any()).optional(),
107
- pricing: z.record(z.any()).optional(),
108
- compatibility: z.record(z.any()).optional(),
106
+ requirements: z.record(z.string(), z.any()).optional(),
107
+ pricing: z.record(z.string(), z.any()).optional(),
108
+ compatibility: z.record(z.string(), z.any()).optional(),
109
109
  documentation: z.union([z.string(), z.array(z.string())]).optional()
110
110
  }).catchall(z.any());
111
111
  var ToolMetadataOverridesSchema = z.object({
@@ -148,9 +148,9 @@ var AuthoredMetadataSchema = z.object({
148
148
  keywords: z.array(z.string()).optional(),
149
149
  useCases: z.array(z.string()).optional(),
150
150
  capabilities: z.array(z.string()).optional(),
151
- requirements: z.record(z.any()).optional(),
152
- pricing: z.record(z.any()).optional(),
153
- compatibility: z.record(z.any()).optional(),
151
+ requirements: z.record(z.string(), z.any()).optional(),
152
+ pricing: z.record(z.string(), z.any()).optional(),
153
+ compatibility: z.record(z.string(), z.any()).optional(),
154
154
  chains: z.array(z.union([z.string(), z.number()])).optional()
155
155
  }).catchall(z.any());
156
156
  var MetadataSchema = z.object({
@@ -409,7 +409,7 @@ function resolvePayment(authored, defaults) {
409
409
  plain402: acceptedMethods.includes("402"),
410
410
  acceptedMethods,
411
411
  acceptedCurrencies: Array.isArray(pricing.acceptedCurrencies) ? pricing.acceptedCurrencies : ["USDC"],
412
- chainIds: Array.isArray(pricing.chainIds) ? pricing.chainIds : [8453]
412
+ chains: Array.isArray(pricing.chains) ? pricing.chains : [8453]
413
413
  };
414
414
  }
415
415
  function buildDiscovery(authored) {
@@ -1884,8 +1884,20 @@ async function buildWorkflowsIfPresent(options) {
1884
1884
  );
1885
1885
  return null;
1886
1886
  }
1887
- const { BaseBuilder } = await import('@workflow/cli/dist/lib/builders/base-builder.js');
1887
+ let BaseBuilder;
1888
+ try {
1889
+ ({ BaseBuilder } = await import('@workflow/cli/dist/lib/builders/base-builder.js'));
1890
+ } catch (error) {
1891
+ const details = error instanceof Error ? `
1892
+ Reason: ${error.message}` : "";
1893
+ throw new Error(
1894
+ `[${timestamp()}] Workflow sources detected, but optional dependency '@workflow/cli' is not installed. Install it with "npm install @workflow/cli" (or add it to devDependencies) and rerun the build.` + details
1895
+ );
1896
+ }
1888
1897
  class OpenToolWorkflowBuilder extends BaseBuilder {
1898
+ constructor(config) {
1899
+ super(config);
1900
+ }
1889
1901
  async build() {
1890
1902
  const inputFiles = await this.getInputFiles();
1891
1903
  const tsConfig = await this.getTsConfigOptions();
@@ -1946,6 +1958,22 @@ async function buildWorkflowsIfPresent(options) {
1946
1958
  });
1947
1959
  await this.createWebhookBundle({ outfile: webhookBundlePath2 });
1948
1960
  }
1961
+ async buildClientLibrary() {
1962
+ if (!this.config?.clientBundlePath) {
1963
+ return;
1964
+ }
1965
+ const clientBundlePath2 = path5.resolve(
1966
+ this.config.workingDir,
1967
+ this.config.clientBundlePath
1968
+ );
1969
+ await fs4.promises.mkdir(path5.dirname(clientBundlePath2), {
1970
+ recursive: true
1971
+ });
1972
+ await this.createWorkflowsBundle({
1973
+ outfile: clientBundlePath2,
1974
+ bundleFinalOutput: true
1975
+ });
1976
+ }
1949
1977
  }
1950
1978
  const relativeSourceDir = path5.relative(options.projectRoot, workflowsDir) || ".";
1951
1979
  const outputBase = path5.join(