specrun 1.0.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/server.js ADDED
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OpenApiMcpServer = void 0;
7
+ const fastmcp_1 = require("fastmcp");
8
+ const openapi_parser_1 = require("./utils/openapi-parser");
9
+ const http_client_1 = require("./utils/http-client");
10
+ const auth_1 = require("./utils/auth");
11
+ const prompts_1 = require("./prompts");
12
+ const tools_1 = require("./tools");
13
+ const fs_1 = __importDefault(require("fs"));
14
+ const path_1 = __importDefault(require("path"));
15
+ function debugLog(message) {
16
+ try {
17
+ const debugPath = path_1.default.join(__dirname, "../debug.log");
18
+ fs_1.default.appendFileSync(debugPath, `${new Date().toISOString()}: ${message}\n`);
19
+ }
20
+ catch (e) { }
21
+ }
22
+ class OpenApiMcpServer {
23
+ fastMCP;
24
+ httpClient;
25
+ parsedSpecs = new Map();
26
+ toolRegistry = new Map();
27
+ authConfig = {};
28
+ config;
29
+ envPath;
30
+ lastEnvMtimeMs = null;
31
+ envWatcher;
32
+ envWatchTimeout;
33
+ resourceCounter = 0;
34
+ promptRegistrar;
35
+ toolRegistrar;
36
+ constructor(config) {
37
+ this.config = config;
38
+ this.httpClient = new http_client_1.HttpClient();
39
+ this.envPath = path_1.default.join(this.config.specsPath, ".env");
40
+ this.fastMCP = new fastmcp_1.FastMCP({
41
+ name: "SpecRun",
42
+ version: "1.0.0",
43
+ instructions: "I SpecRun OpenAPI specifications to MCP tools. I load .json, .yaml, and .yml files containing OpenAPI specs from a specified folder and automatically generate tools for each endpoint. Authentication is handled via environment variables with naming patterns like {API_NAME}_API_KEY.",
44
+ });
45
+ this.toolRegistrar = new tools_1.ToolRegistrar({
46
+ fastMCP: this.fastMCP,
47
+ toolRegistry: this.toolRegistry,
48
+ httpClient: this.httpClient,
49
+ getAuthConfig: () => this.authConfig,
50
+ refreshEnvConfigIfChanged: this.refreshEnvConfigIfChanged.bind(this),
51
+ createResponseResourceContent: this.createResponseResourceContent.bind(this),
52
+ });
53
+ this.promptRegistrar = new prompts_1.PromptRegistrar({
54
+ fastMCP: this.fastMCP,
55
+ toolRegistry: this.toolRegistry,
56
+ });
57
+ this.registerResponseResourceSupport();
58
+ this.setupServerEvents();
59
+ this.toolRegistrar.registerBatchDispatcherTool();
60
+ this.promptRegistrar.registerPrompts();
61
+ }
62
+ setupServerEvents() {
63
+ this.fastMCP.on("connect", (event) => {
64
+ this.authConfig = (0, auth_1.loadAuthConfig)(this.config.specsPath);
65
+ this.lastEnvMtimeMs = this.getEnvMtimeMs();
66
+ });
67
+ this.fastMCP.on("disconnect", (event) => { });
68
+ }
69
+ async start() {
70
+ // Only log to console if not in stdio mode (which would interfere with MCP protocol)
71
+ const isStdioMode = this.config.transportType !== "httpStream";
72
+ debugLog(`Starting SpecRun with specsPath: ${this.config.specsPath}`);
73
+ if (!isStdioMode) {
74
+ console.log("Starting SpecRun...");
75
+ }
76
+ // Load authentication config
77
+ await this.loadSpecs();
78
+ this.startEnvWatcher();
79
+ debugLog(`After loading specs: ${this.parsedSpecs.size} specs, ${this.getTotalToolsCount()} tools`);
80
+ // Start FastMCP server AFTER all tools are registered
81
+ const transportConfig = this.config.transportType === "httpStream" && this.config.port
82
+ ? {
83
+ transportType: "httpStream",
84
+ httpStream: { port: this.config.port },
85
+ }
86
+ : { transportType: "stdio" };
87
+ this.fastMCP.start(transportConfig);
88
+ if (!isStdioMode) {
89
+ console.log(`SpecRun started. Loaded ${this.parsedSpecs.size} API specifications with ${this.getTotalToolsCount()} tools from ${this.config.specsPath}.`);
90
+ }
91
+ }
92
+ async loadSpecs() {
93
+ const existingFiles = await this.getExistingFiles();
94
+ (0, auth_1.ensureEnvKeysForSpecs)(this.config.specsPath, existingFiles);
95
+ this.authConfig = (0, auth_1.loadAuthConfig)(this.config.specsPath);
96
+ (0, openapi_parser_1.updateSpecServerUrls)(existingFiles, process.env);
97
+ this.lastEnvMtimeMs = this.getEnvMtimeMs();
98
+ await this.loadExistingSpecs(existingFiles);
99
+ }
100
+ async stop() {
101
+ if (this.envWatchTimeout) {
102
+ clearTimeout(this.envWatchTimeout);
103
+ this.envWatchTimeout = undefined;
104
+ }
105
+ if (this.envWatcher) {
106
+ this.envWatcher.close();
107
+ this.envWatcher = undefined;
108
+ }
109
+ }
110
+ async loadExistingSpecs(existingFiles) {
111
+ debugLog(`Found ${existingFiles.length} existing files: ${existingFiles.join(", ")}`);
112
+ for (const filePath of existingFiles) {
113
+ debugLog(`Processing file: ${filePath}`);
114
+ await this.handleSpecAdded(filePath);
115
+ }
116
+ }
117
+ async getExistingFiles() {
118
+ try {
119
+ debugLog(`Reading directory: ${this.config.specsPath}`);
120
+ // Ensure directory exists
121
+ try {
122
+ await fs_1.default.promises.access(this.config.specsPath);
123
+ }
124
+ catch {
125
+ await fs_1.default.promises.mkdir(this.config.specsPath, { recursive: true });
126
+ return [];
127
+ }
128
+ const files = await fs_1.default.promises.readdir(this.config.specsPath);
129
+ debugLog(`Found files: ${files.join(", ")}`);
130
+ const filteredFiles = files.filter((file) => {
131
+ const isValid = (0, openapi_parser_1.isOpenAPIFile)(file);
132
+ debugLog(`File ${file}: isOpenAPIFile = ${isValid}`);
133
+ return isValid;
134
+ });
135
+ const fullPaths = filteredFiles.map((file) => path_1.default.join(this.config.specsPath, file));
136
+ debugLog(`Returning files: ${fullPaths.join(", ")}`);
137
+ return fullPaths;
138
+ }
139
+ catch (error) {
140
+ debugLog(`Error reading directory ${this.config.specsPath}: ${error}`);
141
+ return [];
142
+ }
143
+ }
144
+ async handleSpecAdded(filePath) {
145
+ debugLog(`Attempting to parse: ${filePath}`);
146
+ const parsedSpec = await (0, openapi_parser_1.parseOpenApiSpec)(filePath);
147
+ if (parsedSpec) {
148
+ debugLog(`Successfully parsed ${filePath}: ${parsedSpec.tools.length} tools`);
149
+ this.parsedSpecs.set(filePath, parsedSpec);
150
+ this.toolRegistrar.registerToolsFromSpec(parsedSpec);
151
+ }
152
+ else {
153
+ debugLog(`Failed to parse: ${filePath}`);
154
+ }
155
+ }
156
+ getEnvMtimeMs() {
157
+ try {
158
+ return fs_1.default.statSync(this.envPath).mtimeMs;
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ }
164
+ refreshEnvConfigIfChanged(force = false) {
165
+ const currentMtimeMs = this.getEnvMtimeMs();
166
+ if (!force && currentMtimeMs === this.lastEnvMtimeMs) {
167
+ return;
168
+ }
169
+ this.authConfig = (0, auth_1.loadAuthConfig)(this.config.specsPath);
170
+ (0, openapi_parser_1.updateSpecServerUrls)(Array.from(this.parsedSpecs.keys()), process.env);
171
+ this.updateToolBaseUrlsFromEnv();
172
+ this.lastEnvMtimeMs = currentMtimeMs;
173
+ }
174
+ updateToolBaseUrlsFromEnv() {
175
+ for (const spec of this.parsedSpecs.values()) {
176
+ const newBaseUrl = (0, openapi_parser_1.resolveServerUrl)(spec.apiName, process.env);
177
+ if (!newBaseUrl) {
178
+ continue;
179
+ }
180
+ const resolvedBaseUrl = this.resolveToolBaseUrl(spec, newBaseUrl);
181
+ for (const tool of spec.tools) {
182
+ tool.baseUrl = resolvedBaseUrl;
183
+ }
184
+ for (const entry of this.toolRegistry.values()) {
185
+ if (entry.spec.apiName === spec.apiName) {
186
+ entry.tool.baseUrl = resolvedBaseUrl;
187
+ }
188
+ }
189
+ }
190
+ }
191
+ resolveToolBaseUrl(spec, newBaseUrl) {
192
+ const swaggerSpec = spec.spec;
193
+ if (swaggerSpec && swaggerSpec.swagger === "2.0") {
194
+ try {
195
+ const parsed = new URL(newBaseUrl);
196
+ const hasPath = parsed.pathname && parsed.pathname !== "/";
197
+ if (!hasPath && typeof swaggerSpec.basePath === "string") {
198
+ const basePath = swaggerSpec.basePath.trim();
199
+ if (basePath) {
200
+ parsed.pathname = basePath;
201
+ return parsed.toString().replace(/\/$/, "");
202
+ }
203
+ }
204
+ }
205
+ catch {
206
+ return newBaseUrl;
207
+ }
208
+ }
209
+ if (swaggerSpec && swaggerSpec.openapi) {
210
+ return this.appendOpenApiBasePath(newBaseUrl, swaggerSpec);
211
+ }
212
+ return newBaseUrl;
213
+ }
214
+ appendOpenApiBasePath(baseUrl, spec) {
215
+ const basePath = this.getOpenApiBasePath(spec);
216
+ if (!basePath) {
217
+ return baseUrl;
218
+ }
219
+ try {
220
+ const parsed = new URL(baseUrl);
221
+ const hasPath = parsed.pathname && parsed.pathname !== "/";
222
+ if (hasPath) {
223
+ return baseUrl;
224
+ }
225
+ parsed.pathname = basePath;
226
+ return parsed.toString().replace(/\/$/, "");
227
+ }
228
+ catch {
229
+ return baseUrl;
230
+ }
231
+ }
232
+ getOpenApiBasePath(spec) {
233
+ const raw = (typeof spec?.basePath === "string" && spec.basePath) || "";
234
+ const trimmed = String(raw).trim();
235
+ if (!trimmed) {
236
+ return null;
237
+ }
238
+ return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
239
+ }
240
+ startEnvWatcher() {
241
+ if (this.envWatcher) {
242
+ return;
243
+ }
244
+ try {
245
+ this.envWatcher = fs_1.default.watch(this.envPath, (eventType) => {
246
+ if (eventType !== "change" && eventType !== "rename") {
247
+ return;
248
+ }
249
+ if (this.envWatchTimeout) {
250
+ clearTimeout(this.envWatchTimeout);
251
+ }
252
+ this.envWatchTimeout = setTimeout(() => {
253
+ this.refreshEnvConfigIfChanged(true);
254
+ }, 50);
255
+ });
256
+ }
257
+ catch {
258
+ // Watching is best-effort; fall back to refresh-on-request only.
259
+ }
260
+ }
261
+ registerResponseResourceSupport() {
262
+ this.fastMCP.addResource({
263
+ uri: "specrun://responses",
264
+ name: "SpecRun Responses",
265
+ description: "SpecRun response resources",
266
+ mimeType: "application/json",
267
+ load: async () => ({
268
+ text: JSON.stringify({
269
+ message: "SpecRun response resources are available by URI.",
270
+ }),
271
+ }),
272
+ });
273
+ }
274
+ async createResponseResourceContent(name, description, payload) {
275
+ const uri = `specrun://responses/${this.createResourceId()}`;
276
+ this.fastMCP.addResource({
277
+ uri,
278
+ name,
279
+ description,
280
+ mimeType: "application/json",
281
+ load: async () => ({
282
+ text: JSON.stringify(payload, null, 2),
283
+ }),
284
+ });
285
+ return {
286
+ type: "resource",
287
+ resource: await this.fastMCP.embedded(uri),
288
+ };
289
+ }
290
+ createResourceId() {
291
+ this.resourceCounter += 1;
292
+ return `${Date.now()}-${this.resourceCounter}-${Math.floor(Math.random() * 1_000_000)}`;
293
+ }
294
+ getTotalToolsCount() {
295
+ return Array.from(this.parsedSpecs.values()).reduce((total, spec) => total + spec.tools.length, 0);
296
+ }
297
+ getLoadedSpecs() {
298
+ return Array.from(this.parsedSpecs.values());
299
+ }
300
+ getAuthConfig() {
301
+ return this.authConfig;
302
+ }
303
+ }
304
+ exports.OpenApiMcpServer = OpenApiMcpServer;
305
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { FastMCP } from "fastmcp";
2
+ import { z } from "zod";
3
+ import { ParsedSpec, GeneratedTool, AuthConfig } from "./types";
4
+ import { HttpClient } from "./utils/http-client";
5
+ type ToolRegistryEntry = {
6
+ spec: ParsedSpec;
7
+ tool: GeneratedTool;
8
+ schema: z.ZodObject<any>;
9
+ };
10
+ type ToolRegistry = Map<string, ToolRegistryEntry>;
11
+ type ToolRegistrarOptions = {
12
+ fastMCP: FastMCP;
13
+ toolRegistry: ToolRegistry;
14
+ httpClient: HttpClient;
15
+ getAuthConfig: () => AuthConfig;
16
+ refreshEnvConfigIfChanged: () => void;
17
+ createResponseResourceContent: (name: string, description: string, payload: unknown) => Promise<{
18
+ type: "resource";
19
+ resource: any;
20
+ }>;
21
+ };
22
+ export declare class ToolRegistrar {
23
+ private static readonly largeBatchThreshold;
24
+ private static readonly largeBatchTokenTtlMs;
25
+ private fastMCP;
26
+ private toolRegistry;
27
+ private httpClient;
28
+ private getAuthConfig;
29
+ private refreshEnvConfigIfChanged;
30
+ private createResponseResourceContent;
31
+ private largeBatchConfirmations;
32
+ constructor(options: ToolRegistrarOptions);
33
+ registerToolsFromSpec(spec: ParsedSpec): void;
34
+ registerBatchDispatcherTool(): void;
35
+ private normalizeToolName;
36
+ private registerTool;
37
+ private issueLargeBatchToken;
38
+ private isLargeBatchConfirmed;
39
+ private buildZodSchema;
40
+ private openAPISchemaToZod;
41
+ }
42
+ export {};
43
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,UAAU,EACV,aAAa,EAGb,UAAU,EACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CAC1B,CAAC;AAEF,KAAK,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAEnD,KAAK,oBAAoB,GAAG;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,MAAM,UAAU,CAAC;IAChC,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,6BAA6B,EAAE,CAC7B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,KACb,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;CACnD,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAiB;IAC7D,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,yBAAyB,CAAa;IAC9C,OAAO,CAAC,6BAA6B,CAAwD;IAC7F,OAAO,CAAC,uBAAuB,CAG7B;gBAEU,OAAO,EAAE,oBAAoB;IAUzC,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAM7C,2BAA2B,IAAI,IAAI;IAwInC,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,kBAAkB;CAkD3B"}
package/dist/tools.js ADDED
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ToolRegistrar = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const zod_1 = require("zod");
6
+ class ToolRegistrar {
7
+ static largeBatchThreshold = 200;
8
+ static largeBatchTokenTtlMs = 5 * 60 * 1000;
9
+ fastMCP;
10
+ toolRegistry;
11
+ httpClient;
12
+ getAuthConfig;
13
+ refreshEnvConfigIfChanged;
14
+ createResponseResourceContent;
15
+ largeBatchConfirmations;
16
+ constructor(options) {
17
+ this.fastMCP = options.fastMCP;
18
+ this.toolRegistry = options.toolRegistry;
19
+ this.httpClient = options.httpClient;
20
+ this.getAuthConfig = options.getAuthConfig;
21
+ this.refreshEnvConfigIfChanged = options.refreshEnvConfigIfChanged;
22
+ this.createResponseResourceContent = options.createResponseResourceContent;
23
+ this.largeBatchConfirmations = new Map();
24
+ }
25
+ registerToolsFromSpec(spec) {
26
+ for (const tool of spec.tools) {
27
+ this.registerTool(spec, tool);
28
+ }
29
+ }
30
+ registerBatchDispatcherTool() {
31
+ const batchSchema = zod_1.z.object({
32
+ toolName: zod_1.z.string().min(1),
33
+ items: zod_1.z.array(zod_1.z.any()).min(1),
34
+ failFast: zod_1.z.boolean().optional(),
35
+ confirmLargeBatch: zod_1.z.boolean().optional(),
36
+ confirmLargeBatchToken: zod_1.z.string().min(1).optional(),
37
+ });
38
+ this.fastMCP.addTool({
39
+ name: "specrun_batch",
40
+ description: "Run any SpecRun tool in batch with multiple inputs",
41
+ parameters: batchSchema,
42
+ execute: async (args) => {
43
+ this.refreshEnvConfigIfChanged();
44
+ const rawToolName = String(args.toolName || "");
45
+ const toolName = this.normalizeToolName(rawToolName);
46
+ const entry = this.toolRegistry.get(toolName);
47
+ if (!entry) {
48
+ const resource = await this.createResponseResourceContent("SpecRun Batch Error", "Batch execution error", {
49
+ toolName: rawToolName,
50
+ normalizedToolName: toolName,
51
+ error: `Unknown tool: ${toolName}`,
52
+ });
53
+ return {
54
+ content: [resource],
55
+ };
56
+ }
57
+ const items = Array.isArray(args.items) ? args.items : [];
58
+ const failFast = Boolean(args.failFast);
59
+ const confirmLargeBatch = Boolean(args.confirmLargeBatch);
60
+ const confirmLargeBatchToken = typeof args.confirmLargeBatchToken === "string"
61
+ ? args.confirmLargeBatchToken
62
+ : "";
63
+ if (items.length > ToolRegistrar.largeBatchThreshold &&
64
+ !this.isLargeBatchConfirmed(confirmLargeBatch, confirmLargeBatchToken, toolName, items.length)) {
65
+ const token = this.issueLargeBatchToken(toolName, items.length);
66
+ const resource = await this.createResponseResourceContent("SpecRun Batch Confirmation Required", "Batch execution confirmation required", {
67
+ toolName,
68
+ count: items.length,
69
+ threshold: ToolRegistrar.largeBatchThreshold,
70
+ confirmLargeBatchToken: token,
71
+ confirmLargeBatchTokenTtlMs: ToolRegistrar.largeBatchTokenTtlMs,
72
+ message: "Batch execution over 200 items requires user confirmation. Re-run with confirmLargeBatch: true and confirmLargeBatchToken to proceed.",
73
+ });
74
+ return {
75
+ content: [
76
+ {
77
+ type: "text",
78
+ text: "Confirmation required: ask the user to approve this batch, then retry with confirmLargeBatch: true and the provided confirmLargeBatchToken.",
79
+ },
80
+ resource,
81
+ ],
82
+ isError: true,
83
+ };
84
+ }
85
+ const results = [];
86
+ for (let index = 0; index < items.length; index += 1) {
87
+ const itemArgs = items[index];
88
+ const parsedArgs = entry.schema.safeParse(itemArgs);
89
+ if (!parsedArgs.success) {
90
+ results.push({
91
+ index,
92
+ error: parsedArgs.error.message,
93
+ });
94
+ if (failFast) {
95
+ break;
96
+ }
97
+ continue;
98
+ }
99
+ const context = {
100
+ apiName: entry.spec.apiName,
101
+ tool: entry.tool,
102
+ authConfig: this.getAuthConfig()[entry.spec.apiName],
103
+ };
104
+ try {
105
+ const output = await this.httpClient.executeRequest(context, parsedArgs.data);
106
+ results.push({ index, result: output });
107
+ }
108
+ catch (error) {
109
+ const message = error instanceof Error ? error.message : String(error);
110
+ results.push({ index, error: message });
111
+ if (failFast) {
112
+ break;
113
+ }
114
+ }
115
+ }
116
+ const resource = await this.createResponseResourceContent(`SpecRun Batch ${toolName}`, `Batch responses for ${toolName}`, {
117
+ toolName,
118
+ count: items.length,
119
+ results,
120
+ });
121
+ return {
122
+ content: [resource],
123
+ };
124
+ },
125
+ });
126
+ }
127
+ normalizeToolName(value) {
128
+ const trimmed = value.trim();
129
+ const prefixes = ["mcp_specrun_", "specrun_"];
130
+ for (const prefix of prefixes) {
131
+ if (trimmed.startsWith(prefix)) {
132
+ return trimmed.slice(prefix.length);
133
+ }
134
+ }
135
+ return trimmed;
136
+ }
137
+ registerTool(spec, tool) {
138
+ const schema = this.buildZodSchema(tool);
139
+ this.toolRegistry.set(tool.name, { spec, tool, schema });
140
+ this.fastMCP.addTool({
141
+ name: tool.name,
142
+ description: tool.description,
143
+ parameters: schema,
144
+ execute: async (args) => {
145
+ this.refreshEnvConfigIfChanged();
146
+ const context = {
147
+ apiName: spec.apiName,
148
+ tool,
149
+ authConfig: this.getAuthConfig()[spec.apiName],
150
+ };
151
+ const result = await this.httpClient.executeRequest(context, args);
152
+ const resource = await this.createResponseResourceContent(`SpecRun Response ${tool.name}`, `Response for ${tool.name}`, result);
153
+ return {
154
+ content: [resource],
155
+ };
156
+ },
157
+ });
158
+ }
159
+ issueLargeBatchToken(toolName, count) {
160
+ const token = (0, crypto_1.randomUUID)();
161
+ this.largeBatchConfirmations.set(token, {
162
+ toolName,
163
+ count,
164
+ expiresAt: Date.now() + ToolRegistrar.largeBatchTokenTtlMs,
165
+ });
166
+ return token;
167
+ }
168
+ isLargeBatchConfirmed(confirmLargeBatch, confirmLargeBatchToken, toolName, count) {
169
+ if (!confirmLargeBatch || !confirmLargeBatchToken) {
170
+ return false;
171
+ }
172
+ const record = this.largeBatchConfirmations.get(confirmLargeBatchToken);
173
+ if (!record) {
174
+ return false;
175
+ }
176
+ if (record.expiresAt <= Date.now()) {
177
+ this.largeBatchConfirmations.delete(confirmLargeBatchToken);
178
+ return false;
179
+ }
180
+ if (record.toolName !== toolName || record.count !== count) {
181
+ return false;
182
+ }
183
+ this.largeBatchConfirmations.delete(confirmLargeBatchToken);
184
+ return true;
185
+ }
186
+ buildZodSchema(tool) {
187
+ const schemaFields = {};
188
+ for (const param of tool.parameters) {
189
+ let fieldSchema = this.openAPISchemaToZod(param.schema);
190
+ if (param.description) {
191
+ fieldSchema = fieldSchema.describe(param.description);
192
+ }
193
+ if (!param.required) {
194
+ fieldSchema = fieldSchema.optional();
195
+ }
196
+ schemaFields[param.name] = fieldSchema;
197
+ }
198
+ if (tool.requestBody) {
199
+ schemaFields.body = zod_1.z.any().optional().describe("Request body data");
200
+ }
201
+ const schema = zod_1.z.object(schemaFields);
202
+ return tool.requestBody ? schema.passthrough() : schema;
203
+ }
204
+ openAPISchemaToZod(schema) {
205
+ if (!schema || typeof schema !== "object") {
206
+ return zod_1.z.any();
207
+ }
208
+ switch (schema.type) {
209
+ case "string":
210
+ return zod_1.z.string();
211
+ case "number":
212
+ return zod_1.z.number();
213
+ case "integer":
214
+ return zod_1.z.number().int();
215
+ case "boolean":
216
+ return zod_1.z.boolean();
217
+ case "array":
218
+ return zod_1.z.array(this.openAPISchemaToZod(schema.items || {}));
219
+ case "object": {
220
+ const properties = schema.properties || {};
221
+ const required = new Set(schema.required || []);
222
+ const shape = {};
223
+ for (const [key, value] of Object.entries(properties)) {
224
+ let propertySchema = this.openAPISchemaToZod(value);
225
+ if (!required.has(key)) {
226
+ propertySchema = propertySchema.optional();
227
+ }
228
+ shape[key] = propertySchema;
229
+ }
230
+ let objectSchema = zod_1.z.object(shape);
231
+ const additional = schema.additionalProperties;
232
+ if (additional === false) {
233
+ objectSchema = objectSchema.strict();
234
+ }
235
+ else if (additional === true || additional === undefined) {
236
+ objectSchema = objectSchema.loose();
237
+ }
238
+ else if (typeof additional === "object") {
239
+ objectSchema = objectSchema.catchall(this.openAPISchemaToZod(additional));
240
+ }
241
+ return objectSchema;
242
+ }
243
+ default:
244
+ return zod_1.z.any();
245
+ }
246
+ }
247
+ }
248
+ exports.ToolRegistrar = ToolRegistrar;
249
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}