mcp-use 2.0.0-beta.34 → 2.0.0-beta.36
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/bin.js +1 -3
- package/dist/{chunk-PPQL2WHL.js → chunk-GX6PGIEO.js} +32 -142
- package/dist/chunk-JMDHTN6N.js +1 -0
- package/dist/chunk-OJF6B5EU.js +1 -0
- package/dist/chunk-PSKSL567.js +1 -0
- package/dist/chunk-WYBJYZJB.js +1 -0
- package/dist/chunk-Y26DNVWA.js +3 -0
- package/dist/chunk-ZMU5USAZ.js +1 -0
- package/dist/index.js +9 -3100
- package/dist/internal/resource-completion.js +1 -6
- package/dist/landing-handler-TG6LVQBI.js +1 -0
- package/dist/landing.js +1 -6
- package/dist/mcp-proxy-NGJ4JADQ.js +2 -0
- package/dist/next/index.js +1 -171
- package/dist/node-bridge.js +1 -150
- package/dist/oauth/auth0.js +1 -60
- package/dist/oauth/better-auth.js +1 -75
- package/dist/oauth/clerk.js +1 -69
- package/dist/oauth/index.js +1 -26
- package/dist/oauth/keycloak.js +1 -93
- package/dist/oauth/supabase.js +1 -100
- package/dist/oauth/workos.js +1 -76
- package/dist/openapi/index.js +1 -6
- package/dist/public-route-DAQJGS6K.js +1 -0
- package/package.json +7 -6
- package/dist/chunk-DFFP6QPR.js +0 -37
- package/dist/chunk-HDV7K2TE.js +0 -97
- package/dist/chunk-HNNQJLD5.js +0 -383
- package/dist/chunk-QCIREWRS.js +0 -64
- package/dist/chunk-QKJJ6DWK.js +0 -184
- package/dist/chunk-YF5X7FYF.js +0 -517
- package/dist/landing-handler-QEH2ATIR.js +0 -36
- package/dist/mcp-proxy-JK7IC5CR.js +0 -281
- package/dist/public-route-BAMZRI4R.js +0 -8
package/dist/bin.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/bin.ts
|
|
4
|
-
await import("@mcp-use/cli");
|
|
2
|
+
var{main}=await import("@mcp-use/cli");main(process.argv.slice(2),{frameworkVersion:"2.0.0-beta.35"}).then(code=>{process.exitCode=code},error=>{console.error(error instanceof Error?error.message:String(error)),process.exitCode=1});
|
|
@@ -1,68 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return `cursor://anysphere.cursor-deeplink/mcp/install?config=${encodeURIComponent(base64Config)}&name=${encodeURIComponent(sanitizedName)}`;
|
|
17
|
-
}
|
|
18
|
-
function generateVSCodeDeepLink(url, name) {
|
|
19
|
-
const config = {
|
|
20
|
-
url,
|
|
21
|
-
name: sanitizeServerName(name),
|
|
22
|
-
type: "http"
|
|
23
|
-
};
|
|
24
|
-
const configJson = JSON.stringify(config);
|
|
25
|
-
const urlEncodedConfig = encodeURIComponent(configJson);
|
|
26
|
-
return `vscode:mcp/install?${urlEncodedConfig}`;
|
|
27
|
-
}
|
|
28
|
-
function generateVSCodeInsidersDeepLink(url, name) {
|
|
29
|
-
const config = {
|
|
30
|
-
url,
|
|
31
|
-
name: sanitizeServerName(name),
|
|
32
|
-
type: "http"
|
|
33
|
-
};
|
|
34
|
-
const configJson = JSON.stringify(config);
|
|
35
|
-
const urlEncodedConfig = encodeURIComponent(configJson);
|
|
36
|
-
return `vscode-insiders:mcp/install?${urlEncodedConfig}`;
|
|
37
|
-
}
|
|
38
|
-
function generateClaudeCommand(url, name) {
|
|
39
|
-
const sanitizedName = sanitizeServerName(name);
|
|
40
|
-
const quotedUrl = `'${url.replace(/'/g, "'\\''")}'`;
|
|
41
|
-
return `claude mcp add --transport http "${sanitizedName}" ${quotedUrl}`;
|
|
42
|
-
}
|
|
43
|
-
var MANUFACT_INSPECTOR_ORIGIN = "https://inspector.manufact.com";
|
|
44
|
-
function getManufactInspectorUrl(serverUrl) {
|
|
45
|
-
const params = new URLSearchParams({
|
|
46
|
-
autoConnect: serverUrl,
|
|
47
|
-
tab: "chat"
|
|
48
|
-
});
|
|
49
|
-
return `${MANUFACT_INSPECTOR_ORIGIN}/inspector?${params.toString()}`;
|
|
50
|
-
}
|
|
51
|
-
var LOGO_SVG_PATHS = {
|
|
52
|
-
path1: "M105.933 0C164.437 0.000115889 211.865 47.607 211.865 106.333C211.865 131.828 210.494 158.401 221.068 181.6L228.976 198.947C243.585 230.997 269.266 256.7 301.304 271.336L316.156 278.121C340.143 289.079 367.695 287.335 394.067 287.335C452.572 287.335 500 334.942 500 393.668C500 452.394 452.572 500.001 394.067 500.001C335.563 500.001 288.135 452.394 288.135 393.668C288.135 368.974 289.241 343.275 278.992 320.807L270.587 302.38C255.949 270.289 230.214 244.565 198.118 229.939L180.164 221.758C157.282 211.331 131.078 212.666 105.933 212.666C47.4278 212.666 4.92992e-05 165.059 0 106.333C0 47.607 47.4278 0 105.933 0Z",
|
|
53
|
-
circle: { cx: 100.426, cy: 399.575, r: 100.426 },
|
|
54
|
-
path2: "M500 100.426C500 155.889 455.037 200.851 399.574 200.851C344.11 200.851 299.148 155.889 299.148 100.426C299.148 44.962 344.11 0 399.574 0C455.037 0 500 44.962 500 100.426Z"
|
|
55
|
-
};
|
|
56
|
-
var LINE_INTERSECTION_PATH = "M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z";
|
|
57
|
-
function getMeshGradientScript() {
|
|
58
|
-
const VERT = `#version 300 es
|
|
1
|
+
function escapeHtml(text){return text.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function serializeScriptJson(value){return JSON.stringify(value).replace(/</g,"\\u003c").replace(/>/g,"\\u003e")}function sanitizeServerName(name){return name.replace(/[^a-zA-Z0-9-_]/g,"_").toLowerCase()}function generateCursorDeepLink(url,name){let configJson=JSON.stringify({url}),base64Config=typeof Buffer<"u"?Buffer.from(configJson).toString("base64"):btoa(configJson),sanitizedName=sanitizeServerName(name);return`cursor://anysphere.cursor-deeplink/mcp/install?config=${encodeURIComponent(base64Config)}&name=${encodeURIComponent(sanitizedName)}`}function generateVSCodeDeepLink(url,name){let config={url,name:sanitizeServerName(name),type:"http"},configJson=JSON.stringify(config);return`vscode:mcp/install?${encodeURIComponent(configJson)}`}function generateVSCodeInsidersDeepLink(url,name){let config={url,name:sanitizeServerName(name),type:"http"},configJson=JSON.stringify(config);return`vscode-insiders:mcp/install?${encodeURIComponent(configJson)}`}function generateClaudeCommand(url,name){let sanitizedName=sanitizeServerName(name),quotedUrl=`'${url.replace(/'/g,"'\\''")}'`;return`claude mcp add --transport http "${sanitizedName}" ${quotedUrl}`}var MANUFACT_INSPECTOR_ORIGIN="https://inspector.manufact.com";function getManufactInspectorUrl(serverUrl){let params=new URLSearchParams({autoConnect:serverUrl,tab:"chat"});return`${MANUFACT_INSPECTOR_ORIGIN}/inspector?${params.toString()}`}var LOGO_SVG_PATHS={path1:"M105.933 0C164.437 0.000115889 211.865 47.607 211.865 106.333C211.865 131.828 210.494 158.401 221.068 181.6L228.976 198.947C243.585 230.997 269.266 256.7 301.304 271.336L316.156 278.121C340.143 289.079 367.695 287.335 394.067 287.335C452.572 287.335 500 334.942 500 393.668C500 452.394 452.572 500.001 394.067 500.001C335.563 500.001 288.135 452.394 288.135 393.668C288.135 368.974 289.241 343.275 278.992 320.807L270.587 302.38C255.949 270.289 230.214 244.565 198.118 229.939L180.164 221.758C157.282 211.331 131.078 212.666 105.933 212.666C47.4278 212.666 4.92992e-05 165.059 0 106.333C0 47.607 47.4278 0 105.933 0Z",circle:{cx:100.426,cy:399.575,r:100.426},path2:"M500 100.426C500 155.889 455.037 200.851 399.574 200.851C344.11 200.851 299.148 155.889 299.148 100.426C299.148 44.962 344.11 0 399.574 0C455.037 0 500 44.962 500 100.426Z"},LINE_INTERSECTION_PATH="M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z";function getMeshGradientScript(){return`(function(){
|
|
2
|
+
var c=document.getElementById('mesh-bg');
|
|
3
|
+
if(!c)return;
|
|
4
|
+
var wrap=c.parentElement;
|
|
5
|
+
if(!wrap)return;
|
|
6
|
+
var gl=c.getContext('webgl2');
|
|
7
|
+
if(!gl)return;
|
|
8
|
+
function compileShader(typ,src){
|
|
9
|
+
var s=gl.createShader(typ);
|
|
10
|
+
gl.shaderSource(s,src);
|
|
11
|
+
gl.compileShader(s);
|
|
12
|
+
if(!gl.getShaderParameter(s,gl.COMPILE_STATUS)){console.error(gl.getShaderInfoLog(s));return null;}
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
var vs=compileShader(gl.VERTEX_SHADER,${JSON.stringify(`#version 300 es
|
|
59
16
|
in vec4 a_position;
|
|
60
17
|
out vec2 v_objectUV;
|
|
61
18
|
void main(){
|
|
62
19
|
gl_Position=a_position;
|
|
63
20
|
v_objectUV=a_position.xy*0.5;
|
|
64
|
-
}
|
|
65
|
-
|
|
21
|
+
}`)});
|
|
22
|
+
var fs=compileShader(gl.FRAGMENT_SHADER,${JSON.stringify(`#version 300 es
|
|
66
23
|
precision mediump float;
|
|
67
24
|
uniform float u_time;
|
|
68
25
|
uniform vec4 u_colors[4];
|
|
@@ -129,23 +86,7 @@ void main(){
|
|
|
129
86
|
color=mix(color,grainOC,.35*grainOS);
|
|
130
87
|
opacity+=.5*grainOS;
|
|
131
88
|
fragColor=vec4(color,clamp(opacity,0.,1.));
|
|
132
|
-
}
|
|
133
|
-
return `(function(){
|
|
134
|
-
var c=document.getElementById('mesh-bg');
|
|
135
|
-
if(!c)return;
|
|
136
|
-
var wrap=c.parentElement;
|
|
137
|
-
if(!wrap)return;
|
|
138
|
-
var gl=c.getContext('webgl2');
|
|
139
|
-
if(!gl)return;
|
|
140
|
-
function compileShader(typ,src){
|
|
141
|
-
var s=gl.createShader(typ);
|
|
142
|
-
gl.shaderSource(s,src);
|
|
143
|
-
gl.compileShader(s);
|
|
144
|
-
if(!gl.getShaderParameter(s,gl.COMPILE_STATUS)){console.error(gl.getShaderInfoLog(s));return null;}
|
|
145
|
-
return s;
|
|
146
|
-
}
|
|
147
|
-
var vs=compileShader(gl.VERTEX_SHADER,${JSON.stringify(VERT)});
|
|
148
|
-
var fs=compileShader(gl.FRAGMENT_SHADER,${JSON.stringify(FRAG)});
|
|
89
|
+
}`)});
|
|
149
90
|
if(!vs||!fs)return;
|
|
150
91
|
var prog=gl.createProgram();
|
|
151
92
|
gl.attachShader(prog,vs);
|
|
@@ -196,56 +137,10 @@ function draw(){
|
|
|
196
137
|
resize();
|
|
197
138
|
new ResizeObserver(resize).observe(wrap);
|
|
198
139
|
draw();
|
|
199
|
-
})()
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
name: protocolName,
|
|
204
|
-
title,
|
|
205
|
-
version,
|
|
206
|
-
url,
|
|
207
|
-
description,
|
|
208
|
-
tools,
|
|
209
|
-
prompts,
|
|
210
|
-
resources,
|
|
211
|
-
iconUrl,
|
|
212
|
-
iconType
|
|
213
|
-
} = options;
|
|
214
|
-
const name = title ?? protocolName;
|
|
215
|
-
const cursorDeepLink = generateCursorDeepLink(url, name);
|
|
216
|
-
const vscodeDeepLink = generateVSCodeDeepLink(url, name);
|
|
217
|
-
const vscodeInsidersDeepLink = generateVSCodeInsidersDeepLink(url, name);
|
|
218
|
-
const claudeCommand = generateClaudeCommand(url, name);
|
|
219
|
-
const manufactInspectorUrl = getManufactInspectorUrl(url);
|
|
220
|
-
const safeName = escapeHtml(name);
|
|
221
|
-
const safeDescription = description ? escapeHtml(description) : "";
|
|
222
|
-
const rawMetaDescription = description || `${name} MCP Server \u2014 Connect with Claude Code, Cursor, and VS Code. Model Context Protocol server.`;
|
|
223
|
-
const metaDescription = escapeHtml(rawMetaDescription);
|
|
224
|
-
const pageTitle = `${safeName} MCP Server \u2014 Connect with Claude Code, Cursor & VS Code`;
|
|
225
|
-
const jsonLd = serializeScriptJson({
|
|
226
|
-
"@context": "https://schema.org",
|
|
227
|
-
"@type": "SoftwareApplication",
|
|
228
|
-
name,
|
|
229
|
-
softwareVersion: version,
|
|
230
|
-
description: rawMetaDescription,
|
|
231
|
-
applicationCategory: "DeveloperApplication"
|
|
232
|
-
});
|
|
233
|
-
const normalizedTools = tools && tools.length > 0 ? tools.map((tool) => ({
|
|
234
|
-
name: tool.title ?? tool.name,
|
|
235
|
-
...tool.description !== void 0 && {
|
|
236
|
-
description: tool.description
|
|
237
|
-
}
|
|
238
|
-
})) : [];
|
|
239
|
-
const toolsListHtml = normalizedTools.length > 0 ? normalizedTools.map(
|
|
240
|
-
(t) => `<div class="spec-item"><code class="spec-name">${escapeHtml(t.name)}</code>${t.description ? `<p class="spec-desc">${escapeHtml(t.description)}</p>` : ""}</div>`
|
|
241
|
-
).join("\n") : "";
|
|
242
|
-
const promptsListHtml = prompts && prompts.length > 0 ? prompts.map(
|
|
243
|
-
(p) => `<div class="spec-item"><code class="spec-name">${escapeHtml(p.title ?? p.name)}</code>${p.description ? `<p class="spec-desc">${escapeHtml(p.description)}</p>` : ""}</div>`
|
|
244
|
-
).join("\n") : "";
|
|
245
|
-
const resourcesListHtml = resources && resources.length > 0 ? resources.map(
|
|
246
|
-
(r) => `<div class="spec-item"><code class="spec-uri">${escapeHtml(r.uri)}</code>${r.description ? `<p class="spec-desc">${escapeHtml(r.description)}</p>` : ""}</div>`
|
|
247
|
-
).join("\n") : "";
|
|
248
|
-
return `<!DOCTYPE html>
|
|
140
|
+
})();`}function generateLandingPage(options){let{name:protocolName,title,version,url,description,tools,prompts,resources,iconUrl,iconType}=options,name=title??protocolName,cursorDeepLink=generateCursorDeepLink(url,name),vscodeDeepLink=generateVSCodeDeepLink(url,name),vscodeInsidersDeepLink=generateVSCodeInsidersDeepLink(url,name),claudeCommand=generateClaudeCommand(url,name),manufactInspectorUrl=getManufactInspectorUrl(url),safeName=escapeHtml(name),safeDescription=description?escapeHtml(description):"",rawMetaDescription=description||`${name} MCP Server \u2014 Connect with Claude Code, Cursor, and VS Code. Model Context Protocol server.`,metaDescription=escapeHtml(rawMetaDescription),pageTitle=`${safeName} MCP Server \u2014 Connect with Claude Code, Cursor & VS Code`,jsonLd=serializeScriptJson({"@context":"https://schema.org","@type":"SoftwareApplication",name,softwareVersion:version,description:rawMetaDescription,applicationCategory:"DeveloperApplication"}),normalizedTools=tools&&tools.length>0?tools.map(tool=>({name:tool.title??tool.name,...tool.description!==void 0&&{description:tool.description}})):[],toolsListHtml=normalizedTools.length>0?normalizedTools.map(t=>`<div class="spec-item"><code class="spec-name">${escapeHtml(t.name)}</code>${t.description?`<p class="spec-desc">${escapeHtml(t.description)}</p>`:""}</div>`).join(`
|
|
141
|
+
`):"",promptsListHtml=prompts&&prompts.length>0?prompts.map(p=>`<div class="spec-item"><code class="spec-name">${escapeHtml(p.title??p.name)}</code>${p.description?`<p class="spec-desc">${escapeHtml(p.description)}</p>`:""}</div>`).join(`
|
|
142
|
+
`):"",resourcesListHtml=resources&&resources.length>0?resources.map(r=>`<div class="spec-item"><code class="spec-uri">${escapeHtml(r.uri)}</code>${r.description?`<p class="spec-desc">${escapeHtml(r.description)}</p>`:""}</div>`).join(`
|
|
143
|
+
`):"";return`<!DOCTYPE html>
|
|
249
144
|
<html lang="en">
|
|
250
145
|
<head>
|
|
251
146
|
<meta charset="UTF-8">
|
|
@@ -258,7 +153,7 @@ function generateLandingPage(options) {
|
|
|
258
153
|
<meta name="twitter:card" content="summary">
|
|
259
154
|
<meta name="twitter:title" content="${pageTitle}">
|
|
260
155
|
<meta name="twitter:description" content="${metaDescription}">
|
|
261
|
-
${iconUrl
|
|
156
|
+
${iconUrl?`<link rel="icon"${iconType?` type="${escapeHtml(iconType)}"`:""} href="${escapeHtml(iconUrl)}">`:""}
|
|
262
157
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
263
158
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
264
159
|
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
@@ -579,12 +474,12 @@ a:hover { text-decoration: underline; }
|
|
|
579
474
|
<div class="hero-gradient-wrap" id="hero-gradient-wrap">
|
|
580
475
|
<canvas id="mesh-bg" aria-hidden="true"></canvas>
|
|
581
476
|
<div class="hero-inner">
|
|
582
|
-
<div class="card-header ${iconUrl
|
|
583
|
-
${iconUrl
|
|
477
|
+
<div class="card-header ${iconUrl?"has-icon":""}">
|
|
478
|
+
${iconUrl?`<img src="${escapeHtml(iconUrl)}" alt="" class="hero-icon" width="64" height="64" />`:""}
|
|
584
479
|
<div class="hero-row">
|
|
585
480
|
<h1>${safeName} <span class="version">(v${escapeHtml(version)})</span></h1>
|
|
586
481
|
</div>
|
|
587
|
-
${safeDescription
|
|
482
|
+
${safeDescription?`<p class="hero-description">${safeDescription}</p>`:""}
|
|
588
483
|
<div class="hero-url-block">
|
|
589
484
|
<div class="url-block">
|
|
590
485
|
<div class="url-box" data-copy="${escapeHtml(url)}">${escapeHtml(url)}</div>
|
|
@@ -662,16 +557,16 @@ a:hover { text-decoration: underline; }
|
|
|
662
557
|
</div>
|
|
663
558
|
</div>
|
|
664
559
|
|
|
665
|
-
${toolsListHtml
|
|
560
|
+
${toolsListHtml||promptsListHtml||resourcesListHtml?`
|
|
666
561
|
<div class="card">
|
|
667
562
|
<div class="card-header">
|
|
668
563
|
<h2 class="card-title">Primitives</h2>
|
|
669
|
-
${toolsListHtml
|
|
670
|
-
${promptsListHtml
|
|
671
|
-
${resourcesListHtml
|
|
564
|
+
${toolsListHtml?`<div class="spec-section"><h3>Tools (${normalizedTools.length})</h3>${toolsListHtml}</div>`:""}
|
|
565
|
+
${promptsListHtml?`<div class="spec-section"><h3>Prompts (${prompts.length})</h3>${promptsListHtml}</div>`:""}
|
|
566
|
+
${resourcesListHtml?`<div class="spec-section"><h3>Resources (${resources.length})</h3>${resourcesListHtml}</div>`:""}
|
|
672
567
|
</div>
|
|
673
568
|
</div>
|
|
674
|
-
|
|
569
|
+
`:""}
|
|
675
570
|
|
|
676
571
|
<footer class="footer-content">
|
|
677
572
|
<a href="https://manufact.com" target="_blank" rel="noopener noreferrer" class="footer-brand-link" aria-label="Manufact">
|
|
@@ -732,9 +627,4 @@ a:hover { text-decoration: underline; }
|
|
|
732
627
|
})();
|
|
733
628
|
</script>
|
|
734
629
|
</body>
|
|
735
|
-
</html
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
export {
|
|
739
|
-
generateLandingPage
|
|
740
|
-
};
|
|
630
|
+
</html>`}export{generateLandingPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function isRecord(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function isLocalhost(url){let hostname=url.hostname.toLowerCase();return hostname==="localhost"||hostname.endsWith(".localhost")||hostname==="[::1]"||/^127(?:\.\d{1,3}){3}$/.test(hostname)}function parseAbsoluteUrl(value,name){let url;try{url=new URL(value)}catch{throw new Error(`${name} must be an absolute URL`)}if(url.origin==="null"||url.username!==""||url.password!=="")throw new Error(`${name} must be an absolute URL without credentials`);return url}function assertSecureHttpUrl(url,name){if(url.protocol!=="https:"&&!(url.protocol==="http:"&&isLocalhost(url)))throw new Error(`${name} must use HTTPS, or HTTP for localhost`)}import{OAuthError,OAuthErrorCode}from"@modelcontextprotocol/server";import{createRemoteJWKSet,jwtVerify,errors}from"jose";function createJwtVerifier(options){let key=options.key??createRemoteJWKSet(options.jwksUrl),configuredResource=canonicalUrl(options.resource);return{async verifyAccessToken(token){try{let{payload}=await jwtVerify(token,key,{issuer:options.issuer,...options.algorithms!==void 0&&{algorithms:[...options.algorithms]},requiredClaims:["exp","sub"]}),claims={...payload},clientId=requiredString(claims,"client_id")??requiredString(claims,"azp"),expiresAt=requiredFutureNumber(claims,"exp"),resource=verifiedResource(claims,configuredResource);return{token,clientId:clientId??"",scopes:normalizedStrings(claims.scope),expiresAt,extra:{payload:claims},resource}}catch(error){throw error instanceof OAuthError?error:isCredentialFailure(error)?(process.env.MCP_USE_OAUTH_DEBUG&&logJwtFailure(token,error),invalidToken("JWT verification failed",error)):error}}}}function normalizedProviderUrl(value,name){let raw=typeof value=="string"&&!value.includes("://")?`https://${value}`:value,url;try{url=new URL(raw)}catch{throw new TypeError(`${name} must be an absolute HTTP(S) URL`)}if(!isAllowedHttpUrl(url))throw new TypeError(`${name} must use HTTPS, or HTTP for localhost, without credentials, query, or fragment`);return url.pathname=url.pathname.replace(/\/+$/,"")||"/",url}function providerEndpoint(issuer,path){let base=new URL(issuer);return base.pathname=`${base.pathname.replace(/\/+$/,"")}/`,new URL(path.replace(/^\/+/,""),base).href}function payloadFromAuthInfo(authInfo){let payload=authInfo.extra?.payload;if(!isRecord(payload))throw invalidToken("Verified token payload is missing");return payload}function requiredString(claims,name){let value=claims[name];return typeof value=="string"&&value.trim().length>0?value:void 0}function stringValue(claims,name){let value=claims[name];return typeof value=="string"?value:void 0}function booleanValue(claims,name){let value=claims[name];return typeof value=="boolean"?value:void 0}function numberValue(claims,name){let value=claims[name];return typeof value=="number"&&Number.isFinite(value)?value:void 0}function recordValue(claims,name){let value=claims[name];return isRecord(value)?value:void 0}function normalizedStrings(value){return typeof value=="string"?value.split(/\s+/).filter(Boolean):Array.isArray(value)?value.filter(item=>typeof item=="string"&&item.length>0):[]}function requiredFutureNumber(claims,name){let value=numberValue(claims,name);if(value===void 0||value<=Date.now()/1e3)throw invalidToken(`Missing or expired ${name} claim`);return value}function invalidToken(message,cause){let error=new OAuthError(OAuthErrorCode.InvalidToken,message);return cause!==void 0&&(error.cause=cause),error}function verifiedResource(claims,configuredResource){let value=claims.resource;if(value!==void 0){if(typeof value!="string")throw invalidToken("Token resource claim must be an absolute URL");if(canonicalUrl(value).href!==configuredResource.href)throw invalidToken("Token resource claim does not match protected resource");return configuredResource}let audience=claims.aud;if(!validAudience(audience))throw invalidToken("Token audience claim must be a string or string array");if(!(typeof audience=="string"?[audience]:audience).includes(configuredResource.href))throw invalidToken("Token audience does not include the protected resource");return configuredResource}function validAudience(value){return typeof value=="string"||Array.isArray(value)&&value.length>0&&value.every(item=>typeof item=="string")}function canonicalUrl(value){try{let url=new URL(value);if(!isAllowedHttpUrl(url))throw new TypeError;return url.pathname=url.pathname==="/"?"/":url.pathname.replace(/\/+$/,""),url}catch{throw invalidToken("Token resource claim must be an absolute HTTPS URL, or HTTP URL for localhost")}}function isAllowedHttpUrl(url){return/^https?:$/.test(url.protocol)&&!url.username&&!url.password&&!url.search&&!url.hash&&(url.protocol!=="http:"||isLocalhost(url))}function isCredentialFailure(error){return error instanceof errors.JWTClaimValidationFailed||error instanceof errors.JWTExpired||error instanceof errors.JOSEAlgNotAllowed||error instanceof errors.JOSENotSupported||error instanceof errors.JWSInvalid||error instanceof errors.JWTInvalid||error instanceof errors.JWSSignatureVerificationFailed||error instanceof errors.JWKSNoMatchingKey}var JWT_DEBUG_CLAIMS=["iss","aud","azp","sub","exp","iat","nbf","client_id","scope","typ","jti"];function debugErrorText(error){return error instanceof Error?error.message:String(error)}function logJwtFailure(token,error){try{let decodeSegment2=function(segment,label){try{return Buffer.from(segment,"base64url").toString("utf8")}catch(decodeError){console.error(`[oauth-debug] ${label} decode failed: ${debugErrorText(decodeError)}`);return}};var decodeSegment=decodeSegment2;let name=error instanceof Error?error.constructor.name:typeof error;console.error(`[oauth-debug] JWT verify failed: ${name}: ${debugErrorText(error)}`),error instanceof errors.JWTClaimValidationFailed&&console.error(`[oauth-debug] claim=${error.claim} reason=${error.reason}`);let segments=token.split(".");if(console.error(`[oauth-debug] token segments: ${segments.length}`),segments.length!==3){let preview=token.length>12?`${token.slice(0,12)}\u2026`:token;console.error(`[oauth-debug] non-JWT token preview=${preview} length=${token.length}`);return}let headerJson=decodeSegment2(segments[0],"header");headerJson!==void 0&&console.error(`[oauth-debug] header=${headerJson}`);let payloadJson=decodeSegment2(segments[1],"payload");if(payloadJson===void 0)return;try{let payload=JSON.parse(payloadJson),selected={};for(let claim of JWT_DEBUG_CLAIMS)claim in payload&&(selected[claim]=payload[claim]);selected.now=Math.floor(Date.now()/1e3),console.error(`[oauth-debug] payload=${JSON.stringify(selected)}`)}catch(decodeError){console.error(`[oauth-debug] payload decode failed: ${debugErrorText(decodeError)}`)}}catch{}}function resolveConfiguredOAuthResource(options){let provider=options.provider,basePath=normalizeBasePath(options.basePath);if(provider.resource!==void 0)return validateOAuthResource(provider.resource,basePath);if(options.mcpUrl!==void 0)return validateOAuthResource(appendBasePath(requireAbsoluteOrigin(options.mcpUrl,"MCP_URL"),basePath),basePath)}function resolveLocalOAuthResource(listenOrigin,basePath){let listenOriginUrl=requireAbsoluteOrigin(listenOrigin,"listen origin");if(!isLocalhost(listenOriginUrl))throw new Error("OAuth listen origin must be localhost or a loopback address");return validateOAuthResource(appendBasePath(listenOriginUrl,normalizeBasePath(basePath)),basePath)}function validateOAuthResource(resource,basePath){let normalizedBasePath=normalizeBasePath(basePath),url=parseAbsoluteUrl(resource,"OAuth resource");if(url.search!==""||url.hash!=="")throw new Error("OAuth resource must not include a query string or fragment");if(assertSecureHttpUrl(url,"OAuth resource"),normalizePathname(url.pathname)!==normalizedBasePath)throw new Error(`OAuth resource path must exactly match basePath (${normalizedBasePath})`);return url.pathname=normalizedBasePath,url}function wrapOAuthTokenVerifier(provider,expectedResource){let canonicalResource=normalizeResourceUrl(expectedResource),tokenVerifier=provider.createTokenVerifier(new URL(canonicalResource.href));if(tokenVerifier===null||typeof tokenVerifier!="object"||typeof tokenVerifier.verifyAccessToken!="function")throw new TypeError("OAuth provider createTokenVerifier must return an OAuthTokenVerifier");return{async verifyAccessToken(token){let authInfo=await tokenVerifier.verifyAccessToken(token);assertVerifiedAuthInfo(authInfo),assertResourceBinding(authInfo,canonicalResource);let mapped;try{mapped=provider.mapAuthInfo(authInfo)}catch(error){throw invalidToken("Token identity mapping failed",error)}return assertMappedExtra(mapped),{...authInfo,scopes:[...authInfo.scopes],extra:{...authInfo.extra,...mapped}}}}}function assertResourceBinding(authInfo,expectedResource){if(authInfo.resource===void 0)throw invalidToken("Token verifier did not return a validated protected resource");if(parseTokenResource(authInfo.resource).href!==normalizeResourceUrl(expectedResource).href)throw invalidToken("Token resource does not match the protected resource")}function parseTokenResource(value){if(!(value instanceof URL))throw invalidToken("Token resource must be an absolute HTTPS URL, or HTTP URL for localhost");let resource=value;if(!/^https?:$/.test(resource.protocol)||resource.username!==""||resource.password!==""||resource.search!==""||resource.hash!==""||resource.protocol==="http:"&&!isLocalhost(resource))throw invalidToken("Token resource must be an absolute HTTPS URL, or HTTP URL for localhost");return normalizeResourceUrl(resource)}function normalizeResourceUrl(resource){let normalized=new URL(resource);return normalized.pathname=normalized.pathname==="/"?"/":normalized.pathname.replace(/\/+$/,""),normalized}function getOAuthProviderOptions(provider){return{oauthMetadata:provider.oauthMetadata,...provider.requiredScopes!==void 0&&{requiredScopes:[...provider.requiredScopes]},...provider.scopesSupported!==void 0&&{scopesSupported:[...provider.scopesSupported]},...provider.resourceName!==void 0&&{resourceName:provider.resourceName},...provider.serviceDocumentationUrl!==void 0&&{serviceDocumentationUrl:provider.serviceDocumentationUrl}}}function assertVerifiedAuthInfo(authInfo){if(authInfo===null||typeof authInfo!="object"||typeof authInfo.token!="string"||authInfo.token.length===0||typeof authInfo.clientId!="string"||!Array.isArray(authInfo.scopes)||!authInfo.scopes.every(scope=>typeof scope=="string")||typeof authInfo.expiresAt!="number"||!Number.isFinite(authInfo.expiresAt)||authInfo.expiresAt<=Date.now()/1e3)throw invalidToken("Token verifier returned invalid authentication information")}function assertMappedExtra(mapped){if(mapped===null||typeof mapped!="object"||!("user"in mapped)||mapped.user===void 0||!isRecord(mapped.payload)||!Array.isArray(mapped.permissions)||!mapped.permissions.every(permission=>typeof permission=="string"))throw invalidToken("Token identity mapping must return user, payload, and string permissions")}function requireAbsoluteOrigin(value,name){let url=parseAbsoluteUrl(value,name);if(url.pathname!=="/"||url.search!==""||url.hash!==""||url.username!==""||url.password!=="")throw new Error(`${name} must be an absolute origin without a path`);return url}function appendBasePath(origin,basePath){let resource=new URL(origin.origin);return resource.pathname=basePath,resource}function normalizeBasePath(basePath){if(!basePath.startsWith("/")||basePath.includes("?")||basePath.includes("#"))throw new Error("basePath must be an absolute URL pathname");return normalizePathname(basePath)}function normalizePathname(pathname){return pathname==="/"?"/":pathname.replace(/\/+$/,"")}function oauthCustomProvider(options){if(options===null||typeof options!="object"||typeof options.createTokenVerifier!="function"||typeof options.mapAuthInfo!="function")throw new TypeError("oauthCustomProvider requires createTokenVerifier, oauthMetadata, and mapAuthInfo");if(assertOAuthMetadata(options.oauthMetadata),options.resource!==void 0&&assertResourceUrl(options.resource),assertStringArray(options.requiredScopes,"requiredScopes"),assertStringArray(options.scopesSupported,"scopesSupported"),options.resourceName!==void 0&&(typeof options.resourceName!="string"||options.resourceName.trim().length===0))throw new TypeError("resourceName must be a non-empty string");if(options.serviceDocumentationUrl!==void 0){if(!(options.serviceDocumentationUrl instanceof URL))throw new TypeError("serviceDocumentationUrl must be a URL");assertSecureHttpUrl(options.serviceDocumentationUrl,"serviceDocumentationUrl")}return{createTokenVerifier:options.createTokenVerifier,oauthMetadata:options.oauthMetadata,mapAuthInfo:options.mapAuthInfo,...options.resource!==void 0&&{resource:options.resource},...options.requiredScopes!==void 0&&{requiredScopes:[...options.requiredScopes]},...options.scopesSupported!==void 0&&{scopesSupported:[...options.scopesSupported]},...options.resourceName!==void 0&&{resourceName:options.resourceName},...options.serviceDocumentationUrl!==void 0&&{serviceDocumentationUrl:options.serviceDocumentationUrl}}}function assertOAuthMetadata(metadata){if(metadata===null||typeof metadata!="object"||!("issuer"in metadata)||typeof metadata.issuer!="string")throw new TypeError("oauthMetadata must include a string issuer");assertSecureHttpUrl(parseAbsoluteUrl(metadata.issuer,"oauthMetadata.issuer"),"oauthMetadata.issuer")}function assertResourceUrl(resource){assertSecureHttpUrl(parseAbsoluteUrl(resource,"resource"),"resource")}function assertStringArray(value,name){if(value!==void 0&&(!Array.isArray(value)||!value.every(item=>typeof item=="string")))throw new TypeError(`${name} must be an array of strings`)}export{isRecord,createJwtVerifier,normalizedProviderUrl,providerEndpoint,payloadFromAuthInfo,requiredString,stringValue,booleanValue,recordValue,normalizedStrings,invalidToken,resolveConfiguredOAuthResource,resolveLocalOAuthResource,wrapOAuthTokenVerifier,getOAuthProviderOptions,oauthCustomProvider};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{completable as sdkCompletable}from"@modelcontextprotocol/server";function createPrefixCompletion(values){let strings=values.map(String);return value=>{let prefix=String(value??"").toLowerCase();return strings.filter(candidate=>candidate.toLowerCase().startsWith(prefix))}}function completable(schema,complete){return typeof complete=="function"?sdkCompletable(schema,(value,context)=>complete(String(value??""),context)):sdkCompletable(schema,createPrefixCompletion(complete))}function normalizeCompletions(completions){let normalized=Object.create(null);for(let[variable,completer]of Object.entries(completions))completer!==void 0&&(normalized[variable]=Array.isArray(completer)?createPrefixCompletion(completer):completer);return normalized}export{completable,normalizeCompletions};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function stripTrailingSlashes(value){return value.replace(/\/+$/,"")}function readEnv(name){if(typeof process>"u")return;let value=process.env[name];return value!==void 0&&value!==""?value:void 0}function parseForwardedHeader(header){for(let part of header.split(",")){let params=new Map;for(let token of part.split(";")){let[key,...rest]=token.trim().split("=");key===void 0||rest.length===0||params.set(key.toLowerCase(),rest.join("=").replace(/^"|"$/g,""))}let proto=params.get("proto"),host=params.get("host");if(proto!==void 0&&host!==void 0)return`${proto}://${host}`}}function resolveRequestOriginFromHeaders(request){let forwarded=request.headers.get("forwarded");if(forwarded!==null){let fromForwarded=parseForwardedHeader(forwarded);if(fromForwarded!==void 0)return fromForwarded}let proto=request.headers.get("x-forwarded-proto"),host=request.headers.get("x-forwarded-host");if(proto!==null&&host!==null){let firstHost=host.split(",")[0]?.trim(),firstProto=proto.split(",")[0]?.trim();if(firstHost!==void 0&&firstProto!==void 0&&firstHost!=="")return`${firstProto}://${firstHost}`}return new URL(request.url).origin}function resolveServerOrigin(request){let mcpUrl=readEnv("MCP_URL");if(mcpUrl!==void 0)try{return new URL(mcpUrl).origin}catch{}return resolveRequestOriginFromHeaders(request)}function originFromAssetsBase(assetsBase){try{return new URL(assetsBase).origin}catch{return assetsBase}}function normalizeAssetsBaseUrl(value){return stripTrailingSlashes(value)}function resolveAssetsBase(request){let assetsUrl=readEnv("MCP_ASSETS_URL");if(assetsUrl!==void 0)try{return normalizeAssetsBaseUrl(new URL(assetsUrl).href.replace(/\/$/,""))}catch{}return resolveServerOrigin(request)}function hasExplicitAssetsBase(){let assetsUrl=readEnv("MCP_ASSETS_URL");if(assetsUrl===void 0)return!1;try{return new URL(assetsUrl),!0}catch{return!1}}export{resolveServerOrigin,originFromAssetsBase,resolveAssetsBase,hasExplicitAssetsBase};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getOAuthProviderOptions,wrapOAuthTokenVerifier}from"./chunk-JMDHTN6N.js";import{OAuthError,OAuthErrorCode,bearerAuthChallengeResponse,getOAuthProtectedResourceMetadataUrl as getOAuthProtectedResourceMetadataUrl2,oauthMetadataResponse as oauthMetadataResponse2,requireBearerAuth as requireBearerAuth2,verifyBearerToken}from"@modelcontextprotocol/server";import{getOAuthProtectedResourceMetadataUrl,oauthMetadataResponse,requireBearerAuth}from"@modelcontextprotocol/server";import{hostHeaderValidationResponse,originValidationResponse}from"@modelcontextprotocol/server";var requestBags=new WeakMap;function getRequestBag(request){let bag=requestBags.get(request);return bag===void 0&&(bag={},requestBags.set(request,bag)),bag}function composeFetch(terminal,...middlewares){return async request=>{let index=0,dispatch=async()=>{if(index<middlewares.length){let middleware=middlewares[index];return index+=1,middleware(request,dispatch)}return terminal(request)};return dispatch()}}function pathnameOf(request){return new URL(request.url).pathname}function matchesPath(request,path){return pathnameOf(request)===path}function matchesPathPrefix(request,prefix){let pathname=pathnameOf(request);return pathname===prefix||pathname.startsWith(`${prefix}/`)}function pathUnderBase(basePath,childPath){let child=childPath.replace(/^\/+/,"");return basePath==="/"?`/${child}`:`${basePath}/${child}`}function isHtmlNavigationRequest(request){if(request.method!=="GET"&&request.method!=="HEAD")return!1;let accept=request.headers.get("accept");return accept===null?!1:accept.split(",").some(range=>{let[mediaType,...parameters]=range.split(";");return mediaType?.trim().toLowerCase()!=="text/html"?!1:!parameters.some(parameter=>{let[name,value]=parameter.trim().toLowerCase().split("=");return name==="q"&&Number(value)===0})})}function jsonBodyMiddleware(){return async(request,next)=>{let bag=getRequestBag(request);if(bag.parsedBody!==void 0||!(request.headers.get("content-type")??"").includes("application/json"))return next();try{bag.parsedBody=await request.clone().json()}catch{return new Response("Invalid JSON",{status:400})}return next()}}function hostValidationMiddleware(hosts){return async(request,next)=>hostHeaderValidationResponse(request,hosts)??next()}function originValidationMiddleware(origins,skipSafeMethods=!0){return async(request,next)=>skipSafeMethods&&(request.method==="GET"||request.method==="HEAD")?next():originValidationResponse(request,origins)??next()}function bearerAuth(provider,resource){let options=getOAuthProviderOptions(provider),gate=requireBearerAuth({verifier:wrapOAuthTokenVerifier(provider,resource),resourceMetadataUrl:getOAuthProtectedResourceMetadataUrl(resource),...options.requiredScopes!==void 0&&{requiredScopes:[...options.requiredScopes]}});return async(request,next)=>{let result=await gate(request);return result instanceof Response?result:(getRequestBag(request).authInfo=result,next())}}function oauthMetadata(provider,resource){let options=getOAuthProviderOptions(provider);return async(request,next)=>{let response=oauthMetadataResponse(request,{oauthMetadata:options.oauthMetadata,resourceServerUrl:resource,...options.scopesSupported!==void 0&&{scopesSupported:[...options.scopesSupported]},...options.resourceName!==void 0&&{resourceName:options.resourceName},...options.serviceDocumentationUrl!==void 0&&{serviceDocumentationUrl:options.serviceDocumentationUrl}});return response!==void 0?response:next()}}function authInfoFromRequest(request){return getRequestBag(request).authInfo}export{getRequestBag,composeFetch,pathnameOf,matchesPath,matchesPathPrefix,pathUnderBase,isHtmlNavigationRequest,jsonBodyMiddleware,hostValidationMiddleware,originValidationMiddleware,bearerAuth,oauthMetadata,authInfoFromRequest,OAuthError,OAuthErrorCode,bearerAuthChallengeResponse,getOAuthProtectedResourceMetadataUrl2 as getOAuthProtectedResourceMetadataUrl,oauthMetadataResponse2 as oauthMetadataResponse,requireBearerAuth2 as requireBearerAuth,verifyBearerToken};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{fromJsonSchema}from"@modelcontextprotocol/server";var HTTP_METHODS=["get","put","post","delete","options","head","patch","trace"];function registerOpenAPITools(server,options){let operations=collectOperations(options.spec,options),names=createToolNames(operations),baseUrl=operations.length>0?resolveBaseUrl(options):void 0;for(let[index,operation]of operations.entries()){let name=names[index];if(name===void 0||baseUrl===void 0)continue;let inputBindings=createInputBindings(operation);server.tool({name,description:createToolDescription(operation),inputSchema:createToolInputSchema(options.spec,operation,inputBindings)},async params=>callOpenAPIOperation(operation,params,options,inputBindings,baseUrl))}}function collectOperations(spec,options){let collected=[];for(let[path,pathItemOrRef]of Object.entries(spec.paths??{})){let pathItem=resolveRef(spec,pathItemOrRef);if(pathItem===void 0||isReferenceObject(pathItem))continue;let pathParameters=resolveParameters(spec,pathItem.parameters);for(let method of HTTP_METHODS){let operationOrRef=pathItem[method];if(operationOrRef===void 0)continue;let operation=resolveRef(spec,operationOrRef);if(operation===void 0||isReferenceObject(operation))continue;let operationParameters=resolveParameters(spec,operation.parameters),requestBody=operation.requestBody===void 0?void 0:resolveRef(spec,operation.requestBody),item={method,path,operation,parameters:mergeParameters(pathParameters,operationParameters),...requestBody!==void 0&&!isReferenceObject(requestBody)&&{requestBody}};isIncluded(item,options)&&collected.push(item)}}return collected}function resolveParameters(spec,parameters){let resolved=[];for(let parameter of parameters??[]){let value=resolveRef(spec,parameter);value!==void 0&&!isReferenceObject(value)&&resolved.push(value)}return resolved}function mergeParameters(pathParameters,operationParameters){let merged=new Map;for(let parameter of[...pathParameters,...operationParameters])merged.set(`${parameter.in}:${parameter.name}`,parameter);return[...merged.values()]}function isIncluded(operation,options){if(options.tags?.length){let tags=new Set(operation.operation.tags??[]);if(!options.tags.some(tag=>tags.has(tag)))return!1}return!(options.exclude??[]).some(rule=>matchesExcludeRule(operation,rule))}function matchesExcludeRule(operation,rule){if(rule.method&&rule.method.toLowerCase()!==operation.method||rule.operationId&&!matchesPattern(rule.operationId,operation.operation.operationId??"")||rule.path&&!matchesPattern(rule.path,operation.path))return!1;if(rule.tags?.length){let tags=new Set(operation.operation.tags??[]);if(!rule.tags.some(tag=>tags.has(tag)))return!1}return!0}function matchesPattern(pattern,value){return typeof pattern=="string"?pattern===value:(pattern.lastIndex=0,pattern.test(value))}function createToolNames(operations){let seen=new Map;return operations.map(operation=>{let baseName=slugifyToolName(operation.operation.operationId??`${operation.method}_${operation.path.replace(/[{}]/g,"").replace(/\//g,"_")}`),count=seen.get(baseName)??0;if(seen.set(baseName,count+1),count===0)return baseName;let suffix=`_${count+1}`;return`${baseName.slice(0,64-suffix.length)}${suffix}`})}function createToolDescription(operation){return[operation.operation.summary,operation.operation.description,`HTTP: ${operation.method.toUpperCase()} ${operation.path}`].filter(part=>!!part).join(`
|
|
2
|
+
|
|
3
|
+
`)}function slugifyToolName(value){return value.trim().replace(/[^a-zA-Z0-9_-]+/g,"_").replace(/_+/g,"_").replace(/^_/,"").replace(/_$/,"").slice(0,64)||"openapi_tool"}function createToolInputSchema(spec,operation,inputBindings){let properties={},required=[];for(let{parameter,inputName}of inputBindings.parameters){let parameterSchema=transformSchema(spec,parameter.schema??{});properties[inputName]={...parameterSchema,description:parameter.description??`${parameter.in} parameter`},(parameter.required||parameter.in==="path")&&required.push(inputName)}let bodySchema=getJsonRequestBodySchema(operation.requestBody);bodySchema!==void 0&&inputBindings.bodyInputName!==void 0&&(properties[inputBindings.bodyInputName]=transformSchema(spec,bodySchema),operation.requestBody?.required&&required.push(inputBindings.bodyInputName));let definitions=createSchemaDefinitions(spec),schema={type:"object",properties,additionalProperties:!1,...required.length>0&&{required},...definitions!==void 0&&{$defs:definitions}};return fromJsonSchema(schema)}function createInputBindings(operation){let parameters=operation.parameters.filter(parameter=>parameter.in!=="cookie"),bodyInputName=getJsonRequestBodySchema(operation.requestBody)===void 0?void 0:"body",nameCounts=new Map;for(let parameter of parameters)nameCounts.set(parameter.name,(nameCounts.get(parameter.name)??0)+1);let usedNames=new Set(bodyInputName===void 0?[]:[bodyInputName]);return{parameters:parameters.map(parameter=>{let preferredName=(nameCounts.get(parameter.name)??0)>1||parameter.name===bodyInputName?`${parameter.name}_${parameter.in}`:parameter.name;return{parameter,inputName:claimInputName(preferredName,usedNames)}}),...bodyInputName!==void 0&&{bodyInputName}}}function claimInputName(preferredName,usedNames){let inputName=preferredName,suffix=2;for(;usedNames.has(inputName);)inputName=`${preferredName}_${suffix}`,suffix+=1;return usedNames.add(inputName),inputName}function createSchemaDefinitions(spec){let schemas=readRecord(spec.components?.schemas);if(schemas===void 0)return;let definitions={};for(let[name,schema]of Object.entries(schemas))definitions[name]=transformSchemaNode(spec,schema,new Set);return definitions}function transformSchema(spec,schema){let transformed=transformSchemaNode(spec,schema,new Set);return readRecord(transformed)??{}}function transformSchemaNode(spec,value,resolvingRefs){if(Array.isArray(value))return value.map(item=>transformSchemaNode(spec,item,resolvingRefs));let object=readRecord(value);if(object===void 0)return value;let ref=typeof object.$ref=="string"?object.$ref:void 0,siblings={};for(let[key,child]of Object.entries(object))key!=="$ref"&&(key==="nullable"&&typeof child=="boolean"||(siblings[key]=transformSchemaNode(spec,child,resolvingRefs)));let transformed=siblings;if(ref!==void 0){let schemaRef=rewriteSchemaRef(spec,ref);if(schemaRef!==void 0)transformed={$ref:schemaRef,...siblings};else if(!resolvingRefs.has(ref)){let resolved=resolveRef(spec,{$ref:ref});if(resolved!==void 0){let nextRefs=new Set(resolvingRefs);nextRefs.add(ref),transformed={...readRecord(transformSchemaNode(spec,resolved,nextRefs))??{},...siblings}}}}return object.nullable===!0?{anyOf:[transformed,{type:"null"}]}:transformed}function rewriteSchemaRef(spec,ref){let prefix="#/components/schemas/";if(ref.startsWith(prefix))return resolveRef(spec,{$ref:ref})===void 0?void 0:`#/$defs/${ref.slice(prefix.length)}`}function getJsonRequestBodySchema(requestBody){let content=requestBody?.content;if(content!==void 0)return content["application/json"]?.schema??content["application/*+json"]?.schema??Object.entries(content).find(([mediaType])=>mediaType.includes("+json"))?.[1].schema}async function callOpenAPIOperation(operation,params,options,inputBindings,baseUrl){let fetchImpl=options.fetch??globalThis.fetch,url=buildUrl(operation,params,inputBindings.parameters,baseUrl),headers=buildHeaders(inputBindings.parameters,params,options),bodyInputName=inputBindings.bodyInputName,body=bodyInputName===void 0||params[bodyInputName]===void 0?void 0:JSON.stringify(params[bodyInputName]);body!==void 0&&!hasHeader(headers,"content-type")&&(headers["content-type"]="application/json");let response=await fetchImpl(url,{method:operation.method.toUpperCase(),headers,...body!==void 0&&{body}}),contentType=response.headers.get("content-type")??"";if(!response.ok)return{content:[{type:"text",text:await response.text()}],isError:!0};if(contentType.includes("application/json")||contentType.includes("+json")){let text=await response.text();try{let data=JSON.parse(text);return{content:[{type:"text",text:JSON.stringify(data)}],structuredContent:data}}catch{return{content:[{type:"text",text}]}}}return{content:[{type:"text",text:await response.text()}]}}function buildUrl(operation,params,parameterBindings,baseUrl){let interpolatedPath=operation.path.replace(/{([^}]+)}/g,(_match,name)=>{let binding=parameterBindings.find(({parameter})=>parameter.in==="path"&¶meter.name===name);return encodeURIComponent(String(binding===void 0?"":params[binding.inputName]??""))}),url=new URL(interpolatedPath.replace(/^\/+/,""),ensureTrailingSlash(baseUrl));for(let{parameter,inputName}of parameterBindings){if(parameter.in!=="query")continue;let value=params[inputName];value==null||value===""||appendQueryParam(url,parameter.name,value)}return url.toString()}function buildHeaders(parameterBindings,params,options){let headers={...options.headers??{}};for(let{parameter,inputName}of parameterBindings){if(parameter.in!=="header")continue;let value=params[inputName];value==null||value===""||(headers[parameter.name]=String(value))}return options.auth?.type==="bearer"&&options.auth.token&&(headers.authorization=`Bearer ${options.auth.token}`),options.auth?.type==="header"&&options.auth.value&&(headers[options.auth.name]=options.auth.value),headers}function resolveBaseUrl(options){let baseUrl=options.baseUrl??options.spec.servers?.[0]?.url;if(baseUrl===void 0||baseUrl.trim()==="")throw new Error("MCPServer.fromOpenAPI requires options.baseUrl or spec.servers[0].url");return baseUrl}function appendQueryParam(url,name,value){if(Array.isArray(value)){for(let item of value)item!=null&&item!==""&&url.searchParams.append(name,String(item));return}url.searchParams.set(name,String(value))}function ensureTrailingSlash(url){return url.endsWith("/")?url:`${url}/`}function hasHeader(headers,name){return Object.keys(headers).some(headerName=>headerName.toLowerCase()===name)}function isReferenceObject(value){let object=readRecord(value);return object!==void 0&&typeof object.$ref=="string"}function resolveRef(spec,value){if(!isReferenceObject(value))return value;if(!value.$ref.startsWith("#/"))return;let segments=value.$ref.slice(2).split("/").map(segment=>segment.replace(/~1/g,"/").replace(/~0/g,"~")),current=spec;for(let segment of segments){let object=readRecord(current);if(object===void 0||!(segment in object))return;current=object[segment]}return current}function readRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:void 0}export{registerOpenAPITools};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var PUBLIC_CONTENT_TYPES={".css":"text/css",".gif":"image/gif",".html":"text/html",".ico":"image/x-icon",".jpeg":"image/jpeg",".jpg":"image/jpeg",".js":"application/javascript",".json":"application/json",".map":"application/json",".png":"image/png",".svg":"image/svg+xml",".txt":"text/plain",".webp":"image/webp",".woff":"font/woff",".woff2":"font/woff2"};async function resolvePublicFilePath(publicRoot,subpath){let{stat}=await import("fs/promises"),{resolve,sep}=await import("path");if(subpath===""||subpath.includes("\\")||subpath.split("/").some(segment=>segment===".."))return null;let clean=subpath.replace(/^\/+/,"");if(clean===""||clean.endsWith("/"))return null;let root=resolve(publicRoot),abs=resolve(root,clean);if(abs!==root&&!abs.startsWith(root+sep))return null;try{if(!(await stat(abs)).isFile())return null}catch{return null}return abs}async function servePublicFile(diskPath,options={}){let{readFile}=await import("fs/promises"),{extname}=await import("path"),ext=extname(diskPath).toLowerCase(),contentType=PUBLIC_CONTENT_TYPES[ext]??"application/octet-stream",body=options.head===!0?null:new Uint8Array(await readFile(diskPath));return new Response(body,{status:200,headers:{"Content-Type":contentType,"Cache-Control":"public, max-age=0, must-revalidate",...options.deferCors!==!0&&{"Access-Control-Allow-Origin":"*"}}})}export{resolvePublicFilePath,servePublicFile};
|