MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / execute

Method execute

src/tools/api/openapi-digest.ts:46–145  ·  view source on GitHub ↗
(a: z.infer<typeof Args>, _ctx: ToolContext)

Source from the content-addressed store, hash-verified

44 isReadOnly = true; isDestructive = false; argsSchema = Args;
45
46 async execute(a: z.infer<typeof Args>, _ctx: ToolContext): Promise<ToolResult> {
47 let raw: string;
48 try {
49 if (/^https?:\/\//i.test(a.source)) {
50 const res = await proxyFetch(a.source, { redirect: 'follow' });
51 if (!res.ok) return { content: `Failed to fetch spec: HTTP ${res.status}`, isError: true };
52 raw = await res.text();
53 } else {
54 raw = await fs.readFile(a.source, 'utf8');
55 }
56 } catch (e: any) {
57 return { content: `Could not read spec source: ${e.message}`, isError: true };
58 }
59
60 let spec: any;
61 try {
62 spec = a.source.trim().endsWith('.json') || raw.trimStart().startsWith('{')
63 ? JSON.parse(raw)
64 : yaml.load(raw);
65 } catch (e: any) {
66 return { content: `Spec is not valid JSON/YAML: ${e.message}`, isError: true };
67 }
68
69 if (!spec || (!spec.paths && !spec.swagger && !spec.openapi)) {
70 return { content: 'This does not look like an OpenAPI/Swagger document (no paths/openapi/swagger fields).', isError: true };
71 }
72
73 const version = spec.openapi ?? spec.swagger ?? 'unknown';
74 const title = spec.info?.title ?? '(untitled)';
75 const servers: string[] = (spec.servers ?? []).map((s: any) => s.url).filter(Boolean);
76 const securitySchemes = spec.components?.securitySchemes ?? spec.securityDefinitions ?? {};
77
78 const endpoints: EndpointInfo[] = [];
79 const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];
80 for (const [p, item] of Object.entries<any>(spec.paths ?? {})) {
81 if (a.filter && !p.includes(a.filter)) continue;
82 for (const m of methods) {
83 const op = item?.[m];
84 if (!op) continue;
85 const params: ParamInfo[] = [...(item.parameters ?? []), ...(op.parameters ?? [])].map((pr: any) => ({
86 name: pr.name, in: pr.in, required: !!pr.required,
87 type: schemaLabel(pr.schema ?? pr),
88 }));
89 let body: string | undefined;
90 if (op.requestBody) {
91 const content = op.requestBody.content ?? {};
92 const first = content['application/json'] ?? Object.values(content)[0];
93 body = schemaLabel((first as any)?.schema);
94 } else if (m === 'post' || m === 'put' || m === 'patch') {
95 // Swagger 2.0 carries body in parameters with in:'body'.
96 const b = params.find(pr => pr.in === 'body');
97 if (b) body = b.type;
98 }
99 const responses = op.responses ?? {};
100 const okKey = Object.keys(responses).find(k => k.startsWith('2')) ?? 'default';
101 const okResp = responses[okKey];
102 const okContent = okResp?.content?.['application/json'] ?? (okResp?.content ? Object.values(okResp.content)[0] : undefined);
103 const success = schemaLabel((okContent as any)?.schema ?? okResp?.schema);

Callers

nothing calls this directly

Calls 4

proxyFetchFunction · 0.85
schemaLabelFunction · 0.85
loadMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected