opentool 0.8.5 → 0.8.7

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
@@ -73,6 +73,7 @@ For private tools, say for internal trading apps:
73
73
 
74
74
  - GET-only (scheduled default profile)
75
75
  - POST-only (one-off, parameterized with Zod)
76
+ - `profile.category` defaults to `tracker` if omitted; set to `strategy` for PnL/automation tools.
76
77
 
77
78
  GET-only (scheduled default)
78
79
 
@@ -80,6 +81,7 @@ GET-only (scheduled default)
80
81
  // tools/aave-stake.ts
81
82
  export const profile = {
82
83
  description: "Stake 100 USDC daily at 12:00 UTC",
84
+ category: "strategy",
83
85
  fixedAmount: "100",
84
86
  tokenSymbol: "USDC",
85
87
  schedule: { cron: "0 12 * * *", enabled: false },
@@ -103,6 +105,12 @@ POST-only (one-off)
103
105
  // tools/aave-unstake.ts
104
106
  import { z } from "zod";
105
107
 
108
+ export const profile = {
109
+ description: "Unstake USDC on demand",
110
+ category: "tracker",
111
+ notifyEmail: true,
112
+ };
113
+
106
114
  export const schema = z.object({
107
115
  amount: z.string(),
108
116
  token: z.string().default("USDC"),
@@ -115,10 +123,16 @@ export async function POST(req: Request) {
115
123
  }
116
124
  ```
117
125
 
126
+ ### Email notifications for one-off tools
127
+
128
+ - POST-only tools can set `profile.notifyEmail = true` to request an email when the tool runs.
129
+ - Scheduled tools should continue to use `profile.schedule.notifyEmail`.
130
+
118
131
  ### Cron schedules (`profile.schedule`)
119
132
 
120
133
  - GET-only tools require `profile.schedule` with a standard 5–6 field cron expression (e.g., `0 12 * * *` or `0 0 ? * MON-FRI *`).
121
134
  - Build validates the cron shape and emits `.well-known/opentool/cron.json` capturing each scheduled tool (`toolName`, `toolPath`, `scheduleExpression`). Enabled defaults to `false` even if authors set it to `true` in code. Deployment targets can translate these cron strings to their provider format (e.g., EventBridge) downstream.
135
+ - Use `profile.schedule.notifyEmail = true` to request email delivery on schedule runs.
122
136
 
123
137
  ### Public tools: Add x402 payments (optional)
124
138
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { M as Metadata, I as InternalToolDefinition } from '../validate-BJ5-5n8h.js';
3
- export { G as GenerateMetadataOptions, a as GenerateMetadataResult, V as ValidateOptions, b as generateMetadata, g as generateMetadataCommand, l as loadAndValidateTools, v as validateCommand, c as validateFullCommand } from '../validate-BJ5-5n8h.js';
2
+ import { M as Metadata, I as InternalToolDefinition } from '../validate-3e5UvzfQ.js';
3
+ export { G as GenerateMetadataOptions, a as GenerateMetadataResult, V as ValidateOptions, b as generateMetadata, g as generateMetadataCommand, l as loadAndValidateTools, v as validateCommand, c as validateFullCommand } from '../validate-3e5UvzfQ.js';
4
4
  import 'zod';
5
5
  import '../x402/index.js';
6
6
  import 'viem';
package/dist/cli/index.js CHANGED
@@ -139,6 +139,7 @@ var DiscoveryMetadataSchema = z.object({
139
139
  compatibility: z.record(z.string(), z.any()).optional(),
140
140
  documentation: z.union([z.string(), z.array(z.string())]).optional()
141
141
  }).catchall(z.any());
142
+ var ToolCategorySchema = z.enum(["strategy", "tracker"]);
142
143
  var ToolMetadataOverridesSchema = z.object({
143
144
  name: z.string().optional(),
144
145
  description: z.string().optional(),
@@ -154,7 +155,9 @@ var ToolSchema = z.object({
154
155
  annotations: McpAnnotationsSchema.optional(),
155
156
  payment: PaymentConfigSchema.optional(),
156
157
  discovery: DiscoveryMetadataSchema.optional(),
157
- chains: z.array(z.union([z.string(), z.number()])).optional()
158
+ chains: z.array(z.union([z.string(), z.number()])).optional(),
159
+ notifyEmail: z.boolean().optional(),
160
+ category: ToolCategorySchema.optional()
158
161
  }).strict();
159
162
  var MetadataSchema = z.object({
160
163
  metadataSpecVersion: z.string().optional(),
@@ -340,6 +343,10 @@ async function buildMetadataArtifact(options) {
340
343
  }
341
344
  const toolDiscovery = overrides.discovery ?? void 0;
342
345
  const toolChains = overrides.chains ?? authored.chains ?? void 0;
346
+ const toolCategory = tool.profileCategory ?? "tracker";
347
+ if (!tool.profileCategory) {
348
+ defaultsApplied.push(`tool ${toolName} category \u2192 tracker (default)`);
349
+ }
343
350
  const toolDefinition = {
344
351
  name: toolName,
345
352
  description: toolDescription,
@@ -357,6 +364,14 @@ async function buildMetadataArtifact(options) {
357
364
  if (toolChains) {
358
365
  toolDefinition.chains = toolChains;
359
366
  }
367
+ toolDefinition.category = toolCategory;
368
+ const notifyEmail = tool.notifyEmail ?? tool.schedule?.notifyEmail;
369
+ if (notifyEmail !== void 0) {
370
+ toolDefinition.notifyEmail = notifyEmail;
371
+ }
372
+ if (tool.profileCategory) {
373
+ toolDefinition.category = tool.profileCategory;
374
+ }
360
375
  return toolDefinition;
361
376
  });
362
377
  const metadata = BuildMetadataSchema.parse({
@@ -1093,6 +1108,14 @@ async function loadAndValidateTools(toolsDir, options = {}) {
1093
1108
  }
1094
1109
  let normalizedSchedule = null;
1095
1110
  const schedule = toolModule?.profile?.schedule;
1111
+ const profileNotifyEmail = typeof toolModule?.profile?.notifyEmail === "boolean" ? toolModule.profile.notifyEmail : void 0;
1112
+ const profileCategoryRaw = typeof toolModule?.profile?.category === "string" ? toolModule.profile.category : void 0;
1113
+ const allowedProfileCategories = /* @__PURE__ */ new Set(["strategy", "tracker"]);
1114
+ if (profileCategoryRaw && !allowedProfileCategories.has(profileCategoryRaw)) {
1115
+ throw new Error(
1116
+ `${file}: profile.category must be one of ${Array.from(allowedProfileCategories).join(", ")}`
1117
+ );
1118
+ }
1096
1119
  if (hasGET && schedule && typeof schedule.cron === "string" && schedule.cron.trim().length > 0) {
1097
1120
  normalizedSchedule = normalizeScheduleExpression(schedule.cron, file);
1098
1121
  if (typeof schedule.enabled === "boolean") {
@@ -1162,7 +1185,9 @@ async function loadAndValidateTools(toolsDir, options = {}) {
1162
1185
  handler: async (params) => adapter(params),
1163
1186
  payment: paymentExport ?? null,
1164
1187
  schedule: normalizedSchedule,
1165
- profileDescription: typeof toolModule?.profile?.description === "string" ? toolModule.profile?.description ?? null : null
1188
+ ...profileNotifyEmail !== void 0 ? { notifyEmail: profileNotifyEmail } : {},
1189
+ profileDescription: typeof toolModule?.profile?.description === "string" ? toolModule.profile?.description ?? null : null,
1190
+ ...profileCategoryRaw ? { profileCategory: profileCategoryRaw } : {}
1166
1191
  };
1167
1192
  tools.push(tool);
1168
1193
  }