mcp-use 2.10.0-canary.3 → 2.10.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/bin.js +1 -1
- package/dist/{chunk-KVVGKJR2.js → chunk-3XIIMBWV.js} +1 -1
- package/dist/{chunk-H7AMD7SA.js → chunk-4ICJVJOI.js} +1 -1
- package/dist/chunk-JX52OYMQ.js +1 -0
- package/dist/config.d.ts +3 -3
- package/dist/index-node.js +1 -1
- package/dist/index.js +3 -3
- package/dist/internal/usage.js +1 -1
- package/dist/next/config.d.ts +6 -2
- package/dist/oauth/auth0.js +1 -1
- package/dist/oauth/better-auth.js +1 -1
- package/dist/oauth/clerk.js +1 -1
- package/dist/oauth/convex.js +1 -1
- package/dist/oauth/guards.d.ts +5 -0
- package/dist/oauth/index.js +2 -2
- package/dist/oauth/keycloak.js +1 -1
- package/dist/oauth/scalekit.js +1 -1
- package/dist/oauth/storage.js +1 -1
- package/dist/oauth/supabase.js +1 -1
- package/dist/oauth/workos.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-4VRUHDIY.js +0 -1
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var{runBin}=await import("@mcp-use/cli");runBin(process.argv.slice(2),{frameworkVersion:"2.10.0
|
|
2
|
+
var{runBin}=await import("@mcp-use/cli");runBin(process.argv.slice(2),{frameworkVersion:"2.10.0"});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isLocalhost,isRecord}from"./chunk-4VRUHDIY.js";function isBuilding(){return typeof process>"u"||process.env===void 0?!1:process.env.MCP_USE_PHASE==="build"}function upstream(options){let result={...options,kind:"redirect"};return assertRedirectUpstream(result),result}function assertRedirectUpstream(value){if(value===null||typeof value!="object")throw new TypeError("oauthProxy upstream must be an object");let fields=isBuilding()?["id","name"]:["id","name","clientId","clientSecret"];for(let field of fields)if(typeof value[field]!="string"||value[field].length===0)throw new TypeError(`oauthProxy upstream.${field} must be a non-empty string`);if(!/^[a-z0-9-]+$/.test(value.id))throw new TypeError("oauthProxy upstream.id must contain only lowercase letters, digits, and hyphens");for(let field of["authorizationEndpoint","tokenEndpoint"])assertEndpoint(value[field],`upstream.${field}`);if(value.issuer!==void 0&&assertEndpoint(value.issuer,"upstream.issuer"),!Array.isArray(value.scopes)||!value.scopes.every(scope=>typeof scope=="string"&&scope!==""))throw new TypeError("oauthProxy upstream.scopes must be an array of strings");if(typeof value.fetchUser!="function")throw new TypeError("oauthProxy upstream.fetchUser must be a function")}function assertEndpoint(value,name){let url;try{url=new URL(String(value))}catch{throw new TypeError(`oauthProxy ${name} must be an absolute URL`)}if(typeof value!="string"||url.hash!==""||url.username!==""||url.password!==""||!(url.protocol==="https:"||url.protocol==="http:"&&isLocalhost(url)))throw new TypeError(`oauthProxy ${name} must be an HTTPS URL (HTTP only on localhost)`)}var UpstreamError=class extends Error{code;transient;upstreamCode;description;detail;constructor(code,message,transient,options={}){super(message,options.cause===void 0?void 0:{cause:options.cause}),this.name="UpstreamError",this.code=code,this.transient=transient,this.upstreamCode=options.upstreamCode,this.description=options.description,this.detail=options.detail}};function printable(value,max=200){let flat=value.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g," ");return flat.length>max?`${flat.slice(0,max)}\u2026`:flat}var PROVIDER_ERROR_CODES={bad_verification_code:"invalid_grant",bad_refresh_token:"invalid_grant",incorrect_client_credentials:"invalid_client",redirect_uri_mismatch:"invalid_grant",unverified_user_email:"access_denied"},UPSTREAM_CODE_FIELD="mcp_use_upstream_error",UPSTREAM_STATUS_HEADER="x-mcp-use-upstream-status";function normalizingFetch(base){return async(input,init)=>{let response=await base(input,init);if(!(response.headers.get("content-type")??"").includes("json")||response.status!==200&&response.status!==400)return response;let body=await response.clone().json().catch(()=>{});if(!isRecord(body)||typeof body.error!="string"||body.access_token!==void 0)return response;let code=PROVIDER_ERROR_CODES[body.error]??body.error;return new Response(JSON.stringify({...body,error:code,[UPSTREAM_CODE_FIELD]:body.error}),{status:400,headers:{"content-type":"application/json",[UPSTREAM_STATUS_HEADER]:String(response.status)}})}}async function upstreamClient(provider,fetchImpl){let oauth=await import("oauth4webapi"),issuer=provider.issuer??new URL(provider.authorizationEndpoint).origin,insecure=[provider.tokenEndpoint,issuer].some(url=>new URL(url).protocol==="http:");return{oauth,as:{issuer,authorization_endpoint:provider.authorizationEndpoint,token_endpoint:provider.tokenEndpoint},client:{client_id:provider.clientId},auth:oauth.ClientSecretPost(provider.clientSecret),options:{[oauth.customFetch]:normalizingFetch(fetchImpl),...insecure&&{[oauth.allowInsecureRequests]:!0},signal:AbortSignal.timeout(15e3)}}}async function exchangeUpstreamCode(provider,fetchImpl,input){let{oauth,as,client,auth,options}=await upstreamClient(provider,fetchImpl),params;try{params=oauth.validateAuthResponse(as,client,input.callbackParams,oauth.skipStateCheck)}catch(error){throw callbackError(oauth,provider,error)}return runTokenRequest(oauth,provider,async()=>{let response=await oauth.authorizationCodeGrantRequest(as,client,auth,params,input.redirectUri,input.codeVerifier??oauth.nopkce,options);return oauth.processAuthorizationCodeResponse(as,client,response)})}async function refreshUpstreamTokens(provider,fetchImpl,refreshToken){let{oauth,as,client,auth,options}=await upstreamClient(provider,fetchImpl);return runTokenRequest(oauth,provider,async()=>{let response=await oauth.refreshTokenGrantRequest(as,client,auth,refreshToken,options);return oauth.processRefreshTokenResponse(as,client,response)})}function callbackError(oauth,provider,error){if(error instanceof oauth.AuthorizationResponseError){let code=printable(error.error,64);return new UpstreamError("server_error",`${provider.name} returned ${code} to the callback`,!1,{cause:error,upstreamCode:code,...error.error_description!==void 0&&{description:printable(error.error_description)}})}let facts=[];if(error instanceof oauth.OperationProcessingError){let cause=error.cause;if(isRecord(cause)&&typeof cause.expected=="string"){facts.push(`expected ${JSON.stringify(cause.expected)}`);let parameters=cause.parameters;parameters instanceof URLSearchParams&¶meters.has("iss")&&facts.push(`got ${JSON.stringify(printable(parameters.get("iss")??""))}`)}}return new UpstreamError("server_error",`${provider.name} callback failed validation: ${errorText(error)}`,!1,{cause:error,...facts.length>0&&{detail:facts.join(", ")}})}async function runTokenRequest(oauth,provider,request){let response;try{response=await request()}catch(error){return Promise.reject(tokenRequestError(oauth,provider,error))}return{accessToken:response.access_token,...response.refresh_token!==void 0&&{refreshToken:response.refresh_token},...typeof response.expires_in=="number"&&{expiresAt:Math.floor(Date.now()/1e3)+response.expires_in},scopes:typeof response.scope=="string"?response.scope.split(/[\s,]+/).filter(Boolean):[...provider.scopes],...response.id_token!==void 0&&{idToken:response.id_token}}}function tokenRequestError(oauth,provider,error){let endpoint=`${provider.name} token endpoint`;if(error instanceof oauth.ResponseBodyError){let body=error.cause,original=isRecord(body)?body[UPSTREAM_CODE_FIELD]:void 0,upstreamCode=printable(typeof original=="string"?original:error.error,64),status=Number(error.response.headers.get(UPSTREAM_STATUS_HEADER))||error.status,description=error.error_description===void 0?void 0:printable(error.error_description);return new UpstreamError(error.error,`${endpoint} returned ${upstreamCode}${description===void 0?"":`: ${description}`}`,status>=500,{cause:error,upstreamCode,...description!==void 0&&{description},detail:`HTTP ${status}`})}if(error instanceof oauth.WWWAuthenticateChallengeError){let schemes=error.cause.map(challenge=>challenge.scheme);return new UpstreamError("invalid_client",`${endpoint} refused the client credentials`,error.status>=500,{cause:error,detail:`HTTP ${error.status}, WWW-Authenticate ${schemes.join(", ")}`})}if(error instanceof oauth.OperationProcessingError){let cause=error.cause,facts=[],status;if(cause instanceof Response)status=cause.status,facts.push(`HTTP ${status}`,`content-type ${cause.headers.get("content-type")??"none"}`);else if(isRecord(cause)&&isRecord(cause.body)){let fields=Object.keys(cause.body);facts.push(`fields ${fields.length>0?fields.join(", "):"none"}`)}return error.code!==void 0&&facts.push(error.code),new UpstreamError("server_error",`${endpoint} returned an unusable response: ${error.message}`,status!==void 0&&status>=500,{cause:error,detail:facts.join(", ")})}if(error instanceof Error&&(error.name==="TimeoutError"||error.name==="AbortError"))return new UpstreamError("temporarily_unavailable",`${endpoint} did not answer in time`,!0,{cause:error});if(error instanceof TypeError&&!("code"in error)){let cause=error.cause,reason=isRecord(cause)&&typeof cause.code=="string"?cause.code:cause instanceof Error?cause.message:error.message;return new UpstreamError("temporarily_unavailable",`${endpoint} is unreachable: ${printable(reason)}`,!0,{cause:error})}return new UpstreamError("server_error",`${endpoint} request failed: ${errorText(error)}`,!1,{cause:error})}function errorText(error){if(!(error instanceof Error))return printable(String(error));let code="code"in error&&typeof error.code=="string"?` [${error.code}]`:"";return printable(`${error.name}: ${error.message}${code}`)}var textEncoder=new TextEncoder,textDecoder=new TextDecoder("utf-8",{fatal:!0}),ENVELOPE_VERSION="v1",IV_BYTES=12,MIN_SECRET_LENGTH=32;function normalizeSecrets(secret){let secrets=Array.isArray(secret)?secret:[secret];if(secrets.length===0)throw new TypeError("oauthProxy secret must not be an empty array");for(let value of secrets)if(typeof value!="string"||value.length<MIN_SECRET_LENGTH)throw new TypeError(`oauthProxy secret must be a string of at least ${MIN_SECRET_LENGTH} characters`);return secrets}async function deriveKeyring(secrets){let all=await Promise.all(secrets.map(secret=>deriveKey(secret)));return{current:all[0],all}}async function randomKeyring(){return deriveKeyring([randomToken(32)])}async function deriveKey(secret){let ikm=await crypto.subtle.importKey("raw",textEncoder.encode(secret),"HKDF",!1,["deriveKey","deriveBits"]),hkdf=info=>({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(0),info:textEncoder.encode(`mcp-use/oauth-proxy/${info}`)}),[storage,cookieBits,kidBits]=await Promise.all([crypto.subtle.deriveKey(hkdf("storage"),ikm,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]),crypto.subtle.deriveBits(hkdf("cookie"),ikm,256),crypto.subtle.deriveBits(hkdf("kid"),ikm,64)]);return{kid:toHex(new Uint8Array(kidBits)),storage,cookie:new Uint8Array(cookieBits)}}async function encryptValue(keyring,storageKey,plaintext){let iv=crypto.getRandomValues(new Uint8Array(IV_BYTES)),ciphertext=await crypto.subtle.encrypt({name:"AES-GCM",iv,additionalData:textEncoder.encode(storageKey),tagLength:128},keyring.current.storage,textEncoder.encode(plaintext));return[ENVELOPE_VERSION,keyring.current.kid,base64UrlEncode(iv),base64UrlEncode(new Uint8Array(ciphertext))].join(".")}async function decryptValue(keyring,storageKey,envelope){let parts=envelope.split(".");if(parts.length!==4||parts[0]!==ENVELOPE_VERSION)return;let key=keyring.all.find(candidate=>candidate.kid===parts[1]);if(key!==void 0)try{let plaintext=await crypto.subtle.decrypt({name:"AES-GCM",iv:base64UrlDecode(parts[2]),additionalData:textEncoder.encode(storageKey),tagLength:128},key.storage,base64UrlDecode(parts[3]));return textDecoder.decode(plaintext)}catch{return}}function randomToken(bytes=32){return base64UrlEncode(crypto.getRandomValues(new Uint8Array(bytes)))}async function sha256(value){let digest=await crypto.subtle.digest("SHA-256",textEncoder.encode(value));return base64UrlEncode(new Uint8Array(digest))}function pkceChallenge(verifier){return sha256(verifier)}function timingSafeEqual(a,b){let left=textEncoder.encode(a),right=textEncoder.encode(b),difference=left.length^right.length,length=Math.max(left.length,right.length);for(let index=0;index<length;index++)difference|=(left[index]??0)^(right[index]??0);return difference===0}function base64UrlEncode(bytes){let binary="";for(let byte of bytes)binary+=String.fromCharCode(byte);return btoa(binary).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function base64UrlDecode(value){if(!/^[A-Za-z0-9_-]*$/.test(value))throw new TypeError("Invalid base64url value");let padded=value.replace(/-/g,"+").replace(/_/g,"/"),binary=atob(padded+"=".repeat((4-padded.length%4)%4)),bytes=new Uint8Array(binary.length);for(let index=0;index<binary.length;index++)bytes[index]=binary.charCodeAt(index);return bytes}function toHex(bytes){return Array.from(bytes,byte=>byte.toString(16).padStart(2,"0")).join("")}var MEMORY_STORAGE=Symbol.for("mcp-use.oauth.memoryStorage");function memoryStorage(){let values=new Map,read=key=>{let entry=values.get(key);if(entry!==void 0){if(entry.expiresAt<=Date.now()){values.delete(key);return}return entry.value}},write=(key,value,ttlSeconds)=>{if(values.size>1e4)for(let[candidate,entry]of values)entry.expiresAt<=Date.now()&&values.delete(candidate);values.set(key,{value,expiresAt:Date.now()+ttlSeconds*1e3})},storage={get:async key=>read(key),set:async(key,value,ttlSeconds)=>write(key,value,ttlSeconds),delete:async key=>{values.delete(key)},take:async key=>{let value=read(key);return values.delete(key),value},add:async(key,value,ttlSeconds)=>read(key)!==void 0?!1:(write(key,value,ttlSeconds),!0)};return Object.defineProperty(storage,MEMORY_STORAGE,{value:!0}),storage}function isMemoryStorage(storage){return storage[MEMORY_STORAGE]===!0}function assertStorage(storage){if(storage===null||typeof storage!="object")throw new TypeError("oauthProxy storage must be an object");for(let method of["get","set","delete","take","add"])if(typeof storage[method]!="function")throw new TypeError(`oauthProxy storage must implement ${method}()`)}var KEY_PREFIX="mcp-use:oauth:",SecureStore=class{#storage;#keyring;#prefix;#warned=new Set;constructor(storage,keyring,resource){this.#storage=storage,this.#keyring=keyring,this.#prefix=sha256(resource.href).then(hash=>`${KEY_PREFIX}${hash.slice(0,16)}:`)}async get(key){let fullKey=await this.#prefix+key;return this.#decode(key,fullKey,await this.#storage.get(fullKey))}async set(key,value,ttlSeconds){let fullKey=await this.#prefix+key;await this.#storage.set(fullKey,await this.#encode(fullKey,value),ttl(ttlSeconds))}async delete(key){await this.#storage.delete(await this.#prefix+key)}async take(key){let fullKey=await this.#prefix+key;return this.#decode(key,fullKey,await this.#storage.take(fullKey))}async add(key,value,ttlSeconds){let fullKey=await this.#prefix+key;return this.#storage.add(fullKey,await this.#encode(fullKey,value),ttl(ttlSeconds))}async#encode(fullKey,value){return encryptValue(await this.#keyring(),fullKey,JSON.stringify(value))}async#decode(key,fullKey,stored){if(typeof stored!="string")return;let keyring=await this.#keyring(),plaintext=await decryptValue(keyring,fullKey,stored);if(plaintext===void 0){this.#warnUnreadable(keyring,key,stored);return}try{return JSON.parse(plaintext)}catch{return}}#warnUnreadable(keyring,key,stored){let kid=printable(stored.split(".")[1]??"",32),known=keyring.all.some(entry=>entry.kid===kid),kind=key.split(":")[0]??"",id=known?`record:${kind}`:`kid:${kid}`;this.#warned.has(id)||(this.#warned.add(id),console.warn(known?`[mcp-use] oauthProxy: a stored "${kind}" record failed to decrypt and reads as absent. Is something else writing to the same keys?`:`[mcp-use] oauthProxy: stored records were encrypted with a secret this server does not have (key id "${kid}"), so they read as absent and those users must sign in again. If the secret changed, pass the old one after the new one to keep their sign-ins: secret: [newSecret, oldSecret].`))}};function ttl(seconds){return Math.max(1,Math.ceil(seconds))}export{normalizeSecrets,deriveKeyring,randomKeyring,randomToken,sha256,pkceChallenge,timingSafeEqual,isBuilding,upstream,assertRedirectUpstream,assertEndpoint,UpstreamError,printable,exchangeUpstreamCode,refreshUpstreamTokens,memoryStorage,isMemoryStorage,assertStorage,SecureStore};
|
|
1
|
+
import{isLocalhost,isRecord}from"./chunk-JX52OYMQ.js";function isBuilding(){return typeof process>"u"||process.env===void 0?!1:process.env.MCP_USE_PHASE==="build"}function upstream(options){let result={...options,kind:"redirect"};return assertRedirectUpstream(result),result}function assertRedirectUpstream(value){if(value===null||typeof value!="object")throw new TypeError("oauthProxy upstream must be an object");let fields=isBuilding()?["id","name"]:["id","name","clientId","clientSecret"];for(let field of fields)if(typeof value[field]!="string"||value[field].length===0)throw new TypeError(`oauthProxy upstream.${field} must be a non-empty string`);if(!/^[a-z0-9-]+$/.test(value.id))throw new TypeError("oauthProxy upstream.id must contain only lowercase letters, digits, and hyphens");for(let field of["authorizationEndpoint","tokenEndpoint"])assertEndpoint(value[field],`upstream.${field}`);if(value.issuer!==void 0&&assertEndpoint(value.issuer,"upstream.issuer"),!Array.isArray(value.scopes)||!value.scopes.every(scope=>typeof scope=="string"&&scope!==""))throw new TypeError("oauthProxy upstream.scopes must be an array of strings");if(typeof value.fetchUser!="function")throw new TypeError("oauthProxy upstream.fetchUser must be a function")}function assertEndpoint(value,name){let url;try{url=new URL(String(value))}catch{throw new TypeError(`oauthProxy ${name} must be an absolute URL`)}if(typeof value!="string"||url.hash!==""||url.username!==""||url.password!==""||!(url.protocol==="https:"||url.protocol==="http:"&&isLocalhost(url)))throw new TypeError(`oauthProxy ${name} must be an HTTPS URL (HTTP only on localhost)`)}var UpstreamError=class extends Error{code;transient;upstreamCode;description;detail;constructor(code,message,transient,options={}){super(message,options.cause===void 0?void 0:{cause:options.cause}),this.name="UpstreamError",this.code=code,this.transient=transient,this.upstreamCode=options.upstreamCode,this.description=options.description,this.detail=options.detail}};function printable(value,max=200){let flat=value.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g," ");return flat.length>max?`${flat.slice(0,max)}\u2026`:flat}var PROVIDER_ERROR_CODES={bad_verification_code:"invalid_grant",bad_refresh_token:"invalid_grant",incorrect_client_credentials:"invalid_client",redirect_uri_mismatch:"invalid_grant",unverified_user_email:"access_denied"},UPSTREAM_CODE_FIELD="mcp_use_upstream_error",UPSTREAM_STATUS_HEADER="x-mcp-use-upstream-status";function normalizingFetch(base){return async(input,init)=>{let response=await base(input,init);if(!(response.headers.get("content-type")??"").includes("json")||response.status!==200&&response.status!==400)return response;let body=await response.clone().json().catch(()=>{});if(!isRecord(body)||typeof body.error!="string"||body.access_token!==void 0)return response;let code=PROVIDER_ERROR_CODES[body.error]??body.error;return new Response(JSON.stringify({...body,error:code,[UPSTREAM_CODE_FIELD]:body.error}),{status:400,headers:{"content-type":"application/json",[UPSTREAM_STATUS_HEADER]:String(response.status)}})}}async function upstreamClient(provider,fetchImpl){let oauth=await import("oauth4webapi"),issuer=provider.issuer??new URL(provider.authorizationEndpoint).origin,insecure=[provider.tokenEndpoint,issuer].some(url=>new URL(url).protocol==="http:");return{oauth,as:{issuer,authorization_endpoint:provider.authorizationEndpoint,token_endpoint:provider.tokenEndpoint},client:{client_id:provider.clientId},auth:oauth.ClientSecretPost(provider.clientSecret),options:{[oauth.customFetch]:normalizingFetch(fetchImpl),...insecure&&{[oauth.allowInsecureRequests]:!0},signal:AbortSignal.timeout(15e3)}}}async function exchangeUpstreamCode(provider,fetchImpl,input){let{oauth,as,client,auth,options}=await upstreamClient(provider,fetchImpl),params;try{params=oauth.validateAuthResponse(as,client,input.callbackParams,oauth.skipStateCheck)}catch(error){throw callbackError(oauth,provider,error)}return runTokenRequest(oauth,provider,async()=>{let response=await oauth.authorizationCodeGrantRequest(as,client,auth,params,input.redirectUri,input.codeVerifier??oauth.nopkce,options);return oauth.processAuthorizationCodeResponse(as,client,response)})}async function refreshUpstreamTokens(provider,fetchImpl,refreshToken){let{oauth,as,client,auth,options}=await upstreamClient(provider,fetchImpl);return runTokenRequest(oauth,provider,async()=>{let response=await oauth.refreshTokenGrantRequest(as,client,auth,refreshToken,options);return oauth.processRefreshTokenResponse(as,client,response)})}function callbackError(oauth,provider,error){if(error instanceof oauth.AuthorizationResponseError){let code=printable(error.error,64);return new UpstreamError("server_error",`${provider.name} returned ${code} to the callback`,!1,{cause:error,upstreamCode:code,...error.error_description!==void 0&&{description:printable(error.error_description)}})}let facts=[];if(error instanceof oauth.OperationProcessingError){let cause=error.cause;if(isRecord(cause)&&typeof cause.expected=="string"){facts.push(`expected ${JSON.stringify(cause.expected)}`);let parameters=cause.parameters;parameters instanceof URLSearchParams&¶meters.has("iss")&&facts.push(`got ${JSON.stringify(printable(parameters.get("iss")??""))}`)}}return new UpstreamError("server_error",`${provider.name} callback failed validation: ${errorText(error)}`,!1,{cause:error,...facts.length>0&&{detail:facts.join(", ")}})}async function runTokenRequest(oauth,provider,request){let response;try{response=await request()}catch(error){return Promise.reject(tokenRequestError(oauth,provider,error))}return{accessToken:response.access_token,...response.refresh_token!==void 0&&{refreshToken:response.refresh_token},...typeof response.expires_in=="number"&&{expiresAt:Math.floor(Date.now()/1e3)+response.expires_in},scopes:typeof response.scope=="string"?response.scope.split(/[\s,]+/).filter(Boolean):[...provider.scopes],...response.id_token!==void 0&&{idToken:response.id_token}}}function tokenRequestError(oauth,provider,error){let endpoint=`${provider.name} token endpoint`;if(error instanceof oauth.ResponseBodyError){let body=error.cause,original=isRecord(body)?body[UPSTREAM_CODE_FIELD]:void 0,upstreamCode=printable(typeof original=="string"?original:error.error,64),status=Number(error.response.headers.get(UPSTREAM_STATUS_HEADER))||error.status,description=error.error_description===void 0?void 0:printable(error.error_description);return new UpstreamError(error.error,`${endpoint} returned ${upstreamCode}${description===void 0?"":`: ${description}`}`,status>=500,{cause:error,upstreamCode,...description!==void 0&&{description},detail:`HTTP ${status}`})}if(error instanceof oauth.WWWAuthenticateChallengeError){let schemes=error.cause.map(challenge=>challenge.scheme);return new UpstreamError("invalid_client",`${endpoint} refused the client credentials`,error.status>=500,{cause:error,detail:`HTTP ${error.status}, WWW-Authenticate ${schemes.join(", ")}`})}if(error instanceof oauth.OperationProcessingError){let cause=error.cause,facts=[],status;if(cause instanceof Response)status=cause.status,facts.push(`HTTP ${status}`,`content-type ${cause.headers.get("content-type")??"none"}`);else if(isRecord(cause)&&isRecord(cause.body)){let fields=Object.keys(cause.body);facts.push(`fields ${fields.length>0?fields.join(", "):"none"}`)}return error.code!==void 0&&facts.push(error.code),new UpstreamError("server_error",`${endpoint} returned an unusable response: ${error.message}`,status!==void 0&&status>=500,{cause:error,detail:facts.join(", ")})}if(error instanceof Error&&(error.name==="TimeoutError"||error.name==="AbortError"))return new UpstreamError("temporarily_unavailable",`${endpoint} did not answer in time`,!0,{cause:error});if(error instanceof TypeError&&!("code"in error)){let cause=error.cause,reason=isRecord(cause)&&typeof cause.code=="string"?cause.code:cause instanceof Error?cause.message:error.message;return new UpstreamError("temporarily_unavailable",`${endpoint} is unreachable: ${printable(reason)}`,!0,{cause:error})}return new UpstreamError("server_error",`${endpoint} request failed: ${errorText(error)}`,!1,{cause:error})}function errorText(error){if(!(error instanceof Error))return printable(String(error));let code="code"in error&&typeof error.code=="string"?` [${error.code}]`:"";return printable(`${error.name}: ${error.message}${code}`)}var textEncoder=new TextEncoder,textDecoder=new TextDecoder("utf-8",{fatal:!0}),ENVELOPE_VERSION="v1",IV_BYTES=12,MIN_SECRET_LENGTH=32;function normalizeSecrets(secret){let secrets=Array.isArray(secret)?secret:[secret];if(secrets.length===0)throw new TypeError("oauthProxy secret must not be an empty array");for(let value of secrets)if(typeof value!="string"||value.length<MIN_SECRET_LENGTH)throw new TypeError(`oauthProxy secret must be a string of at least ${MIN_SECRET_LENGTH} characters`);return secrets}async function deriveKeyring(secrets){let all=await Promise.all(secrets.map(secret=>deriveKey(secret)));return{current:all[0],all}}async function randomKeyring(){return deriveKeyring([randomToken(32)])}async function deriveKey(secret){let ikm=await crypto.subtle.importKey("raw",textEncoder.encode(secret),"HKDF",!1,["deriveKey","deriveBits"]),hkdf=info=>({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(0),info:textEncoder.encode(`mcp-use/oauth-proxy/${info}`)}),[storage,cookieBits,kidBits]=await Promise.all([crypto.subtle.deriveKey(hkdf("storage"),ikm,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]),crypto.subtle.deriveBits(hkdf("cookie"),ikm,256),crypto.subtle.deriveBits(hkdf("kid"),ikm,64)]);return{kid:toHex(new Uint8Array(kidBits)),storage,cookie:new Uint8Array(cookieBits)}}async function encryptValue(keyring,storageKey,plaintext){let iv=crypto.getRandomValues(new Uint8Array(IV_BYTES)),ciphertext=await crypto.subtle.encrypt({name:"AES-GCM",iv,additionalData:textEncoder.encode(storageKey),tagLength:128},keyring.current.storage,textEncoder.encode(plaintext));return[ENVELOPE_VERSION,keyring.current.kid,base64UrlEncode(iv),base64UrlEncode(new Uint8Array(ciphertext))].join(".")}async function decryptValue(keyring,storageKey,envelope){let parts=envelope.split(".");if(parts.length!==4||parts[0]!==ENVELOPE_VERSION)return;let key=keyring.all.find(candidate=>candidate.kid===parts[1]);if(key!==void 0)try{let plaintext=await crypto.subtle.decrypt({name:"AES-GCM",iv:base64UrlDecode(parts[2]),additionalData:textEncoder.encode(storageKey),tagLength:128},key.storage,base64UrlDecode(parts[3]));return textDecoder.decode(plaintext)}catch{return}}function randomToken(bytes=32){return base64UrlEncode(crypto.getRandomValues(new Uint8Array(bytes)))}async function sha256(value){let digest=await crypto.subtle.digest("SHA-256",textEncoder.encode(value));return base64UrlEncode(new Uint8Array(digest))}function pkceChallenge(verifier){return sha256(verifier)}function timingSafeEqual(a,b){let left=textEncoder.encode(a),right=textEncoder.encode(b),difference=left.length^right.length,length=Math.max(left.length,right.length);for(let index=0;index<length;index++)difference|=(left[index]??0)^(right[index]??0);return difference===0}function base64UrlEncode(bytes){let binary="";for(let byte of bytes)binary+=String.fromCharCode(byte);return btoa(binary).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function base64UrlDecode(value){if(!/^[A-Za-z0-9_-]*$/.test(value))throw new TypeError("Invalid base64url value");let padded=value.replace(/-/g,"+").replace(/_/g,"/"),binary=atob(padded+"=".repeat((4-padded.length%4)%4)),bytes=new Uint8Array(binary.length);for(let index=0;index<binary.length;index++)bytes[index]=binary.charCodeAt(index);return bytes}function toHex(bytes){return Array.from(bytes,byte=>byte.toString(16).padStart(2,"0")).join("")}var MEMORY_STORAGE=Symbol.for("mcp-use.oauth.memoryStorage");function memoryStorage(){let values=new Map,read=key=>{let entry=values.get(key);if(entry!==void 0){if(entry.expiresAt<=Date.now()){values.delete(key);return}return entry.value}},write=(key,value,ttlSeconds)=>{if(values.size>1e4)for(let[candidate,entry]of values)entry.expiresAt<=Date.now()&&values.delete(candidate);values.set(key,{value,expiresAt:Date.now()+ttlSeconds*1e3})},storage={get:async key=>read(key),set:async(key,value,ttlSeconds)=>write(key,value,ttlSeconds),delete:async key=>{values.delete(key)},take:async key=>{let value=read(key);return values.delete(key),value},add:async(key,value,ttlSeconds)=>read(key)!==void 0?!1:(write(key,value,ttlSeconds),!0)};return Object.defineProperty(storage,MEMORY_STORAGE,{value:!0}),storage}function isMemoryStorage(storage){return storage[MEMORY_STORAGE]===!0}function assertStorage(storage){if(storage===null||typeof storage!="object")throw new TypeError("oauthProxy storage must be an object");for(let method of["get","set","delete","take","add"])if(typeof storage[method]!="function")throw new TypeError(`oauthProxy storage must implement ${method}()`)}var KEY_PREFIX="mcp-use:oauth:",SecureStore=class{#storage;#keyring;#prefix;#warned=new Set;constructor(storage,keyring,resource){this.#storage=storage,this.#keyring=keyring,this.#prefix=sha256(resource.href).then(hash=>`${KEY_PREFIX}${hash.slice(0,16)}:`)}async get(key){let fullKey=await this.#prefix+key;return this.#decode(key,fullKey,await this.#storage.get(fullKey))}async set(key,value,ttlSeconds){let fullKey=await this.#prefix+key;await this.#storage.set(fullKey,await this.#encode(fullKey,value),ttl(ttlSeconds))}async delete(key){await this.#storage.delete(await this.#prefix+key)}async take(key){let fullKey=await this.#prefix+key;return this.#decode(key,fullKey,await this.#storage.take(fullKey))}async add(key,value,ttlSeconds){let fullKey=await this.#prefix+key;return this.#storage.add(fullKey,await this.#encode(fullKey,value),ttl(ttlSeconds))}async#encode(fullKey,value){return encryptValue(await this.#keyring(),fullKey,JSON.stringify(value))}async#decode(key,fullKey,stored){if(typeof stored!="string")return;let keyring=await this.#keyring(),plaintext=await decryptValue(keyring,fullKey,stored);if(plaintext===void 0){this.#warnUnreadable(keyring,key,stored);return}try{return JSON.parse(plaintext)}catch{return}}#warnUnreadable(keyring,key,stored){let kid=printable(stored.split(".")[1]??"",32),known=keyring.all.some(entry=>entry.kid===kid),kind=key.split(":")[0]??"",id=known?`record:${kind}`:`kid:${kid}`;this.#warned.has(id)||(this.#warned.add(id),console.warn(known?`[mcp-use] oauthProxy: a stored "${kind}" record failed to decrypt and reads as absent. Is something else writing to the same keys?`:`[mcp-use] oauthProxy: stored records were encrypted with a secret this server does not have (key id "${kid}"), so they read as absent and those users must sign in again. If the secret changed, pass the old one after the new one to keep their sign-ins: secret: [newSecret, oldSecret].`))}};function ttl(seconds){return Math.max(1,Math.ceil(seconds))}export{normalizeSecrets,deriveKeyring,randomKeyring,randomToken,sha256,pkceChallenge,timingSafeEqual,isBuilding,upstream,assertRedirectUpstream,assertEndpoint,UpstreamError,printable,exchangeUpstreamCode,refreshUpstreamTokens,memoryStorage,isMemoryStorage,assertStorage,SecureStore};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{assertOAuthMetadata,assertSecureHttpUrl,isLocalhost,isRecord,parseAbsoluteUrl}from"./chunk-
|
|
1
|
+
import{assertOAuthMetadata,assertSecureHttpUrl,isLocalhost,isRecord,parseAbsoluteUrl}from"./chunk-JX52OYMQ.js";import{OAuthError,OAuthErrorCode}from"@modelcontextprotocol/server";function invalidToken(message,cause){let error=new OAuthError(OAuthErrorCode.InvalidToken,message);return cause!==void 0&&(error.cause=cause),error}import{OAuthError as OAuthError2}from"@modelcontextprotocol/server";import{createRemoteJWKSet,jwtVerify,errors}from"jose";function createJwtVerifier(options){let key=options.key??createRemoteJWKSet(options.jwksUrl),configuredResource=configuredResourceUrl(options.resource),configuredAudience=verifierAudience(options.audience);if(configuredAudience!==void 0&&options.issuerBoundAccessTokens===!0)throw new TypeError("JWT verifier cannot combine audience and issuer-bound access tokens");return{async verifyAccessToken(token){try{let{payload}=await jwtVerify(token,key,{issuer:options.issuer,...configuredAudience!==void 0&&{audience:configuredAudience},...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,configuredAudience!==void 0||options.issuerBoundAccessTokens===!0);return{token,clientId:clientId??"",scopes:normalizedStrings(claims.scope),expiresAt,extra:{payload:claims},resource}}catch(error){throw error instanceof OAuthError2?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 verifiedResource(claims,configuredResource,providerBindingWasValidated){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}if(providerBindingWasValidated)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 verifierAudience(value){if(value!==void 0){if(typeof value=="string"&&value.trim().length>0)return value;if(Array.isArray(value)&&value.length>0&&value.every(audience=>typeof audience=="string"&&audience.trim().length>0))return[...value];throw new TypeError("JWT verifier audience must be a non-empty string or string array")}}function validAudience(value){return typeof value=="string"||Array.isArray(value)&&value.length>0&&value.every(item=>typeof item=="string")}function configuredResourceUrl(value){let url;try{url=new URL(value)}catch{throw new TypeError(RESOURCE_URL_REQUIREMENT)}if(!isAllowedHttpUrl(url))throw new TypeError(RESOURCE_URL_REQUIREMENT);return url.pathname=url.pathname==="/"?"/":url.pathname.replace(/\/+$/,""),url}var RESOURCE_URL_REQUIREMENT="resource must use HTTPS, or HTTP for localhost, without credentials, query, or fragment";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 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(options.setup!==void 0&&typeof options.setup!="function")throw new TypeError("setup must be a function when provided");if(typeof options.oauthMetadata!="function"&&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.setup!==void 0&&{setup:options.setup},...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 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`)}function oauthEnvironmentValue(name){if(!(typeof process>"u"||process.env===void 0))return process.env[name]}export{invalidToken,createJwtVerifier,normalizedProviderUrl,providerEndpoint,payloadFromAuthInfo,requiredString,stringValue,booleanValue,recordValue,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function isRecord(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function trimTrailingSlashes(value){let end=value.length;for(;end>0&&value[end-1]==="/";)end--;return value.slice(0,end)}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`)}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")}export{isRecord,trimTrailingSlashes,isLocalhost,parseAbsoluteUrl,assertSecureHttpUrl,assertOAuthMetadata};
|
package/dist/config.d.ts
CHANGED
|
@@ -141,9 +141,9 @@ interface BaseServerConfig {
|
|
|
141
141
|
*
|
|
142
142
|
* `"stateless"` answers each legacy request with a fresh instance over a
|
|
143
143
|
* session-less streamable HTTP transport (2025 session operations — GET and
|
|
144
|
-
* DELETE — get `
|
|
145
|
-
* requests are refused with the
|
|
146
|
-
* the supported revisions.
|
|
144
|
+
* DELETE — and HEAD probes get an empty `204`). `"reject"` is modern-only
|
|
145
|
+
* strict: legacy-classified requests are refused with the
|
|
146
|
+
* unsupported-protocol-version error naming the supported revisions.
|
|
147
147
|
*
|
|
148
148
|
* @defaultValue `"stateless"`
|
|
149
149
|
*/
|
package/dist/index-node.js
CHANGED
|
@@ -768,7 +768,7 @@ ${cyan("=".repeat(80))}`),console.log(bold(cyan("[TRACE] Request Details"))),con
|
|
|
768
768
|
`)}function styleStatus(status){let text2=String(status);return status>=500?magenta(text2):status>=400?red(text2):status>=300?yellow(text2):green(text2)}function isNoisyRequest(httpMethod,pathname){return httpMethod!=="GET"&&httpMethod!=="HEAD"?!1:pathname.endsWith("/favicon.ico")}function formatRequestLogLine(line){let{description,detail}=line;return[...line.prefix===void 0?[]:[bold(line.prefix)],methodStyle(description.method)(description.method),...detail?.subject===void 0?[]:[bold(sanitize(detail.subject))],line.pathname,styleStatus(line.status),...description.client===void 0?[]:[dim(`client=${sanitize(description.client)}`)],dim(`${line.durationMs}ms`),...line.suffix].join(" ")}function requestLogger(options={}){return options.enabled===!1?(_request,next)=>next():async(request,next)=>{let level=resolveLogLevel(options.level),startedAt=Date.now(),httpMethod=request.method,pathname=new URL(request.url).pathname;if(isNoisyRequest(httpMethod,pathname))return next();let requestHeaders={};level==="trace"&&request.headers.forEach((value,key)=>{requestHeaders[key]=value});let requestBody;if(httpMethod!=="GET"&&httpMethod!=="HEAD"){let parsedBody=getRequestBag(request).parsedBody;if(parsedBody!==void 0)requestBody=parsedBody;else try{requestBody=await request.clone().json(),(request.headers.get("content-type")??"").includes("application/json")&&(getRequestBag(request).parsedBody=requestBody)}catch{}}let description=describeRequest(httpMethod,pathname,options.mcpPath,requestBody),logLine=(status,detail2,suffix2=[])=>{console.log(formatRequestLogLine({prefix:options.prefix,description,detail:detail2,pathname,status,durationMs:Date.now()-startedAt,suffix:suffix2}))},response;try{response=await next()}catch(error3){throw logLine(500,void 0,[red(`ERROR ${sanitize(error3 instanceof Error?error3.message:String(error3))}`)]),error3}let streaming=description.streaming||response.headers.get("content-type")?.split(";",1)[0]?.trim().toLowerCase()==="text/event-stream",detail=description.mcpRequest===void 0?void 0:formatDetail(description.mcpRequest),suffix=[];if(description.mcpRequest!==void 0&&detail!==void 0){let echoPayloads=level!=="info";echoPayloads&&detail.input!==void 0&&suffix.push(inlineJson(detail.input));let outcome=streaming?{errorMessage:null}:await extractResponseOutcome(response,request);echoPayloads&&description.mcpRequest.method==="tools/call"&&outcome.errorMessage===null&&outcome.result!==void 0&&suffix.push(dim("->"),inlineJson(compactToolResult(outcome.result))),outcome.errorMessage!==null?suffix.push(red(`ERROR ${sanitize(outcome.errorMessage)}`)):response.status>=400&&suffix.push(red(`ERROR (HTTP ${response.status})`))}logLine(response.status,detail,suffix);let oauthEndpoint=options.mcpPath!==void 0&&pathname.startsWith(pathUnderBase(options.mcpPath,"oauth/"));return level==="trace"&&!oauthEndpoint&&await printTraceDump(response,requestHeaders,requestBody,!streaming),response}}init_dist();init_fetch_app();import{trackBufferedResponse as trackBufferedResponse2}from"#mcp-use-buffered-response";function createMcpMount(factory,options={}){let{path="/mcp",handler:handlerOptions,authInfo:getAuthInfo}=options,legacyMode=handlerOptions?.legacy??"stateless",handler=createMcpHandler(factory,{legacy:"stateless",...handlerOptions});return{handler,fetch:async request=>{if(!matchesPath(request,path))return new Response("Not Found",{status:404});if(legacyMode==="stateless"){let method=request.method.toUpperCase();if(method==="GET"||method==="DELETE"||method==="HEAD")return new Response(null,{status:204})}let bag=getRequestBag(request),parsedBody=bag.parsedBody;if(parsedBody===void 0)try{parsedBody=await request.clone().json()}catch{}let capabilities=extractClientCapabilitiesFromBody(parsedBody);capabilities!==void 0&&stashClientCapabilities(request,capabilities);let authInfo=getAuthInfo?.(request)??bag.authInfo,response=await handler.fetch(request,{...parsedBody!==void 0&&{parsedBody},...authInfo!==void 0&&{authInfo}});return response.headers.get("content-type")?.toLowerCase().includes("application/json")?"Bun"in globalThis&&response.body!==null?new Response(await response.arrayBuffer(),{status:response.status,statusText:response.statusText,headers:response.headers}):trackBufferedResponse2(request,response):response}}}function object2(value,label){if(value===null||typeof value!="object"||Array.isArray(value))throw new TypeError(`${label} must be an object`);return value}function array2(value,label){if(!Array.isArray(value))throw new TypeError(`${label} must be an array`);return value}function nonBlank(value,label){if(typeof value!="string"||!value.trim())throw new TypeError(`${label} must be a non-blank string`)}function standard(json,validate){return{"~standard":{version:1,vendor:"mcp-use",jsonSchema:{input:()=>json,output:()=>json},async validate(value){try{return{value:await validate(value)}}catch(error3){return{issues:[{message:error3 instanceof Error?error3.message:String(error3)}]}}}}}}function prepareSettings(options){let readTool=options.readTool??"settings.read",updateTool=options.updateTool??"settings.update";if(nonBlank(readTool,"readTool"),nonBlank(updateTool,"updateTool"),readTool===updateTool)throw new TypeError("Settings read and update tools must have different names");object2(options.fields,"fields");let fields=Object.entries(options.fields).map(([name,field])=>[name,{...field}]);if(!fields.length)throw new TypeError("Settings require at least one field");let properties={};for(let[name,field]of fields){if(nonBlank(field.title,`Setting ${name} title`),field.description!==void 0&&typeof field.description!="string")throw new TypeError(`Setting ${name} description must be a string`);let outputProperty=field.schema["~standard"].jsonSchema.output({target:"draft-2020-12"}),property=field.schema["~standard"].jsonSchema.input({target:"draft-2020-12"});if(!["boolean","string","number","integer"].includes(String(property.type))||outputProperty.type!==property.type||["$ref","anyOf","oneOf","allOf"].some(key=>key in property)||property.enum!==void 0&&(property.type!=="string"||!Array.isArray(property.enum)||!property.enum.length||!property.enum.every(item=>typeof item=="string")))throw new TypeError(`Unsupported native setting ${name}: use boolean, string, string enum, number, or integer`);let wireProperty=structuredClone(property);delete wireProperty.default,Object.defineProperty(properties,name,{enumerable:!0,value:{...wireProperty,title:field.title,...field.description!==void 0&&{description:field.description}}})}let schema2={type:"object",properties,required:fields.map(([name])=>name),additionalProperties:!1},layout=options.layout===void 0?void 0:structuredClone(options.layout);if(layout!==void 0)for(let groupValue of array2(layout,"Settings layout")){let group=object2(groupValue,"Settings layout group");if(group.kind!=="group")throw new TypeError("Settings layout groups must have kind 'group'");nonBlank(group.title,"Settings layout group title");for(let itemValue of array2(group.items,"Settings layout group items")){let item=object2(itemValue,"Settings layout item");if(item.kind==="property"){if(nonBlank(item.property,"Settings layout property"),!Object.hasOwn(properties,item.property))throw new TypeError(`Settings layout references unknown setting: ${item.property}`)}else if(item.kind==="tool"){if(nonBlank(item.tool,"Settings layout action tool"),nonBlank(item.title,"Settings layout action title"),item.description!==void 0&&typeof item.description!="string")throw new TypeError("Settings layout action description must be a string")}else throw new TypeError("Settings layout items must have kind 'property' or 'tool'")}}let validateValues=async(value,partial2=!1)=>{let values=object2(value,partial2?"set":"values");for(let name of Object.keys(values))if(!Object.hasOwn(properties,name))throw new TypeError(`Unknown setting: ${name}`);if(partial2&&!Object.keys(values).length)throw new TypeError("Set at least one setting");let result={};for(let[name,field]of fields){if(!Object.hasOwn(values,name)){if(!partial2)throw new TypeError(`Missing effective setting: ${name}`);continue}let parsed=await field.schema["~standard"].validate(values[name]);if(parsed.issues!==void 0)throw new TypeError(`Invalid setting ${name}: ${parsed.issues.map(issue2=>issue2.message).join(", ")}`);if(parsed.value===void 0||!["string","boolean","number"].includes(typeof parsed.value)||typeof parsed.value=="number"&&!Number.isFinite(parsed.value))throw new TypeError(`Invalid primitive setting: ${name}`);if(!Object.is(parsed.value,values[name]))throw new TypeError(`Setting ${name} schema must not transform values`);Object.defineProperty(result,name,{enumerable:!0,value:parsed.value})}return result},emptySchema=standard({type:"object",additionalProperties:!1},value=>{if(Object.keys(object2(value,"arguments")).length)throw new TypeError("Settings read accepts empty arguments");return{}}),updateInput=standard({type:"object",properties:{set:{...schema2,required:[],minProperties:1}},required:["set"],additionalProperties:!1},async value=>{let input=object2(value,"arguments");if(Object.keys(input).some(key=>key!=="set"))throw new TypeError("Unknown settings update argument");return{set:await validateValues(input.set,!0)}}),readOutput=standard({type:"object",properties:{schema:{type:"object"},values:schema2,layout:{type:"array",items:{type:"object",properties:{kind:{const:"group"},title:{type:"string"},items:{type:"array",items:{type:"object"}}},required:["kind","title","items"]}}},required:["schema","values"]},async value=>{let output=object2(value,"settings result");return{...output,values:await validateValues(output.values)}}),updateOutput=standard({type:"object",properties:{values:schema2},required:["values"]},async value=>({values:await validateValues(object2(value,"settings result").values)}));return{capability:{readTool,updateTool},schema:schema2,layout,readDefinition:{name:readTool,inputSchema:emptySchema,outputSchema:readOutput,annotations:{readOnlyHint:!0}},updateDefinition:{name:updateTool,inputSchema:updateInput,outputSchema:updateOutput}}}init_dist();function createPrefixCompletion(values){let strings=values.map(String);return value=>{let prefix=String(value??"").toLowerCase();return strings.filter(candidate=>candidate.toLowerCase().startsWith(prefix))}}function completable2(schema2,complete){return typeof complete=="function"?completable(schema2,(value,context)=>complete(String(value??""),context)):completable(schema2,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}init_dist();var inputSchema=fromJsonSchema2({type:"object",properties:{query:{type:"string"}},required:["query"]}),outputSchema=fromJsonSchema2({type:"object",properties:{items:{type:"array",items:ResourceLinkSchema["~standard"].jsonSchema.output({target:"draft-2020-12"})}},required:["items"]});function record2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:{}}function prepareMentions(options){if(typeof options.name!="string"||!options.name.trim())throw new TypeError("Mention tool name must be a non-blank string");if(typeof options.search!="function")throw new TypeError("Mention search must be a callback");let{search:_search,...descriptor}=options;return{...descriptor,inputSchema,outputSchema,annotations:{readOnlyHint:!0,...options.annotations},_meta:{...options._meta,"openai/extensions":{...record2(options._meta?.["openai/extensions"]),"mentions/search":{}}}}}function finalizeMentionsMeta(definition,metadata){let rawUi=record2(definition._meta?.ui),visibility=definition.visibility!==void 0?[definition.visibility]:Array.isArray(rawUi.visibility)?rawUi.visibility:[];return{...metadata,ui:{...record2(metadata?.ui),visibility:[...new Set([...visibility,"app"])]}}}init_dist();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&&!matchesPattern2(rule.operationId,operation.operation.operationId??"")||rule.path&&!matchesPattern2(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 matchesPattern2(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(`
|
|
769
769
|
|
|
770
770
|
`)}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={},required2=[];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")&&required2.push(inputName)}let bodySchema=getJsonRequestBodySchema(operation.requestBody);bodySchema!==void 0&&inputBindings.bodyInputName!==void 0&&(properties[inputBindings.bodyInputName]=transformSchema(spec,bodySchema),operation.requestBody?.required&&required2.push(inputBindings.bodyInputName));let definitions=createSchemaDefinitions(spec),schema2={type:"object",properties,additionalProperties:!1,...required2.length>0&&{required:required2},...definitions!==void 0&&{$defs:definitions}};return fromJsonSchema2(schema2)}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,schema2]of Object.entries(schemas))definitions[name]=transformSchemaNode(spec,schema2,new Set);return definitions}function transformSchema(spec,schema2){let transformed=transformSchemaNode(spec,schema2,new Set);return readRecord(transformed)??{}}function transformSchemaNode(spec,value,resolvingRefs){if(Array.isArray(value))return value.map(item=>transformSchemaNode(spec,item,resolvingRefs));let object5=readRecord(value);if(object5===void 0)return value;let ref=typeof object5.$ref=="string"?object5.$ref:void 0,siblings={};for(let[key,child]of Object.entries(object5))key!=="$ref"&&(key==="nullable"&&typeof child=="boolean"||isExclusiveBoundKey(key)&&typeof child=="boolean"||(siblings[key]=transformSchemaNode(spec,child,resolvingRefs)));for(let[boundKey,exclusiveKey]of EXCLUSIVE_BOUND_KEYS)object5[exclusiveKey]===!0&&typeof object5[boundKey]=="number"&&(siblings[exclusiveKey]=object5[boundKey],delete siblings[boundKey]);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 object5.nullable===!0?{anyOf:[transformed,{type:"null"}]}:transformed}var EXCLUSIVE_BOUND_KEYS=[["minimum","exclusiveMinimum"],["maximum","exclusiveMaximum"]];function isExclusiveBoundKey(key){return key==="exclusiveMinimum"||key==="exclusiveMaximum"}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,url2=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(url2,{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 text2=await response.text();try{let data=JSON.parse(text2);return{content:[{type:"text",text:JSON.stringify(data)}],structuredContent:data}}catch{return{content:[{type:"text",text:text2}]}}}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]??""))}),url2=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(url2,parameter.name,value)}return url2.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(url2,name,value){if(Array.isArray(value)){for(let item of value)item!=null&&item!==""&&url2.searchParams.append(name,String(item));return}url2.searchParams.set(name,String(value))}function ensureTrailingSlash(url2){return url2.endsWith("/")?url2:`${url2}/`}function hasHeader(headers,name){return Object.keys(headers).some(headerName=>headerName.toLowerCase()===name)}function isReferenceObject(value){let object5=readRecord(value);return object5!==void 0&&typeof object5.$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 object5=readRecord(current);if(object5===void 0||!(segment in object5))return;current=object5[segment]}return current}function readRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:void 0}init_dist();init_dist();init_fetch_app();function isRecord(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function isLocalhost(url2){let hostname=url2.hostname.toLowerCase();return hostname==="localhost"||hostname.endsWith(".localhost")||hostname==="[::1]"||/^127(?:\.\d{1,3}){3}$/.test(hostname)}function parseAbsoluteUrl(value,name){let url2;try{url2=new URL(value)}catch{throw new Error(`${name} must be an absolute URL`)}if(url2.origin==="null"||url2.username!==""||url2.password!=="")throw new Error(`${name} must be an absolute URL without credentials`);return url2}function assertSecureHttpUrl(url2,name){if(url2.protocol!=="https:"&&!(url2.protocol==="http:"&&isLocalhost(url2)))throw new Error(`${name} must use HTTPS, or HTTP for localhost`)}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")}init_dist();function invalidToken(message,cause){let error3=new OAuthError(OAuthErrorCode.InvalidToken,message);return cause!==void 0&&(error3.cause=cause),error3}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(resource2,basePath){let normalizedBasePath=normalizeBasePath(basePath),url2=parseAbsoluteUrl(resource2,"OAuth resource");if(url2.search!==""||url2.hash!=="")throw new Error("OAuth resource must not include a query string or fragment");if(assertSecureHttpUrl(url2,"OAuth resource"),normalizePathname(url2.pathname)!==normalizedBasePath)throw new Error(`OAuth resource path must exactly match basePath (${normalizedBasePath})`);return url2.pathname=normalizedBasePath,url2}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(error3){throw invalidToken("Token identity mapping failed",error3)}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 resource2=value;if(!/^https?:$/.test(resource2.protocol)||resource2.username!==""||resource2.password!==""||resource2.search!==""||resource2.hash!==""||resource2.protocol==="http:"&&!isLocalhost(resource2))throw invalidToken("Token resource must be an absolute HTTPS URL, or HTTP URL for localhost");return normalizeResourceUrl(resource2)}function normalizeResourceUrl(resource2){let normalized=new URL(resource2);return normalized.pathname=normalized.pathname==="/"?"/":normalized.pathname.replace(/\/+$/,""),normalized}function resolveOAuthMetadata(provider,resource2){let metadata=provider.oauthMetadata;if(typeof metadata!="function")return metadata;let resolved=metadata(new URL(resource2.href));return assertOAuthMetadata(resolved),resolved}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 url2=parseAbsoluteUrl(value,name);if(url2.pathname!=="/"||url2.search!==""||url2.hash!==""||url2.username!==""||url2.password!=="")throw new Error(`${name} must be an absolute origin without a path`);return url2}function appendBasePath(origin,basePath){let resource2=new URL(origin.origin);return resource2.pathname=basePath,resource2}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){if(pathname==="/")return"/";let end=pathname.length;for(;end>0&&pathname.charCodeAt(end-1)===47;)end--;return pathname.slice(0,end)}function oauthMetadata(provider,resource2){let options=getOAuthProviderOptions(provider),metadata=resolveOAuthMetadata(provider,resource2);return async(request,next)=>{let response=oauthMetadataResponse(request,{oauthMetadata:metadata,resourceServerUrl:resource2,...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}init_dist();import{createRemoteJWKSet,jwtVerify,errors}from"jose";var textEncoder=new TextEncoder,textDecoder=new TextDecoder("utf-8",{fatal:!0});function isBuilding(){return typeof process>"u"||process.env===void 0?!1:process.env.MCP_USE_PHASE==="build"}var DCR_CLIENT_TTL=365*24*60*60;var CIMD_MAX_BYTES=5*1024;var CIMD_CACHE_MS=300*1e3;var REFRESH_TTL=720*60*60;var UPSTREAM_TTL=1440*60*60,REMEMBER_TTL=365*24*60*60;init_policy();function resolveToolInputSchema(definition){return definition.inputSchema??definition.schema}init_dist();var META_KEY="openai/ui";function record3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function validateEntrypointInput(definition){let entrypoints=definition.view?.entrypoints;if(!entrypoints?.length)return;let schema2=resolveToolInputSchema(definition),validate=schema2?fromJsonSchema2(schema2["~standard"].jsonSchema.input({target:"draft-2020-12"}))["~standard"].validate:void 0;for(let entrypoint of entrypoints){let payloads=entrypoint.type==="file"?entrypoint.extensions.map(extension=>({file:{name:`file${extension}`,resourceUri:"host-resource://opaque-handle"}})):[{}];if(entrypoint.type==="file"&&!validate)throw new TypeError(`Tool "${definition.name}" file entrypoint requires an inputSchema accepting { file: { name, resourceUri } }.`);for(let payload of payloads){let result=validate?.(payload);if(result&&("then"in result||result.issues))throw new TypeError(`Tool "${definition.name}" ${entrypoint.type} entrypoint launch arguments do not satisfy its inputSchema.`)}}}function buildEntrypointMeta(definition){let entrypoints=definition.view?.entrypoints;if(entrypoints===void 0)return definition._meta;let existing=definition._meta?.[META_KEY];return{...definition._meta,[META_KEY]:{...record3(existing)?existing:{},entrypoints:entrypoints.map(entry=>entry.type==="file"?{type:entry.type,extensions:[...entry.extensions]}:{type:entry.type})}}}var EVENT="mcp_use_sdk_event",ENDPOINT="https://eu.i.posthog.com/i/v0/e/",TOKEN="phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI",CONTENT=/(^|_)(arguments?|args|body|command|headers?|location|message|organization|path|query|response|secret|subject|token|uri|url|user_agent)(_|$)/i,RESERVED=new Set("feature action sdk_generation telemetry_schema_version sdk_package sdk_version server_id runtime_id identity_stability distinct_id validation_run_id is_validation".split(" ")),runtimeId;function getRuntimeId(){return runtimeId??=crypto.randomUUID(),runtimeId}var once=new Set,pending=new Set,identities=new Map;function hasControl(value){return[...value].some(character=>{let code=character.charCodeAt(0);return code<32||code===127})}function env(name){return typeof process>"u"?void 0:process.env?.[name]}function safeEnv(name){let value=env(name);return value!==void 0&&value.length>0&&value.length<=128&&!hasControl(value)?value:void 0}function canPersistTelemetryIdentity(){return typeof process>"u"||process.versions?.node===void 0?!1:!("Deno"in globalThis)}function disabled(){if(env("MCP_USE_ANONYMIZED_TELEMETRY")==="false")return!0;try{return globalThis.__MCP_USE_ANONYMIZED_TELEMETRY__===!1||typeof localStorage<"u"&&localStorage.getItem("MCP_USE_ANONYMIZED_TELEMETRY")==="false"}catch{return!1}}function isUsageDisabled(){return disabled()}function clean(properties){return Object.fromEntries(Object.entries(properties).filter(([key,value])=>key.length>128||hasControl(key)||key.startsWith("$")||RESERVED.has(key)||CONTENT.test(key)||value===void 0?!1:typeof value=="string"?value.length<=128&&!hasControl(value):typeof value=="boolean"||typeof value=="number"&&Number.isFinite(value)))}async function identity(serverRoot){let projectId=safeEnv("MCP_USE_TELEMETRY_PROJECT_ID");if(projectId!==void 0)return{id:projectId,stability:"project"};if(serverRoot===void 0||!canPersistTelemetryIdentity())return{id:getRuntimeId(),stability:"process"};let existing=identities.get(serverRoot);if(existing!==void 0)return existing;let resolving=(async()=>{try{let fs=await import("fs/promises"),directory=`${serverRoot}/.mcp-use`,file=`${directory}/usage.json`,read=async()=>{try{let value=JSON.parse(await fs.readFile(file,"utf8"));if(typeof value=="object"&&value!==null&&"schemaVersion"in value&&value.schemaVersion===1&&"serverId"in value&&typeof value.serverId=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value.serverId))return value.serverId}catch{}},stored=await read();if(stored!==void 0)return{id:stored,stability:"server"};await fs.mkdir(directory,{recursive:!0,mode:448});let created=crypto.randomUUID();try{return await fs.writeFile(file,`${JSON.stringify({schemaVersion:1,serverId:created})}
|
|
771
|
-
`,{flag:"wx",mode:384}),{id:created,stability:"server"}}catch{let raced=await read();if(raced!==void 0)return{id:raced,stability:"server"}}}catch{}return{id:getRuntimeId(),stability:"process"}})();return identities.set(serverRoot,resolving),resolving}function capture(feature,action,properties,options,resolveIdentity){let validationId=safeEnv("MCP_USE_TELEMETRY_VALIDATION_ID");if(disabled()||env("NODE_ENV")==="test"&&validationId===void 0||pending.size>=16)return;if(options.onceKey!==void 0){if(once.has(options.onceKey))return;once.add(options.onceKey)}let rate=Math.max(0,Math.min(1,options.sampleRate??1));if(validationId===void 0&&Math.random()>=rate)return;let request=(async()=>{try{let resolvedIdentity=await resolveIdentity(),body=JSON.stringify({api_key:TOKEN,event:EVENT,properties:{...clean(properties),feature,action,sdk_generation:"v2",telemetry_schema_version:2,sdk_package:"mcp-use",sdk_version:"2.10.0
|
|
771
|
+
`,{flag:"wx",mode:384}),{id:created,stability:"server"}}catch{let raced=await read();if(raced!==void 0)return{id:raced,stability:"server"}}}catch{}return{id:getRuntimeId(),stability:"process"}})();return identities.set(serverRoot,resolving),resolving}function capture(feature,action,properties,options,resolveIdentity){let validationId=safeEnv("MCP_USE_TELEMETRY_VALIDATION_ID");if(disabled()||env("NODE_ENV")==="test"&&validationId===void 0||pending.size>=16)return;if(options.onceKey!==void 0){if(once.has(options.onceKey))return;once.add(options.onceKey)}let rate=Math.max(0,Math.min(1,options.sampleRate??1));if(validationId===void 0&&Math.random()>=rate)return;let request=(async()=>{try{let resolvedIdentity=await resolveIdentity(),body=JSON.stringify({api_key:TOKEN,event:EVENT,properties:{...clean(properties),feature,action,sdk_generation:"v2",telemetry_schema_version:2,sdk_package:"mcp-use",sdk_version:"2.10.0",server_id:resolvedIdentity.id,runtime_id:getRuntimeId(),identity_stability:resolvedIdentity.stability,distinct_id:resolvedIdentity.id,sample_rate:validationId===void 0?rate:1,$process_person_profile:!1,$geoip_disable:!0,...validationId!==void 0&&{is_validation:!0,validation_run_id:validationId}}});await fetch(ENDPOINT,{method:"POST",headers:{"content-type":"application/json"},keepalive:!0,body})}catch{return}})();pending.add(request),request.then(()=>pending.delete(request))}function recordUsage(feature,action,properties={},options={}){capture(feature,action,properties,options,()=>identity(options.serverRoot))}init_dist();function schema(validateValue){return{"~standard":{version:1,vendor:"mcp-use",validate(value){try{return{value:validateValue(value)}}catch(error3){return{issues:[{message:error3 instanceof Error?error3.message:String(error3)}]}}}}}}function object3(value){if(typeof value!="object"||value===null||Array.isArray(value))throw new TypeError("params must be an object");return value}var listParams=schema(value=>{let cursor=object3(value).cursor;if(cursor!==void 0&&typeof cursor!="string")throw new TypeError("cursor must be a string");return cursor===void 0?{}:{cursor}}),uriParams=schema(value=>{let params=object3(value);if(typeof params.uri!="string")throw new TypeError("uri must be a string");if(params.cursor!==void 0&&typeof params.cursor!="string")throw new TypeError("cursor must be a string");return{uri:params.uri,...typeof params.cursor=="string"&&{cursor:params.cursor}}}),anyResult=schema(value=>object3(value));function decodePathSegment(value){try{return decodeURIComponent(value)}catch{return value}}function registerSkillsRuntime(server,snapshot){let skills=new Map(snapshot.skills.map(skill=>[skill.uri,skill]));for(let resource2 of snapshot.resources)server.registerResource(resource2.uri,resource2.uri,{title:resource2.name,mimeType:resource2.mimeType},async()=>({contents:[{uri:resource2.uri,mimeType:resource2.mimeType,...resource2.text!==void 0?{text:resource2.text}:{blob:resource2.blob}}]}));server.server.setRequestHandler("skills/list",{params:listParams,result:anyResult},async()=>({skills:snapshot.skills})),server.server.setRequestHandler("skills/get",{params:uriParams,result:anyResult},async({uri})=>{let skill=skills.get(uri);if(skill===void 0)throw new ProtocolError(INVALID_PARAMS,`Unknown skill: ${uri}`);return{skill}}),server.server.setRequestHandler("resources/directory/read",{params:uriParams,result:anyResult},async({uri})=>{let normalized=uri.replace(/\/$/,""),knownDirectories=new Set(snapshot.directories.map(item=>item.uri)),prefix=`${normalized}/`,children=new Map;for(let resource2 of snapshot.resources){if(!resource2.uri.startsWith(prefix))continue;let remainder=resource2.uri.slice(prefix.length),[name]=remainder.split("/");if(name===void 0||name==="")continue;let childUri=`${normalized}/${name}`;children.set(childUri,{uri:childUri,name:decodePathSegment(name),mimeType:remainder.includes("/")?"inode/directory":resource2.mimeType})}for(let directory of snapshot.directories){if(!directory.uri.startsWith(prefix))continue;let remainder=directory.uri.slice(prefix.length);remainder===""||remainder.includes("/")||children.set(directory.uri,{uri:directory.uri,name:directory.name,mimeType:"inode/directory"})}if(!knownDirectories.has(normalized))throw new ProtocolError(INVALID_PARAMS,`Unknown skill directory: ${uri}`);return{resources:[...children.values()].sort((left,right)=>left.uri.localeCompare(right.uri))}})}var SKILLS_EXTENSION_ID="io.modelcontextprotocol/skills",registerSkills=Symbol.for("mcp-use.registerSkills");var registerViews=Symbol("mcp-use/registerViews");init_fetch_app();function resolveAssetUrl(assetPath,origin){if(!assetPath.startsWith("/"))throw new Error(`View manifest asset path must be origin-absolute (start with "/"); got ${JSON.stringify(assetPath)}`);return`${origin}${assetPath}`}function viewAssetsBasePath(basePath,viewName){return`${pathUnderBase(basePath,`_mcp-use/views/${viewName}`)}/`}function resolveExternalAssetUrl(assetPath,assetsBase,basePath,viewName){return assetPath.startsWith("http://")||assetPath.startsWith("https://")||assetPath.startsWith("data:")?assetPath:assetPath.startsWith("/")?resolveAssetUrl(assetPath,assetsBase):`${assetsBase}${viewAssetsBasePath(basePath,viewName)}${assetPath.replace(/^\/+/,"")}`}function resolvePublicBase(assetsBase,basePath){return`${assetsBase}${pathUnderBase(basePath,"_mcp-use/public")}/`}function escapeInlineScript(code){return code.replaceAll(/<\/script/gi,"<\\/script").replaceAll("<!--","\\x3C!--")}function escapeInlineStyle(css2){return css2.replaceAll(/<\/style/gi,"<\\/style")}function escapeHtml(value){return value.replaceAll("&","&").replaceAll('"',""").replaceAll("<","<").replaceAll(">",">")}var VIEW_BOOTSTRAP_STYLE=`<style>
|
|
772
772
|
html,body,#root{background:transparent}
|
|
773
773
|
html,body{margin:0}
|
|
774
774
|
#root[data-mcp-use-loading]{display:flex;min-height:100vh;align-items:center;justify-content:center;flex-direction:column;gap:10px;color:rgba(127,127,127,.9)}
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,8 @@ ${z("=".repeat(80))}`),console.log(Oe(z("[TRACE] Request Details"))),console.log
|
|
|
3
3
|
... (truncated, ${i.length-Ae} more characters)`:i)}}}catch{console.log(`${P("Response Body:")} (unable to read)`)}console.log(`${z("=".repeat(80))}
|
|
4
4
|
`)}o(ro,"printTraceDump");function oo(e){let t=String(e);return e>=500?Kt(t):e>=400?oe(t):e>=300?P(t):Wt(t)}o(oo,"styleStatus");function so(e,t){return e!=="GET"&&e!=="HEAD"?!1:t.endsWith("/favicon.ico")}o(so,"isNoisyRequest");function io(e){let{description:t,detail:n}=e;return[...e.prefix===void 0?[]:[Oe(e.prefix)],Zr(t.method)(t.method),...n?.subject===void 0?[]:[Oe(N(n.subject))],e.pathname,oo(e.status),...t.client===void 0?[]:[Ue(`client=${N(t.client)}`)],Ue(`${e.durationMs}ms`),...e.suffix].join(" ")}o(io,"formatRequestLogLine");function Ie(e={}){return e.enabled===!1?(t,n)=>n():async(t,n)=>{let r=Kr(e.level),s=Date.now(),i=t.method,a=new URL(t.url).pathname;if(so(i,a))return n();let d={};r==="trace"&&t.headers.forEach((y,T)=>{d[T]=y});let c;if(i!=="GET"&&i!=="HEAD"){let y=v(t).parsedBody;if(y!==void 0)c=y;else try{c=await t.clone().json(),(t.headers.get("content-type")??"").includes("application/json")&&(v(t).parsedBody=c)}catch{}}let u=Qr(i,a,e.mcpPath,c),l=o((y,T,x=[])=>{console.log(io({prefix:e.prefix,description:u,detail:T,pathname:a,status:y,durationMs:Date.now()-s,suffix:x}))},"logLine"),p;try{p=await n()}catch(y){throw l(500,void 0,[oe(`ERROR ${N(y instanceof Error?y.message:String(y))}`)]),y}let h=u.streaming||p.headers.get("content-type")?.split(";",1)[0]?.trim().toLowerCase()==="text/event-stream",f=u.mcpRequest===void 0?void 0:Gr(u.mcpRequest),m=[];if(u.mcpRequest!==void 0&&f!==void 0){let y=r!=="info";y&&f.input!==void 0&&m.push(Bt(f.input));let T=h?{errorMessage:null}:await to(p,t);y&&u.mcpRequest.method==="tools/call"&&T.errorMessage===null&&T.result!==void 0&&m.push(Ue("->"),Bt(no(T.result))),T.errorMessage!==null?m.push(oe(`ERROR ${N(T.errorMessage)}`)):p.status>=400&&m.push(oe(`ERROR (HTTP ${p.status})`))}l(p.status,f,m);let g=e.mcpPath!==void 0&&a.startsWith(C(e.mcpPath,"oauth/"));return r==="trace"&&!g&&await ro(p,d,c,!h),p}}o(Ie,"requestLogger");import{createMcpHandler as ao}from"@modelcontextprotocol/server";import{trackBufferedResponse as co}from"#mcp-use-buffered-response";function Le(e,t={}){let{path:n="/mcp",handler:r,authInfo:s}=t,i=r?.legacy??"stateless",a=ao(e,{legacy:"stateless",...r});return{handler:a,fetch:o(async c=>{if(!pe(c,n))return new Response("Not Found",{status:404});if(i==="stateless"){let g=c.method.toUpperCase();if(g==="GET"||g==="DELETE"||g==="HEAD")return new Response(null,{status:204})}let u=v(c),l=u.parsedBody;if(l===void 0)try{l=await c.clone().json()}catch{}let p=Ut(l);p!==void 0&&Ot(c,p);let h=s?.(c)??u.authInfo,f=await a.fetch(c,{...l!==void 0&&{parsedBody:l},...h!==void 0&&{authInfo:h}});return f.headers.get("content-type")?.toLowerCase().includes("application/json")?"Bun"in globalThis&&f.body!==null?new Response(await f.arrayBuffer(),{status:f.status,statusText:f.statusText,headers:f.headers}):co(c,f):f},"fetch")}}o(Le,"createMcpMount");function A(e,t){if(e===null||typeof e!="object"||Array.isArray(e))throw new TypeError(`${t} must be an object`);return e}o(A,"object");function Gt(e,t){if(!Array.isArray(e))throw new TypeError(`${t} must be an array`);return e}o(Gt,"array");function L(e,t){if(typeof e!="string"||!e.trim())throw new TypeError(`${t} must be a non-blank string`)}o(L,"nonBlank");function se(e,t){return{"~standard":{version:1,vendor:"mcp-use",jsonSchema:{input:o(()=>e,"input"),output:o(()=>e,"output")},async validate(n){try{return{value:await t(n)}}catch(r){return{issues:[{message:r instanceof Error?r.message:String(r)}]}}}}}}o(se,"standard");function Yt(e){let t=e.readTool??"settings.read",n=e.updateTool??"settings.update";if(L(t,"readTool"),L(n,"updateTool"),t===n)throw new TypeError("Settings read and update tools must have different names");A(e.fields,"fields");let r=Object.entries(e.fields).map(([f,m])=>[f,{...m}]);if(!r.length)throw new TypeError("Settings require at least one field");let s={};for(let[f,m]of r){if(L(m.title,`Setting ${f} title`),m.description!==void 0&&typeof m.description!="string")throw new TypeError(`Setting ${f} description must be a string`);let g=m.schema["~standard"].jsonSchema.output({target:"draft-2020-12"}),y=m.schema["~standard"].jsonSchema.input({target:"draft-2020-12"});if(!["boolean","string","number","integer"].includes(String(y.type))||g.type!==y.type||["$ref","anyOf","oneOf","allOf"].some(x=>x in y)||y.enum!==void 0&&(y.type!=="string"||!Array.isArray(y.enum)||!y.enum.length||!y.enum.every(x=>typeof x=="string")))throw new TypeError(`Unsupported native setting ${f}: use boolean, string, string enum, number, or integer`);let T=structuredClone(y);delete T.default,Object.defineProperty(s,f,{enumerable:!0,value:{...T,title:m.title,...m.description!==void 0&&{description:m.description}}})}let i={type:"object",properties:s,required:r.map(([f])=>f),additionalProperties:!1},a=e.layout===void 0?void 0:structuredClone(e.layout);if(a!==void 0)for(let f of Gt(a,"Settings layout")){let m=A(f,"Settings layout group");if(m.kind!=="group")throw new TypeError("Settings layout groups must have kind 'group'");L(m.title,"Settings layout group title");for(let g of Gt(m.items,"Settings layout group items")){let y=A(g,"Settings layout item");if(y.kind==="property"){if(L(y.property,"Settings layout property"),!Object.hasOwn(s,y.property))throw new TypeError(`Settings layout references unknown setting: ${y.property}`)}else if(y.kind==="tool"){if(L(y.tool,"Settings layout action tool"),L(y.title,"Settings layout action title"),y.description!==void 0&&typeof y.description!="string")throw new TypeError("Settings layout action description must be a string")}else throw new TypeError("Settings layout items must have kind 'property' or 'tool'")}}let d=o(async(f,m=!1)=>{let g=A(f,m?"set":"values");for(let T of Object.keys(g))if(!Object.hasOwn(s,T))throw new TypeError(`Unknown setting: ${T}`);if(m&&!Object.keys(g).length)throw new TypeError("Set at least one setting");let y={};for(let[T,x]of r){if(!Object.hasOwn(g,T)){if(!m)throw new TypeError(`Missing effective setting: ${T}`);continue}let b=await x.schema["~standard"].validate(g[T]);if(b.issues!==void 0)throw new TypeError(`Invalid setting ${T}: ${b.issues.map(w=>w.message).join(", ")}`);if(b.value===void 0||!["string","boolean","number"].includes(typeof b.value)||typeof b.value=="number"&&!Number.isFinite(b.value))throw new TypeError(`Invalid primitive setting: ${T}`);if(!Object.is(b.value,g[T]))throw new TypeError(`Setting ${T} schema must not transform values`);Object.defineProperty(y,T,{enumerable:!0,value:b.value})}return y},"validateValues"),c=se({type:"object",additionalProperties:!1},f=>{if(Object.keys(A(f,"arguments")).length)throw new TypeError("Settings read accepts empty arguments");return{}}),u=se({type:"object",properties:{set:{...i,required:[],minProperties:1}},required:["set"],additionalProperties:!1},async f=>{let m=A(f,"arguments");if(Object.keys(m).some(g=>g!=="set"))throw new TypeError("Unknown settings update argument");return{set:await d(m.set,!0)}}),p=se({type:"object",properties:{schema:{type:"object"},values:i,layout:{type:"array",items:{type:"object",properties:{kind:{const:"group"},title:{type:"string"},items:{type:"array",items:{type:"object"}}},required:["kind","title","items"]}}},required:["schema","values"]},async f=>{let m=A(f,"settings result");return{...m,values:await d(m.values)}}),h=se({type:"object",properties:{values:i},required:["values"]},async f=>({values:await d(A(f,"settings result").values)}));return{capability:{readTool:t,updateTool:n},schema:i,layout:a,readDefinition:{name:t,inputSchema:c,outputSchema:p,annotations:{readOnlyHint:!0}},updateDefinition:{name:n,inputSchema:u,outputSchema:h}}}o(Yt,"prepareSettings");import{completable as Xt}from"@modelcontextprotocol/server";function $e(e){let t=e.map(String);return n=>{let r=String(n??"").toLowerCase();return t.filter(s=>s.toLowerCase().startsWith(r))}}o($e,"createPrefixCompletion");function uo(e,t){return typeof t=="function"?Xt(e,(n,r)=>t(String(n??""),r)):Xt(e,$e(t))}o(uo,"completable");function Zt(e){let t=Object.create(null);for(let[n,r]of Object.entries(e))r!==void 0&&(t[n]=Array.isArray(r)?$e(r):r);return t}o(Zt,"normalizeCompletions");import{ResourceLinkSchema as lo}from"@modelcontextprotocol/core";import{fromJsonSchema as Qt}from"@modelcontextprotocol/server";var po=Qt({type:"object",properties:{query:{type:"string"}},required:["query"]}),fo=Qt({type:"object",properties:{items:{type:"array",items:lo["~standard"].jsonSchema.output({target:"draft-2020-12"})}},required:["items"]});function je(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:{}}o(je,"record");function en(e){if(typeof e.name!="string"||!e.name.trim())throw new TypeError("Mention tool name must be a non-blank string");if(typeof e.search!="function")throw new TypeError("Mention search must be a callback");let{search:t,...n}=e;return{...n,inputSchema:po,outputSchema:fo,annotations:{readOnlyHint:!0,...e.annotations},_meta:{...e._meta,"openai/extensions":{...je(e._meta?.["openai/extensions"]),"mentions/search":{}}}}}o(en,"prepareMentions");function tn(e,t){let n=je(e._meta?.ui),r=e.visibility!==void 0?[e.visibility]:Array.isArray(n.visibility)?n.visibility:[];return{...t,ui:{...je(t?.ui),visibility:[...new Set([...r,"app"])]}}}o(tn,"finalizeMentionsMeta");import{fromJsonSchema as mo}from"@modelcontextprotocol/server";var ho=["get","put","post","delete","options","head","patch","trace"];function sn(e,t){let n=go(t.spec,t),r=bo(n),s=n.length>0?_o(t):void 0;for(let[i,a]of n.entries()){let d=r[i];if(d===void 0||s===void 0)continue;let c=Mo(a);e.tool({name:d,description:Ro(a),inputSchema:vo(t.spec,a,c)},async u=>Ao(a,u,t,c,s))}}o(sn,"registerOpenAPITools");function go(e,t){let n=[];for(let[r,s]of Object.entries(e.paths??{})){let i=H(e,s);if(i===void 0||K(i))continue;let a=nn(e,i.parameters);for(let d of ho){let c=i[d];if(c===void 0)continue;let u=H(e,c);if(u===void 0||K(u))continue;let l=nn(e,u.parameters),p=u.requestBody===void 0?void 0:H(e,u.requestBody),h={method:d,path:r,operation:u,parameters:yo(a,l),...p!==void 0&&!K(p)&&{requestBody:p}};wo(h,t)&&n.push(h)}}return n}o(go,"collectOperations");function nn(e,t){let n=[];for(let r of t??[]){let s=H(e,r);s!==void 0&&!K(s)&&n.push(s)}return n}o(nn,"resolveParameters");function yo(e,t){let n=new Map;for(let r of[...e,...t])n.set(`${r.in}:${r.name}`,r);return[...n.values()]}o(yo,"mergeParameters");function wo(e,t){if(t.tags?.length){let n=new Set(e.operation.tags??[]);if(!t.tags.some(r=>n.has(r)))return!1}return!(t.exclude??[]).some(n=>To(e,n))}o(wo,"isIncluded");function To(e,t){if(t.method&&t.method.toLowerCase()!==e.method||t.operationId&&!rn(t.operationId,e.operation.operationId??"")||t.path&&!rn(t.path,e.path))return!1;if(t.tags?.length){let n=new Set(e.operation.tags??[]);if(!t.tags.some(r=>n.has(r)))return!1}return!0}o(To,"matchesExcludeRule");function rn(e,t){return typeof e=="string"?e===t:(e.lastIndex=0,e.test(t))}o(rn,"matchesPattern");function bo(e){let t=new Map;return e.map(n=>{let r=xo(n.operation.operationId??`${n.method}_${n.path.replace(/[{}]/g,"").replace(/\//g,"_")}`),s=t.get(r)??0;if(t.set(r,s+1),s===0)return r;let i=`_${s+1}`;return`${r.slice(0,64-i.length)}${i}`})}o(bo,"createToolNames");function Ro(e){return[e.operation.summary,e.operation.description,`HTTP: ${e.method.toUpperCase()} ${e.path}`].filter(t=>!!t).join(`
|
|
5
5
|
|
|
6
|
-
`)}o(Ro,"createToolDescription");function xo(e){return e.trim().replace(/[^a-zA-Z0-9_-]+/g,"_").replace(/_+/g,"_").replace(/^_/,"").replace(/_$/,"").slice(0,64)||"openapi_tool"}o(xo,"slugifyToolName");function vo(e,t,n){let r={},s=[];for(let{parameter:c,inputName:u}of n.parameters){let l=on(e,c.schema??{});r[u]={...l,description:c.description??`${c.in} parameter`},(c.required||c.in==="path")&&s.push(u)}let i=an(t.requestBody);i!==void 0&&n.bodyInputName!==void 0&&(r[n.bodyInputName]=on(e,i),t.requestBody?.required&&s.push(n.bodyInputName));let a=Po(e),d={type:"object",properties:r,additionalProperties:!1,...s.length>0&&{required:s},...a!==void 0&&{$defs:a}};return mo(d)}o(vo,"createToolInputSchema");function Mo(e){let t=e.parameters.filter(a=>a.in!=="cookie"),n=an(e.requestBody)===void 0?void 0:"body",r=new Map;for(let a of t)r.set(a.name,(r.get(a.name)??0)+1);let s=new Set(n===void 0?[]:[n]);return{parameters:t.map(a=>{let c=(r.get(a.name)??0)>1||a.name===n?`${a.name}_${a.in}`:a.name;return{parameter:a,inputName:Eo(c,s)}}),...n!==void 0&&{bodyInputName:n}}}o(Mo,"createInputBindings");function Eo(e,t){let n=e,r=2;for(;t.has(n);)n=`${e}_${r}`,r+=1;return t.add(n),n}o(Eo,"claimInputName");function Po(e){let t=q(e.components?.schemas);if(t===void 0)return;let n={};for(let[r,s]of Object.entries(t))n[r]=W(e,s,new Set);return n}o(Po,"createSchemaDefinitions");function on(e,t){let n=W(e,t,new Set);return q(n)??{}}o(on,"transformSchema");function W(e,t,n){if(Array.isArray(t))return t.map(d=>W(e,d,n));let r=q(t);if(r===void 0)return t;let s=typeof r.$ref=="string"?r.$ref:void 0,i={};for(let[d,c]of Object.entries(r))d!=="$ref"&&(d==="nullable"&&typeof c=="boolean"||So(d)&&typeof c=="boolean"||(i[d]=W(e,c,n)));for(let[d,c]of ko)r[c]===!0&&typeof r[d]=="number"&&(i[c]=r[d],delete i[d]);let a=i;if(s!==void 0){let d=Co(e,s);if(d!==void 0)a={$ref:d,...i};else if(!n.has(s)){let c=H(e,{$ref:s});if(c!==void 0){let u=new Set(n);u.add(s),a={...q(W(e,c,u))??{},...i}}}}return r.nullable===!0?{anyOf:[a,{type:"null"}]}:a}o(W,"transformSchemaNode");var ko=[["minimum","exclusiveMinimum"],["maximum","exclusiveMaximum"]];function So(e){return e==="exclusiveMinimum"||e==="exclusiveMaximum"}o(So,"isExclusiveBoundKey");function Co(e,t){let n="#/components/schemas/";if(t.startsWith(n))return H(e,{$ref:t})===void 0?void 0:`#/$defs/${t.slice(n.length)}`}o(Co,"rewriteSchemaRef");function an(e){let t=e?.content;if(t!==void 0)return t["application/json"]?.schema??t["application/*+json"]?.schema??Object.entries(t).find(([n])=>n.includes("+json"))?.[1].schema}o(an,"getJsonRequestBodySchema");async function Ao(e,t,n,r,s){let i=n.fetch??globalThis.fetch,a=Oo(e,t,r.parameters,s),d=Uo(r.parameters,t,n),c=r.bodyInputName,u=c===void 0||t[c]===void 0?void 0:JSON.stringify(t[c]);u!==void 0&&!$o(d,"content-type")&&(d["content-type"]="application/json");let l=await i(a,{method:e.method.toUpperCase(),headers:d,...u!==void 0&&{body:u}}),p=l.headers.get("content-type")??"";if(!l.ok)return{content:[{type:"text",text:await l.text()}],isError:!0};if(p.includes("application/json")||p.includes("+json")){let h=await l.text();try{let f=JSON.parse(h);return{content:[{type:"text",text:JSON.stringify(f)}],structuredContent:f}}catch{return{content:[{type:"text",text:h}]}}}return{content:[{type:"text",text:await l.text()}]}}o(Ao,"callOpenAPIOperation");function Oo(e,t,n,r){let s=e.path.replace(/{([^}]+)}/g,(a,d)=>{let c=n.find(({parameter:u})=>u.in==="path"&&u.name===d);return encodeURIComponent(String(c===void 0?"":t[c.inputName]??""))}),i=new URL(s.replace(/^\/+/,""),Lo(r));for(let{parameter:a,inputName:d}of n){if(a.in!=="query")continue;let c=t[d];c==null||c===""||Io(i,a.name,c)}return i.toString()}o(Oo,"buildUrl");function Uo(e,t,n){let r={...n.headers??{}};for(let{parameter:s,inputName:i}of e){if(s.in!=="header")continue;let a=t[i];a==null||a===""||(r[s.name]=String(a))}return n.auth?.type==="bearer"&&n.auth.token&&(r.authorization=`Bearer ${n.auth.token}`),n.auth?.type==="header"&&n.auth.value&&(r[n.auth.name]=n.auth.value),r}o(Uo,"buildHeaders");function _o(e){let t=e.baseUrl??e.spec.servers?.[0]?.url;if(t===void 0||t.trim()==="")throw new Error("MCPServer.fromOpenAPI requires options.baseUrl or spec.servers[0].url");return t}o(_o,"resolveBaseUrl");function Io(e,t,n){if(Array.isArray(n)){for(let r of n)r!=null&&r!==""&&e.searchParams.append(t,String(r));return}e.searchParams.set(t,String(n))}o(Io,"appendQueryParam");function Lo(e){return e.endsWith("/")?e:`${e}/`}o(Lo,"ensureTrailingSlash");function $o(e,t){return Object.keys(e).some(n=>n.toLowerCase()===t)}o($o,"hasHeader");function K(e){let t=q(e);return t!==void 0&&typeof t.$ref=="string"}o(K,"isReferenceObject");function H(e,t){if(!K(t))return t;if(!t.$ref.startsWith("#/"))return;let n=t.$ref.slice(2).split("/").map(s=>s.replace(/~1/g,"/").replace(/~0/g,"~")),r=e;for(let s of n){let i=q(r);if(i===void 0||!(s in i))return;r=i[s]}return r}o(H,"resolveRef");function q(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}o(q,"readRecord");import{OAuthError as xd,OAuthErrorCode as vd,bearerAuthChallengeResponse as Md,getOAuthProtectedResourceMetadataUrl as wn,oauthMetadataResponse as Ed,requireBearerAuth as Pd,verifyBearerToken as kd}from"@modelcontextprotocol/server";import{getOAuthProtectedResourceMetadataUrl as ua,oauthMetadataResponse as Vo,requireBearerAuth as la}from"@modelcontextprotocol/server";function D(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}o(D,"isRecord");function O(e){let t=e.hostname.toLowerCase();return t==="localhost"||t.endsWith(".localhost")||t==="[::1]"||/^127(?:\.\d{1,3}){3}$/.test(t)}o(O,"isLocalhost");function F(e,t){let n;try{n=new URL(e)}catch{throw new Error(`${t} must be an absolute URL`)}if(n.origin==="null"||n.username!==""||n.password!=="")throw new Error(`${t} must be an absolute URL without credentials`);return n}o(F,"parseAbsoluteUrl");function J(e,t){if(e.protocol!=="https:"&&!(e.protocol==="http:"&&O(e)))throw new Error(`${t} must use HTTPS, or HTTP for localhost`)}o(J,"assertSecureHttpUrl");function Ne(e){if(e===null||typeof e!="object"||!("issuer"in e)||typeof e.issuer!="string")throw new TypeError("oauthMetadata must include a string issuer");J(F(e.issuer,"oauthMetadata.issuer"),"oauthMetadata.issuer")}o(Ne,"assertOAuthMetadata");import{OAuthError as jo,OAuthErrorCode as No}from"@modelcontextprotocol/server";function M(e,t){let n=new jo(No.InvalidToken,e);return t!==void 0&&(n.cause=t),n}o(M,"invalidToken");function cn(e){let t=e.provider,n=Fe(e.basePath);if(t.resource!==void 0)return He(t.resource,n);if(e.mcpUrl!==void 0)return He(pn(ln(e.mcpUrl,"MCP_URL"),n),n)}o(cn,"resolveConfiguredOAuthResource");function dn(e,t){let n=ln(e,"listen origin");if(!O(n))throw new Error("OAuth listen origin must be localhost or a loopback address");return He(pn(n,Fe(t)),t)}o(dn,"resolveLocalOAuthResource");function He(e,t){let n=Fe(t),r=F(e,"OAuth resource");if(r.search!==""||r.hash!=="")throw new Error("OAuth resource must not include a query string or fragment");if(J(r,"OAuth resource"),fn(r.pathname)!==n)throw new Error(`OAuth resource path must exactly match basePath (${n})`);return r.pathname=n,r}o(He,"validateOAuthResource");function qe(e,t){let n=De(t),r=e.createTokenVerifier(new URL(n.href));if(r===null||typeof r!="object"||typeof r.verifyAccessToken!="function")throw new TypeError("OAuth provider createTokenVerifier must return an OAuthTokenVerifier");return{async verifyAccessToken(s){let i=await r.verifyAccessToken(s);Do(i),Ho(i,n);let a;try{a=e.mapAuthInfo(i)}catch(d){throw M("Token identity mapping failed",d)}return Fo(a),{...i,scopes:[...i.scopes],extra:{...i.extra,...a}}}}}o(qe,"wrapOAuthTokenVerifier");function Ho(e,t){if(e.resource===void 0)throw M("Token verifier did not return a validated protected resource");if(qo(e.resource).href!==De(t).href)throw M("Token resource does not match the protected resource")}o(Ho,"assertResourceBinding");function qo(e){if(!(e instanceof URL))throw M("Token resource must be an absolute HTTPS URL, or HTTP URL for localhost");let t=e;if(!/^https?:$/.test(t.protocol)||t.username!==""||t.password!==""||t.search!==""||t.hash!==""||t.protocol==="http:"&&!O(t))throw M("Token resource must be an absolute HTTPS URL, or HTTP URL for localhost");return De(t)}o(qo,"parseTokenResource");function De(e){let t=new URL(e);return t.pathname=t.pathname==="/"?"/":t.pathname.replace(/\/+$/,""),t}o(De,"normalizeResourceUrl");function un(e,t){let n=e.oauthMetadata;if(typeof n!="function")return n;let r=n(new URL(t.href));return Ne(r),r}o(un,"resolveOAuthMetadata");function ie(e){return{oauthMetadata:e.oauthMetadata,...e.requiredScopes!==void 0&&{requiredScopes:[...e.requiredScopes]},...e.scopesSupported!==void 0&&{scopesSupported:[...e.scopesSupported]},...e.resourceName!==void 0&&{resourceName:e.resourceName},...e.serviceDocumentationUrl!==void 0&&{serviceDocumentationUrl:e.serviceDocumentationUrl}}}o(ie,"getOAuthProviderOptions");function Do(e){if(e===null||typeof e!="object"||typeof e.token!="string"||e.token.length===0||typeof e.clientId!="string"||!Array.isArray(e.scopes)||!e.scopes.every(t=>typeof t=="string")||typeof e.expiresAt!="number"||!Number.isFinite(e.expiresAt)||e.expiresAt<=Date.now()/1e3)throw M("Token verifier returned invalid authentication information")}o(Do,"assertVerifiedAuthInfo");function Fo(e){if(e===null||typeof e!="object"||!("user"in e)||e.user===void 0||!D(e.payload)||!Array.isArray(e.permissions)||!e.permissions.every(t=>typeof t=="string"))throw M("Token identity mapping must return user, payload, and string permissions")}o(Fo,"assertMappedExtra");function ln(e,t){let n=F(e,t);if(n.pathname!=="/"||n.search!==""||n.hash!==""||n.username!==""||n.password!=="")throw new Error(`${t} must be an absolute origin without a path`);return n}o(ln,"requireAbsoluteOrigin");function pn(e,t){let n=new URL(e.origin);return n.pathname=t,n}o(pn,"appendBasePath");function Fe(e){if(!e.startsWith("/")||e.includes("?")||e.includes("#"))throw new Error("basePath must be an absolute URL pathname");return fn(e)}o(Fe,"normalizeBasePath");function fn(e){if(e==="/")return"/";let t=e.length;for(;t>0&&e.charCodeAt(t-1)===47;)t--;return e.slice(0,t)}o(fn,"normalizePathname");function Ve(e,t){let n=ie(e),r=un(e,t);return async(s,i)=>{let a=Vo(s,{oauthMetadata:r,resourceServerUrl:t,...n.scopesSupported!==void 0&&{scopesSupported:[...n.scopesSupported]},...n.resourceName!==void 0&&{resourceName:n.resourceName},...n.serviceDocumentationUrl!==void 0&&{serviceDocumentationUrl:n.serviceDocumentationUrl}});return a!==void 0?a:i()}}o(Ve,"oauthMetadata");function mn(e){return v(e).authInfo}o(mn,"authInfoFromRequest");import{OAuthError as ya}from"@modelcontextprotocol/server";import{createRemoteJWKSet as Ta,jwtVerify as ba,errors as Ra}from"jose";import{OAuthClientMetadataSchema as za}from"@modelcontextprotocol/core";var Ua=new TextEncoder,_a=new TextDecoder("utf-8",{fatal:!0});function Be(){return typeof process>"u"||process.env===void 0?!1:process.env.MCP_USE_PHASE==="build"}o(Be,"isBuilding");var Ya=365*24*60*60;var Xa=5*1024;var Za=300*1e3;import{deleteCookie as yc,getCookie as wc,getSignedCookie as Tc,setSignedCookie as bc}from"hono/cookie";var kc=720*60*60;var Sc=1440*60*60,Cc=365*24*60*60;function ae(e){return e.inputSchema??e.schema}o(ae,"resolveToolInputSchema");import{fromJsonSchema as Yo}from"@modelcontextprotocol/server";var Tn="openai/ui";function Xo(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(Xo,"record");function bn(e){let t=e.view?.entrypoints;if(!t?.length)return;let n=ae(e),r=n?Yo(n["~standard"].jsonSchema.input({target:"draft-2020-12"}))["~standard"].validate:void 0;for(let s of t){let i=s.type==="file"?s.extensions.map(a=>({file:{name:`file${a}`,resourceUri:"host-resource://opaque-handle"}})):[{}];if(s.type==="file"&&!r)throw new TypeError(`Tool "${e.name}" file entrypoint requires an inputSchema accepting { file: { name, resourceUri } }.`);for(let a of i){let d=r?.(a);if(d&&("then"in d||d.issues))throw new TypeError(`Tool "${e.name}" ${s.type} entrypoint launch arguments do not satisfy its inputSchema.`)}}}o(bn,"validateEntrypointInput");function Rn(e){let t=e.view?.entrypoints;if(t===void 0)return e._meta;let n=e._meta?.[Tn];return{...e._meta,[Tn]:{...Xo(n)?n:{},entrypoints:t.map(r=>r.type==="file"?{type:r.type,extensions:[...r.extensions]}:{type:r.type})}}}o(Rn,"buildEntrypointMeta");var Zo="mcp_use_sdk_event",Qo="https://eu.i.posthog.com/i/v0/e/",es="phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI",ts=/(^|_)(arguments?|args|body|command|headers?|location|message|organization|path|query|response|secret|subject|token|uri|url|user_agent)(_|$)/i,ns=new Set("feature action sdk_generation telemetry_schema_version sdk_package sdk_version server_id runtime_id identity_stability distinct_id validation_run_id is_validation".split(" ")),xn;function We(){return xn??=crypto.randomUUID(),xn}o(We,"getRuntimeId");var vn=new Set,ze=new Set,Mn=new Map;function Ke(e){return[...e].some(t=>{let n=t.charCodeAt(0);return n<32||n===127})}o(Ke,"hasControl");function Je(e){return typeof process>"u"?void 0:process.env?.[e]}o(Je,"env");function En(e){let t=Je(e);return t!==void 0&&t.length>0&&t.length<=128&&!Ke(t)?t:void 0}o(En,"safeEnv");function rs(){return typeof process>"u"||process.versions?.node===void 0?!1:!("Deno"in globalThis)}o(rs,"canPersistTelemetryIdentity");function Pn(){if(Je("MCP_USE_ANONYMIZED_TELEMETRY")==="false")return!0;try{return globalThis.__MCP_USE_ANONYMIZED_TELEMETRY__===!1||typeof localStorage<"u"&&localStorage.getItem("MCP_USE_ANONYMIZED_TELEMETRY")==="false"}catch{return!1}}o(Pn,"disabled");function kn(){return Pn()}o(kn,"isUsageDisabled");function os(e){return Object.fromEntries(Object.entries(e).filter(([t,n])=>t.length>128||Ke(t)||t.startsWith("$")||ns.has(t)||ts.test(t)||n===void 0?!1:typeof n=="string"?n.length<=128&&!Ke(n):typeof n=="boolean"||typeof n=="number"&&Number.isFinite(n)))}o(os,"clean");async function ss(e){let t=En("MCP_USE_TELEMETRY_PROJECT_ID");if(t!==void 0)return{id:t,stability:"project"};if(e===void 0||!rs())return{id:We(),stability:"process"};let n=Mn.get(e);if(n!==void 0)return n;let r=(async()=>{try{let s=await import("fs/promises"),i=`${e}/.mcp-use`,a=`${i}/usage.json`,d=o(async()=>{try{let l=JSON.parse(await s.readFile(a,"utf8"));if(typeof l=="object"&&l!==null&&"schemaVersion"in l&&l.schemaVersion===1&&"serverId"in l&&typeof l.serverId=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(l.serverId))return l.serverId}catch{}},"read"),c=await d();if(c!==void 0)return{id:c,stability:"server"};await s.mkdir(i,{recursive:!0,mode:448});let u=crypto.randomUUID();try{return await s.writeFile(a,`${JSON.stringify({schemaVersion:1,serverId:u})}
|
|
7
|
-
`,{flag:"wx",mode:384}),{id:u,stability:"server"}}catch{let l=await d();if(l!==void 0)return{id:l,stability:"server"}}}catch{}return{id:We(),stability:"process"}})();return Mn.set(e,r),r}o(ss,"identity");function is(e,t,n,r,s){let i=En("MCP_USE_TELEMETRY_VALIDATION_ID");if(Pn()||Je("NODE_ENV")==="test"&&i===void 0||ze.size>=16)return;if(r.onceKey!==void 0){if(vn.has(r.onceKey))return;vn.add(r.onceKey)}let a=Math.max(0,Math.min(1,r.sampleRate??1));if(i===void 0&&Math.random()>=a)return;let d=(async()=>{try{let c=await s(),u=JSON.stringify({api_key:es,event:Zo,properties:{...os(n),feature:e,action:t,sdk_generation:"v2",telemetry_schema_version:2,sdk_package:"mcp-use",sdk_version:"2.10.0
|
|
6
|
+
`)}o(Ro,"createToolDescription");function xo(e){return e.trim().replace(/[^a-zA-Z0-9_-]+/g,"_").replace(/_+/g,"_").replace(/^_/,"").replace(/_$/,"").slice(0,64)||"openapi_tool"}o(xo,"slugifyToolName");function vo(e,t,n){let r={},s=[];for(let{parameter:c,inputName:u}of n.parameters){let l=on(e,c.schema??{});r[u]={...l,description:c.description??`${c.in} parameter`},(c.required||c.in==="path")&&s.push(u)}let i=an(t.requestBody);i!==void 0&&n.bodyInputName!==void 0&&(r[n.bodyInputName]=on(e,i),t.requestBody?.required&&s.push(n.bodyInputName));let a=Po(e),d={type:"object",properties:r,additionalProperties:!1,...s.length>0&&{required:s},...a!==void 0&&{$defs:a}};return mo(d)}o(vo,"createToolInputSchema");function Mo(e){let t=e.parameters.filter(a=>a.in!=="cookie"),n=an(e.requestBody)===void 0?void 0:"body",r=new Map;for(let a of t)r.set(a.name,(r.get(a.name)??0)+1);let s=new Set(n===void 0?[]:[n]);return{parameters:t.map(a=>{let c=(r.get(a.name)??0)>1||a.name===n?`${a.name}_${a.in}`:a.name;return{parameter:a,inputName:Eo(c,s)}}),...n!==void 0&&{bodyInputName:n}}}o(Mo,"createInputBindings");function Eo(e,t){let n=e,r=2;for(;t.has(n);)n=`${e}_${r}`,r+=1;return t.add(n),n}o(Eo,"claimInputName");function Po(e){let t=q(e.components?.schemas);if(t===void 0)return;let n={};for(let[r,s]of Object.entries(t))n[r]=W(e,s,new Set);return n}o(Po,"createSchemaDefinitions");function on(e,t){let n=W(e,t,new Set);return q(n)??{}}o(on,"transformSchema");function W(e,t,n){if(Array.isArray(t))return t.map(d=>W(e,d,n));let r=q(t);if(r===void 0)return t;let s=typeof r.$ref=="string"?r.$ref:void 0,i={};for(let[d,c]of Object.entries(r))d!=="$ref"&&(d==="nullable"&&typeof c=="boolean"||So(d)&&typeof c=="boolean"||(i[d]=W(e,c,n)));for(let[d,c]of ko)r[c]===!0&&typeof r[d]=="number"&&(i[c]=r[d],delete i[d]);let a=i;if(s!==void 0){let d=Co(e,s);if(d!==void 0)a={$ref:d,...i};else if(!n.has(s)){let c=H(e,{$ref:s});if(c!==void 0){let u=new Set(n);u.add(s),a={...q(W(e,c,u))??{},...i}}}}return r.nullable===!0?{anyOf:[a,{type:"null"}]}:a}o(W,"transformSchemaNode");var ko=[["minimum","exclusiveMinimum"],["maximum","exclusiveMaximum"]];function So(e){return e==="exclusiveMinimum"||e==="exclusiveMaximum"}o(So,"isExclusiveBoundKey");function Co(e,t){let n="#/components/schemas/";if(t.startsWith(n))return H(e,{$ref:t})===void 0?void 0:`#/$defs/${t.slice(n.length)}`}o(Co,"rewriteSchemaRef");function an(e){let t=e?.content;if(t!==void 0)return t["application/json"]?.schema??t["application/*+json"]?.schema??Object.entries(t).find(([n])=>n.includes("+json"))?.[1].schema}o(an,"getJsonRequestBodySchema");async function Ao(e,t,n,r,s){let i=n.fetch??globalThis.fetch,a=Oo(e,t,r.parameters,s),d=Uo(r.parameters,t,n),c=r.bodyInputName,u=c===void 0||t[c]===void 0?void 0:JSON.stringify(t[c]);u!==void 0&&!$o(d,"content-type")&&(d["content-type"]="application/json");let l=await i(a,{method:e.method.toUpperCase(),headers:d,...u!==void 0&&{body:u}}),p=l.headers.get("content-type")??"";if(!l.ok)return{content:[{type:"text",text:await l.text()}],isError:!0};if(p.includes("application/json")||p.includes("+json")){let h=await l.text();try{let f=JSON.parse(h);return{content:[{type:"text",text:JSON.stringify(f)}],structuredContent:f}}catch{return{content:[{type:"text",text:h}]}}}return{content:[{type:"text",text:await l.text()}]}}o(Ao,"callOpenAPIOperation");function Oo(e,t,n,r){let s=e.path.replace(/{([^}]+)}/g,(a,d)=>{let c=n.find(({parameter:u})=>u.in==="path"&&u.name===d);return encodeURIComponent(String(c===void 0?"":t[c.inputName]??""))}),i=new URL(s.replace(/^\/+/,""),Lo(r));for(let{parameter:a,inputName:d}of n){if(a.in!=="query")continue;let c=t[d];c==null||c===""||Io(i,a.name,c)}return i.toString()}o(Oo,"buildUrl");function Uo(e,t,n){let r={...n.headers??{}};for(let{parameter:s,inputName:i}of e){if(s.in!=="header")continue;let a=t[i];a==null||a===""||(r[s.name]=String(a))}return n.auth?.type==="bearer"&&n.auth.token&&(r.authorization=`Bearer ${n.auth.token}`),n.auth?.type==="header"&&n.auth.value&&(r[n.auth.name]=n.auth.value),r}o(Uo,"buildHeaders");function _o(e){let t=e.baseUrl??e.spec.servers?.[0]?.url;if(t===void 0||t.trim()==="")throw new Error("MCPServer.fromOpenAPI requires options.baseUrl or spec.servers[0].url");return t}o(_o,"resolveBaseUrl");function Io(e,t,n){if(Array.isArray(n)){for(let r of n)r!=null&&r!==""&&e.searchParams.append(t,String(r));return}e.searchParams.set(t,String(n))}o(Io,"appendQueryParam");function Lo(e){return e.endsWith("/")?e:`${e}/`}o(Lo,"ensureTrailingSlash");function $o(e,t){return Object.keys(e).some(n=>n.toLowerCase()===t)}o($o,"hasHeader");function K(e){let t=q(e);return t!==void 0&&typeof t.$ref=="string"}o(K,"isReferenceObject");function H(e,t){if(!K(t))return t;if(!t.$ref.startsWith("#/"))return;let n=t.$ref.slice(2).split("/").map(s=>s.replace(/~1/g,"/").replace(/~0/g,"~")),r=e;for(let s of n){let i=q(r);if(i===void 0||!(s in i))return;r=i[s]}return r}o(H,"resolveRef");function q(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}o(q,"readRecord");import{OAuthError as vd,OAuthErrorCode as Md,bearerAuthChallengeResponse as Ed,getOAuthProtectedResourceMetadataUrl as wn,oauthMetadataResponse as Pd,requireBearerAuth as kd,verifyBearerToken as Sd}from"@modelcontextprotocol/server";import{getOAuthProtectedResourceMetadataUrl as ua,oauthMetadataResponse as Vo,requireBearerAuth as la}from"@modelcontextprotocol/server";function D(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}o(D,"isRecord");function O(e){let t=e.hostname.toLowerCase();return t==="localhost"||t.endsWith(".localhost")||t==="[::1]"||/^127(?:\.\d{1,3}){3}$/.test(t)}o(O,"isLocalhost");function F(e,t){let n;try{n=new URL(e)}catch{throw new Error(`${t} must be an absolute URL`)}if(n.origin==="null"||n.username!==""||n.password!=="")throw new Error(`${t} must be an absolute URL without credentials`);return n}o(F,"parseAbsoluteUrl");function J(e,t){if(e.protocol!=="https:"&&!(e.protocol==="http:"&&O(e)))throw new Error(`${t} must use HTTPS, or HTTP for localhost`)}o(J,"assertSecureHttpUrl");function Ne(e){if(e===null||typeof e!="object"||!("issuer"in e)||typeof e.issuer!="string")throw new TypeError("oauthMetadata must include a string issuer");J(F(e.issuer,"oauthMetadata.issuer"),"oauthMetadata.issuer")}o(Ne,"assertOAuthMetadata");import{OAuthError as jo,OAuthErrorCode as No}from"@modelcontextprotocol/server";function M(e,t){let n=new jo(No.InvalidToken,e);return t!==void 0&&(n.cause=t),n}o(M,"invalidToken");function cn(e){let t=e.provider,n=Fe(e.basePath);if(t.resource!==void 0)return He(t.resource,n);if(e.mcpUrl!==void 0)return He(pn(ln(e.mcpUrl,"MCP_URL"),n),n)}o(cn,"resolveConfiguredOAuthResource");function dn(e,t){let n=ln(e,"listen origin");if(!O(n))throw new Error("OAuth listen origin must be localhost or a loopback address");return He(pn(n,Fe(t)),t)}o(dn,"resolveLocalOAuthResource");function He(e,t){let n=Fe(t),r=F(e,"OAuth resource");if(r.search!==""||r.hash!=="")throw new Error("OAuth resource must not include a query string or fragment");if(J(r,"OAuth resource"),fn(r.pathname)!==n)throw new Error(`OAuth resource path must exactly match basePath (${n})`);return r.pathname=n,r}o(He,"validateOAuthResource");function qe(e,t){let n=De(t),r=e.createTokenVerifier(new URL(n.href));if(r===null||typeof r!="object"||typeof r.verifyAccessToken!="function")throw new TypeError("OAuth provider createTokenVerifier must return an OAuthTokenVerifier");return{async verifyAccessToken(s){let i=await r.verifyAccessToken(s);Do(i),Ho(i,n);let a;try{a=e.mapAuthInfo(i)}catch(d){throw M("Token identity mapping failed",d)}return Fo(a),{...i,scopes:[...i.scopes],extra:{...i.extra,...a}}}}}o(qe,"wrapOAuthTokenVerifier");function Ho(e,t){if(e.resource===void 0)throw M("Token verifier did not return a validated protected resource");if(qo(e.resource).href!==De(t).href)throw M("Token resource does not match the protected resource")}o(Ho,"assertResourceBinding");function qo(e){if(!(e instanceof URL))throw M("Token resource must be an absolute HTTPS URL, or HTTP URL for localhost");let t=e;if(!/^https?:$/.test(t.protocol)||t.username!==""||t.password!==""||t.search!==""||t.hash!==""||t.protocol==="http:"&&!O(t))throw M("Token resource must be an absolute HTTPS URL, or HTTP URL for localhost");return De(t)}o(qo,"parseTokenResource");function De(e){let t=new URL(e);return t.pathname=t.pathname==="/"?"/":t.pathname.replace(/\/+$/,""),t}o(De,"normalizeResourceUrl");function un(e,t){let n=e.oauthMetadata;if(typeof n!="function")return n;let r=n(new URL(t.href));return Ne(r),r}o(un,"resolveOAuthMetadata");function ie(e){return{oauthMetadata:e.oauthMetadata,...e.requiredScopes!==void 0&&{requiredScopes:[...e.requiredScopes]},...e.scopesSupported!==void 0&&{scopesSupported:[...e.scopesSupported]},...e.resourceName!==void 0&&{resourceName:e.resourceName},...e.serviceDocumentationUrl!==void 0&&{serviceDocumentationUrl:e.serviceDocumentationUrl}}}o(ie,"getOAuthProviderOptions");function Do(e){if(e===null||typeof e!="object"||typeof e.token!="string"||e.token.length===0||typeof e.clientId!="string"||!Array.isArray(e.scopes)||!e.scopes.every(t=>typeof t=="string")||typeof e.expiresAt!="number"||!Number.isFinite(e.expiresAt)||e.expiresAt<=Date.now()/1e3)throw M("Token verifier returned invalid authentication information")}o(Do,"assertVerifiedAuthInfo");function Fo(e){if(e===null||typeof e!="object"||!("user"in e)||e.user===void 0||!D(e.payload)||!Array.isArray(e.permissions)||!e.permissions.every(t=>typeof t=="string"))throw M("Token identity mapping must return user, payload, and string permissions")}o(Fo,"assertMappedExtra");function ln(e,t){let n=F(e,t);if(n.pathname!=="/"||n.search!==""||n.hash!==""||n.username!==""||n.password!=="")throw new Error(`${t} must be an absolute origin without a path`);return n}o(ln,"requireAbsoluteOrigin");function pn(e,t){let n=new URL(e.origin);return n.pathname=t,n}o(pn,"appendBasePath");function Fe(e){if(!e.startsWith("/")||e.includes("?")||e.includes("#"))throw new Error("basePath must be an absolute URL pathname");return fn(e)}o(Fe,"normalizeBasePath");function fn(e){if(e==="/")return"/";let t=e.length;for(;t>0&&e.charCodeAt(t-1)===47;)t--;return e.slice(0,t)}o(fn,"normalizePathname");function Ve(e,t){let n=ie(e),r=un(e,t);return async(s,i)=>{let a=Vo(s,{oauthMetadata:r,resourceServerUrl:t,...n.scopesSupported!==void 0&&{scopesSupported:[...n.scopesSupported]},...n.resourceName!==void 0&&{resourceName:n.resourceName},...n.serviceDocumentationUrl!==void 0&&{serviceDocumentationUrl:n.serviceDocumentationUrl}});return a!==void 0?a:i()}}o(Ve,"oauthMetadata");function mn(e){return v(e).authInfo}o(mn,"authInfoFromRequest");import{OAuthError as ya}from"@modelcontextprotocol/server";import{createRemoteJWKSet as Ta,jwtVerify as ba,errors as Ra}from"jose";import{OAuthClientMetadataSchema as za}from"@modelcontextprotocol/core";var Ua=new TextEncoder,_a=new TextDecoder("utf-8",{fatal:!0});function Be(){return typeof process>"u"||process.env===void 0?!1:process.env.MCP_USE_PHASE==="build"}o(Be,"isBuilding");var Ya=365*24*60*60;var Xa=5*1024;var Za=300*1e3;import{deleteCookie as yc,getCookie as wc,getSignedCookie as Tc,setSignedCookie as bc}from"hono/cookie";var kc=720*60*60;var Sc=1440*60*60,Cc=365*24*60*60;function ae(e){return e.inputSchema??e.schema}o(ae,"resolveToolInputSchema");import{fromJsonSchema as Yo}from"@modelcontextprotocol/server";var Tn="openai/ui";function Xo(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(Xo,"record");function bn(e){let t=e.view?.entrypoints;if(!t?.length)return;let n=ae(e),r=n?Yo(n["~standard"].jsonSchema.input({target:"draft-2020-12"}))["~standard"].validate:void 0;for(let s of t){let i=s.type==="file"?s.extensions.map(a=>({file:{name:`file${a}`,resourceUri:"host-resource://opaque-handle"}})):[{}];if(s.type==="file"&&!r)throw new TypeError(`Tool "${e.name}" file entrypoint requires an inputSchema accepting { file: { name, resourceUri } }.`);for(let a of i){let d=r?.(a);if(d&&("then"in d||d.issues))throw new TypeError(`Tool "${e.name}" ${s.type} entrypoint launch arguments do not satisfy its inputSchema.`)}}}o(bn,"validateEntrypointInput");function Rn(e){let t=e.view?.entrypoints;if(t===void 0)return e._meta;let n=e._meta?.[Tn];return{...e._meta,[Tn]:{...Xo(n)?n:{},entrypoints:t.map(r=>r.type==="file"?{type:r.type,extensions:[...r.extensions]}:{type:r.type})}}}o(Rn,"buildEntrypointMeta");var Zo="mcp_use_sdk_event",Qo="https://eu.i.posthog.com/i/v0/e/",es="phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI",ts=/(^|_)(arguments?|args|body|command|headers?|location|message|organization|path|query|response|secret|subject|token|uri|url|user_agent)(_|$)/i,ns=new Set("feature action sdk_generation telemetry_schema_version sdk_package sdk_version server_id runtime_id identity_stability distinct_id validation_run_id is_validation".split(" ")),xn;function We(){return xn??=crypto.randomUUID(),xn}o(We,"getRuntimeId");var vn=new Set,ze=new Set,Mn=new Map;function Ke(e){return[...e].some(t=>{let n=t.charCodeAt(0);return n<32||n===127})}o(Ke,"hasControl");function Je(e){return typeof process>"u"?void 0:process.env?.[e]}o(Je,"env");function En(e){let t=Je(e);return t!==void 0&&t.length>0&&t.length<=128&&!Ke(t)?t:void 0}o(En,"safeEnv");function rs(){return typeof process>"u"||process.versions?.node===void 0?!1:!("Deno"in globalThis)}o(rs,"canPersistTelemetryIdentity");function Pn(){if(Je("MCP_USE_ANONYMIZED_TELEMETRY")==="false")return!0;try{return globalThis.__MCP_USE_ANONYMIZED_TELEMETRY__===!1||typeof localStorage<"u"&&localStorage.getItem("MCP_USE_ANONYMIZED_TELEMETRY")==="false"}catch{return!1}}o(Pn,"disabled");function kn(){return Pn()}o(kn,"isUsageDisabled");function os(e){return Object.fromEntries(Object.entries(e).filter(([t,n])=>t.length>128||Ke(t)||t.startsWith("$")||ns.has(t)||ts.test(t)||n===void 0?!1:typeof n=="string"?n.length<=128&&!Ke(n):typeof n=="boolean"||typeof n=="number"&&Number.isFinite(n)))}o(os,"clean");async function ss(e){let t=En("MCP_USE_TELEMETRY_PROJECT_ID");if(t!==void 0)return{id:t,stability:"project"};if(e===void 0||!rs())return{id:We(),stability:"process"};let n=Mn.get(e);if(n!==void 0)return n;let r=(async()=>{try{let s=await import("fs/promises"),i=`${e}/.mcp-use`,a=`${i}/usage.json`,d=o(async()=>{try{let l=JSON.parse(await s.readFile(a,"utf8"));if(typeof l=="object"&&l!==null&&"schemaVersion"in l&&l.schemaVersion===1&&"serverId"in l&&typeof l.serverId=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(l.serverId))return l.serverId}catch{}},"read"),c=await d();if(c!==void 0)return{id:c,stability:"server"};await s.mkdir(i,{recursive:!0,mode:448});let u=crypto.randomUUID();try{return await s.writeFile(a,`${JSON.stringify({schemaVersion:1,serverId:u})}
|
|
7
|
+
`,{flag:"wx",mode:384}),{id:u,stability:"server"}}catch{let l=await d();if(l!==void 0)return{id:l,stability:"server"}}}catch{}return{id:We(),stability:"process"}})();return Mn.set(e,r),r}o(ss,"identity");function is(e,t,n,r,s){let i=En("MCP_USE_TELEMETRY_VALIDATION_ID");if(Pn()||Je("NODE_ENV")==="test"&&i===void 0||ze.size>=16)return;if(r.onceKey!==void 0){if(vn.has(r.onceKey))return;vn.add(r.onceKey)}let a=Math.max(0,Math.min(1,r.sampleRate??1));if(i===void 0&&Math.random()>=a)return;let d=(async()=>{try{let c=await s(),u=JSON.stringify({api_key:es,event:Zo,properties:{...os(n),feature:e,action:t,sdk_generation:"v2",telemetry_schema_version:2,sdk_package:"mcp-use",sdk_version:"2.10.0",server_id:c.id,runtime_id:We(),identity_stability:c.stability,distinct_id:c.id,sample_rate:i===void 0?a:1,$process_person_profile:!1,$geoip_disable:!0,...i!==void 0&&{is_validation:!0,validation_run_id:i}}});await fetch(Qo,{method:"POST",headers:{"content-type":"application/json"},keepalive:!0,body:u})}catch{return}})();ze.add(d),d.then(()=>ze.delete(d))}o(is,"capture");function ce(e,t,n={},r={}){is(e,t,n,r,()=>ss(r.serverRoot))}o(ce,"recordUsage");import{INVALID_PARAMS as Sn,ProtocolError as Cn}from"@modelcontextprotocol/server";function Ye(e){return{"~standard":{version:1,vendor:"mcp-use",validate(t){try{return{value:e(t)}}catch(n){return{issues:[{message:n instanceof Error?n.message:String(n)}]}}}}}}o(Ye,"schema");function Xe(e){if(typeof e!="object"||e===null||Array.isArray(e))throw new TypeError("params must be an object");return e}o(Xe,"object");var as=Ye(e=>{let n=Xe(e).cursor;if(n!==void 0&&typeof n!="string")throw new TypeError("cursor must be a string");return n===void 0?{}:{cursor:n}}),An=Ye(e=>{let t=Xe(e);if(typeof t.uri!="string")throw new TypeError("uri must be a string");if(t.cursor!==void 0&&typeof t.cursor!="string")throw new TypeError("cursor must be a string");return{uri:t.uri,...typeof t.cursor=="string"&&{cursor:t.cursor}}}),Ge=Ye(e=>Xe(e));function cs(e){try{return decodeURIComponent(e)}catch{return e}}o(cs,"decodePathSegment");function On(e,t){let n=new Map(t.skills.map(r=>[r.uri,r]));for(let r of t.resources)e.registerResource(r.uri,r.uri,{title:r.name,mimeType:r.mimeType},async()=>({contents:[{uri:r.uri,mimeType:r.mimeType,...r.text!==void 0?{text:r.text}:{blob:r.blob}}]}));e.server.setRequestHandler("skills/list",{params:as,result:Ge},async()=>({skills:t.skills})),e.server.setRequestHandler("skills/get",{params:An,result:Ge},async({uri:r})=>{let s=n.get(r);if(s===void 0)throw new Cn(Sn,`Unknown skill: ${r}`);return{skill:s}}),e.server.setRequestHandler("resources/directory/read",{params:An,result:Ge},async({uri:r})=>{let s=r.replace(/\/$/,""),i=new Set(t.directories.map(c=>c.uri)),a=`${s}/`,d=new Map;for(let c of t.resources){if(!c.uri.startsWith(a))continue;let u=c.uri.slice(a.length),[l]=u.split("/");if(l===void 0||l==="")continue;let p=`${s}/${l}`;d.set(p,{uri:p,name:cs(l),mimeType:u.includes("/")?"inode/directory":c.mimeType})}for(let c of t.directories){if(!c.uri.startsWith(a))continue;let u=c.uri.slice(a.length);u===""||u.includes("/")||d.set(c.uri,{uri:c.uri,name:c.name,mimeType:"inode/directory"})}if(!i.has(s))throw new Cn(Sn,`Unknown skill directory: ${r}`);return{resources:[...d.values()].sort((c,u)=>c.uri.localeCompare(u.uri))}})}o(On,"registerSkillsRuntime");var Ze="io.modelcontextprotocol/skills",G=Symbol.for("mcp-use.registerSkills");var Y=Symbol("mcp-use/registerViews");function ds(e,t){if(!e.startsWith("/"))throw new Error(`View manifest asset path must be origin-absolute (start with "/"); got ${JSON.stringify(e)}`);return`${t}${e}`}o(ds,"resolveAssetUrl");function us(e,t){return`${C(e,`_mcp-use/views/${t}`)}/`}o(us,"viewAssetsBasePath");function Qe(e,t,n,r){return e.startsWith("http://")||e.startsWith("https://")||e.startsWith("data:")?e:e.startsWith("/")?ds(e,t):`${t}${us(n,r)}${e.replace(/^\/+/,"")}`}o(Qe,"resolveExternalAssetUrl");function ls(e,t){return`${e}${C(t,"_mcp-use/public")}/`}o(ls,"resolvePublicBase");function Un(e){return e.replaceAll(/<\/script/gi,"<\\/script").replaceAll("<!--","\\x3C!--")}o(Un,"escapeInlineScript");function ps(e){return e.replaceAll(/<\/style/gi,"<\\/style")}o(ps,"escapeInlineStyle");function et(e){return e.replaceAll("&","&").replaceAll('"',""").replaceAll("<","<").replaceAll(">",">")}o(et,"escapeHtml");var _n=`<style>
|
|
8
8
|
html,body,#root{background:transparent}
|
|
9
9
|
html,body{margin:0}
|
|
10
10
|
#root[data-mcp-use-loading]{display:flex;min-height:100vh;align-items:center;justify-content:center;flex-direction:column;gap:10px;color:rgba(127,127,127,.9)}
|
|
@@ -40,4 +40,4 @@ ${a}
|
|
|
40
40
|
${d}
|
|
41
41
|
<script type="module" src="${et(u)}"></script>
|
|
42
42
|
</body>
|
|
43
|
-
</html>`}o(tt,"synthesizeViewDocument");var fs=".mcp-use/build/views/public",ms="public",hs=".mcp-use/build/views",In=new WeakMap;function Ln(e,t,n,r){let s;try{s=decodeURIComponent(t)}catch{return new Response("Not Found",{status:404})}if(s.includes("\\")||s.split("/").includes(".."))return new Response("Not Found",{status:404});let i=Object.hasOwn(e,s)?e[s]:void 0;if(i===void 0)return new Response("Not Found",{status:404});let a=null;return n.method!=="HEAD"&&(a=In.get(i)??null,a===null&&(a=Uint8Array.from(atob(i.body),d=>d.charCodeAt(0)),In.set(i,a))),new Response(a,{headers:{"Content-Type":i.contentType,"Cache-Control":"public, max-age=0, must-revalidate",...r!==!0&&{"Access-Control-Allow-Origin":"*"}}})}o(Ln,"serveEmbeddedAsset");function nt(e,t,n){if(t.size===0)return;let r=C(e,"_mcp-use/views"),s=n?.projectRoot??process.cwd();return async i=>{if(i.method!=="GET"&&i.method!=="HEAD")return new Response("Method Not Allowed",{status:405});if(!Q(i,r))return new Response("Not Found",{status:404});let d=Z(i).slice(r.length+1),c=d.indexOf("/");if(c<=0||c===d.length-1)return new Response("Not Found",{status:404});let u=d.slice(0,c),l=d.slice(c+1),p=t.get(u);if(p===void 0||p.kind!=="external")return new Response("Not Found",{status:404});if(n?.assets!==void 0)return Ln(n.assets,d,i,n.deferCors);let[{join:h},{resolvePublicFilePath:f,servePublicFile:m}]=await Promise.all([import("path"),import("./public-route-AVKCGJDQ.js")]),g=h(s,hs,u),y=await f(g,l);return y===null?new Response("Not Found",{status:404}):await m(y,{...n?.deferCors===!0&&{deferCors:!0},...i.method==="HEAD"&&{head:!0}})}}o(nt,"createViewAssetsHandler");function rt(e,t,n){if(t.size===0&&n?.enabled!==!0)return;let r=C(e,"_mcp-use/public"),s=n?.dev===!0?ms:fs,i=n?.projectRoot??process.cwd();return async a=>{if(a.method!=="GET"&&a.method!=="HEAD")return new Response("Method Not Allowed",{status:405});if(!Q(a,r))return new Response("Not Found",{status:404});let c=Z(a).slice(r.length+1),u;try{u=decodeURIComponent(c)}catch{return new Response("Not Found",{status:404})}if(u.length===0)return new Response("Not Found",{status:404});if(n?.assets!==void 0)return Ln(n.assets,`public/${c}`,a,n.deferCors);let[{join:l},{resolvePublicFilePath:p,servePublicFile:h}]=await Promise.all([import("path"),import("./public-route-AVKCGJDQ.js")]),f=l(i,s),m=await p(f,u);return m===null?new Response("Not Found",{status:404}):await h(m,{...n?.deferCors===!0&&{deferCors:!0},...a.method==="HEAD"&&{head:!0}})}}o(rt,"createViewPublicHandler");var gs={connectDomains:"CSP_CONNECT_DOMAINS",resourceDomains:"CSP_RESOURCE_DOMAINS",frameDomains:"CSP_FRAME_DOMAINS",baseUriDomains:"CSP_BASE_URI_DOMAINS"};function ys(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim()).filter(t=>t.length>0)}o(ys,"parseDomainList");function $n(e){if(typeof process>"u")return;let t=process.env[e];if(!(t===void 0||t.trim()===""))return ys(t)}o($n,"readEnvDomains");function ws(){return $n("CSP_URLS")??[]}o(ws,"readCspUrlsShortcut");function de(e){let t=$n(gs[e]);return t!==void 0?t:ws()}o(de,"readEnvDomainsForCategory");function X(...e){let t=new Set,n=[];for(let r of e)for(let s of r)t.has(s)||(t.add(s),n.push(s));return n}o(X,"mergeDomainLists");function Ts(e){return e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e}o(Ts,"toWebSocketOrigin");function jn(e,t){let n=e?.csp,r=[];t.serverOrigin!==""&&(r.push(t.serverOrigin),t.hmrWs===!0&&r.push(Ts(t.serverOrigin)));let s=[],i=t.explicitAssetsBase?t.assetsOrigin:t.serverOrigin;i!==""&&s.push(i);let a=X(n?.connectDomains??[],de("connectDomains"),r),d=X(n?.resourceDomains??[],de("resourceDomains"),s),c=X(n?.frameDomains??[],de("frameDomains")),u=X(n?.baseUriDomains??[],de("baseUriDomains")),l=X(n?.scriptDirectives??[],t.hmrWs===!0?["'unsafe-eval'"]:[]);return{...n,connectDomains:a,resourceDomains:d,frameDomains:c,baseUriDomains:u,...l.length>0?{scriptDirectives:l}:{}}}o(jn,"buildMergedResourceCsp");function ot(e,t,n){if(e===void 0&&t===void 0&&n===void 0)return;let r={...n},s=n?.["ui"],i=typeof s=="object"&&s!==null&&!Array.isArray(s),a=i?{...s}:{};if(e!==void 0){let d=I(e);a.resourceUri=d,r[te]=d}else delete a.resourceUri,delete r[te];return t!==void 0?a.visibility=[t]:delete a.visibility,(e!==void 0||t!==void 0||i)&&(r["ui"]=a),r}o(ot,"buildToolUiMeta");function st(e){let t=I(e);return{ui:{resourceUri:t},[te]:t}}o(st,"buildToolResultUiMeta");function bs(e){let t=e?.request,n=e?.serverOrigin??(t!==void 0?pt(t):""),r=e?.assetsBase??(t!==void 0?S(t):n);return{serverOrigin:n,assetsOrigin:ft(r),explicitAssetsBase:mt(),...e?.hmrWs===!0?{hmrWs:!0}:{}}}o(bs,"resolveCspOptions");function ue(e,t){let r={csp:jn(e,bs(t))};return e?.permissions!==void 0&&(r.permissions=e.permissions),e?.domain!==void 0&&(r.domain=e.domain),e?.prefersBorder!==void 0&&(r.prefersBorder=e.prefersBorder),{ui:r,...e?.displayModes!==void 0&&{"openai/ui":{availableDisplayModes:e.displayModes.filter(s=>s==="inline"||s==="fullscreen"),...e.preferredDisplayMode!==void 0&&{preferredDisplayMode:e.preferredDisplayMode}}}}}o(ue,"buildResourceUiMeta");function it(e,t,n,r){return{mimeType:ee,...n?.description!==void 0&&{description:n.description},_meta:ue(n,r)}}o(it,"viewResourceConfig");var Nn=".claudemcpcontent.com",Rs=32;function xs(e){let t=e?.name;return typeof t=="string"&&t.toLowerCase().includes("claude")}o(xs,"isClaudeClient");async function vs(e){if(e.endsWith(Nn))return e;let t=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(e));return`${Array.from(new Uint8Array(t),r=>r.toString(16).padStart(2,"0")).join("").slice(0,Rs)}${Nn}`}o(vs,"computeClaudeResourceDomain");async function at(e,t,n){let r=typeof t?.name=="string"||typeof n!="string"||n.trim().length===0?t:{...t,name:n.trim()};if(!xs(r))return e;let s=e["ui"];if(typeof s!="object"||s===null||Array.isArray(s))return e;let i=s.domain;return typeof i!="string"||i.length===0?e:{...e,ui:{...s,domain:await vs(i)}}}o(at,"applyClaudeResourceDomain");function V(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}o(V,"record");function ct(e,t){if(typeof e!="string")return t;let n=e.trim();return n.length>0&&n.length<=64&&![...n].some(r=>{let s=r.charCodeAt(0);return s<32||s===127})?n:t}o(ct,"productId");function Fn(e){if(!Bn(e))return;let t=V(e.params);if(e.method==="initialize"){let i=V(t?.clientInfo),a=V(t?.capabilities)??{};return Vn(i,a,t?.protocolVersion,"legacy")}let n=V(t?._meta),r=V(n?.[Ss]),s=V(n?.[ks]);if(!(r===void 0||s===void 0))return Vn(r,s,n?.[Cs],"modern")}o(Fn,"clientUsageFromBody");function Vn(e,t,n,r){let s=t;return{client_name:ct(e?.name,"other"),client_version:ct(e?.version,"unknown"),protocol_era:r,protocol_version:ct(n,"unknown"),connection_mode:r==="modern"?"stateless_request":"legacy_session",sampling_capability:Object.hasOwn(t,"sampling"),elicitation_capability:Object.hasOwn(t,"elicitation"),roots_capability:Object.hasOwn(t,"roots"),extensions_capability:Object.hasOwn(t,"extensions"),views_capability:ne(s),capability_count:Object.keys(t).length}}o(Vn,"clientUsage");function Os(e,t){e.use("*",async(n,r)=>{let s=await t(n.req.raw,async()=>(await r(),n.res));return n.res=s,s})}o(Os,"registerFetchMiddleware");var dt=class e{static{o(this,"MCPServer")}#e;#q;#o;#t=new Map;#s=new Map;#P=new Map;#a=new Map;#c=new Map;#r;#y;#U=!1;#D;#l=new Map;#w=!1;#T;#p=!1;#d=process.cwd();#_;#F;#f;#k;#b;#S;#C=!1;#V=!1;#I;#B=!1;#L;#R=[];#z=!1;#x=[];#m=[];#W;#v=new Set;#h=new Set;#A=new Set;#O=new Set;#K=0;#$=0;#J=0;#G=0;#Y=0;#X=0;#Z=[];#j=new Set;#Q=!1;app;get;post;put;patch;delete;all;fetch;static fromOpenAPI(t){let n=new e({name:t.name??t.spec.info.title,version:t.version??t.spec.info.version??"1.0.0"});sn(n,t);for(let r of n.#t.keys())n.#v.add(r);return n}constructor(t){if(Et(t),this.#e=t,this.#o=vt(t),this.app=new Dn,this.app.use("*",async(n,r)=>{v(n.req.raw).honoContext=n,await r()}),this.get=this.app.get.bind(this.app),this.post=this.app.post.bind(this.app),this.put=this.app.put.bind(this.app),this.patch=this.app.patch.bind(this.app),this.delete=this.app.delete.bind(this.app),this.all=this.app.all.bind(this.app),this.fetch=async(n,r,s)=>(await this.#g(),this.#u("handler"),this.#F.fetch(n,r,s)),t.oauth!==void 0){let n=typeof process>"u"?void 0:process.env.MCP_URL,r=cn({provider:t.oauth,basePath:this.#i(),...n!==void 0&&{mcpUrl:n}});this.#S=r,this.#C=r!==void 0,this.#V=r===void 0}}get basePath(){return this.#i()}get host(){return this.#e.host}get port(){return this.#e.port}get branding(){return this.#o}getHandler(){return this.fetch}tool(t,n){if(this.#n("tool",t.name),this.#r!==void 0&&[this.#r.capability.readTool,this.#r.capability.updateTool].includes(t.name))throw new Error(`Tool "${t.name}" is reserved for settings`);let r=this.#re(t);return bn(t),this.#le(t),this.#v.delete(t.name),this.#h.delete(t.name),this.#t.set(t.name,{definition:t,callback:n,schemes:r}),Object.freeze({name:t.name})}settings(t){if(this.#n("settings",t.readTool??"settings.read"),this.#r!==void 0)throw new Error("Settings are already registered on this server");let n=Yt(t);for(let i of[n.capability.readTool,n.capability.updateTool])if(this.#t.has(i))throw new Error(`Settings tool "${i}" is already registered`);let r=t.read,s=t.update;this.tool(n.readDefinition,async(i,a)=>({content:[],structuredContent:{schema:n.schema,...n.layout!==void 0&&{layout:n.layout},values:await r(a)}})),this.tool(n.updateDefinition,async({set:i},a)=>({content:[],structuredContent:{values:await s(i,a)}})),this.#r=n}mentions(t){this.#n("mentions",t.name);let n=en(t);if(this.#t.has(t.name))throw new Error(`Mention tool "${t.name}" is already registered`);let r=t.search,s=this.tool(n,async(i,a)=>({content:[],structuredContent:await r(i,a)}));return this.#t.get(t.name).mentions=!0,s}[Y](t,n){if(this.#w)throw new Error("Cannot prime views: the views registry is already primed on this server instance.");this.#n("views","manifest");for(let[r,s]of Object.entries(t))try{we(s.viewConfig)}catch(i){throw new Error(`View "${r}" has an invalid viewConfig: ${i instanceof Error?i.message:String(i)}`,{cause:i})}this.#p=n?.dev===!0,this.#T=n?.assets,n?.projectRoot!==void 0&&(this.#d=n.projectRoot);for(let[r,s]of Object.entries(t))this.#c.set(r,s);this.#w=!0}__primeViews(t,n){this[Y](t,n)}[G](t){this.#n("skills","snapshot"),this.#y=t,this.#U=!0}__primeSkills(t){this[G](t)}__skillsConfig(){return this.#e.skills}async#se(t,n){let{discoverConfiguredSkills:r}=await import("#mcp-use-skills-loader"),s=r(this.#e.skills,t,n);return this[G](s),s}resource(t,n){this.#n("resource",t.name);let r=this.#s.get(t.name);return r!==void 0&&this.#A.delete(r.definition.uri),this.#s.set(t.name,{definition:t,callback:n}),this}resourceTemplate(t,n){this.#n("resourceTemplate",t.name);let r=t.complete===void 0?void 0:Zt(t.complete);return this.#P.set(t.name,{definition:t,...r!==void 0&&{complete:r},callback:n}),this}prompt(t,n){return this.#n("prompt",t.name),this.#O.delete(t.name),this.#a.set(t.name,{definition:t,callback:n}),this}async proxy(t){this.#N("proxy()");let n=(async()=>{let{isProxyConnection:r,mountProxyConnection:s,mountProxyServers:i}=await import("./mcp-proxy-YSI2UFBY.js");if(r(t)){this.#$+=1,await s(this.#te(),t);return}this.#$+=Object.keys(t).length,await i(this.#te(),t)})();this.#j.add(n);try{await n}finally{this.#j.delete(n)}}use(t,...n){if(typeof t=="string"&&t.startsWith("mcp:")){this.#n("middleware",t);let s=n[0];return this.#x.push(Se(t,s)),this}return this.app.use.call(this.app,t,...n),this.#K+=typeof t=="function"?1:n.length,this}on(t,n){return this.#n("event listener",t),this.#m.push(Ce(t,n)),this}__setEventBus(t){this.#n("event bus","shared"),this.#k=t}__setRequestLogPrefix(t){this.#n("request log prefix","development"),this.#q=t}__mount(){if(!this.#U)throw new Error("Cannot mount before skills discovery. CLI tooling must call __primeSkills first.");this.#u("handler")}async notifyToolsChanged(){await this.#g(),await this.#u("handler").handler.notify.toolsChanged()}async notifyPromptsChanged(){await this.#g(),await this.#u("handler").handler.notify.promptsChanged()}async notifyResourcesChanged(){await this.#g(),await this.#u("handler").handler.notify.resourcesChanged()}async notifyResourceUpdated(t){await this.#g(),await this.#u("handler").handler.notify.resourceUpdated(t)}async listen(t=void 0,n={}){this.#N("listen()"),await this.#g();let r=Pt(n.host,this.#e.host),s=kt(t,this.#e.port);return this.#ae(r),new Promise((i,a)=>{let d,c,u=new Promise((m,g)=>{d=m,c=g});u.catch(()=>{});let l=!1,p=o(m=>{l||(l=!0,a(m)),c?.(m),new Promise(g=>f.close(()=>g())).catch(()=>{}).finally(()=>{this.#b===f&&(this.#b=void 0)})},"rejectAndClose"),h=Ct({fetch:o(async m=>(await u)(m),"fetch")}),f=As((m,g)=>{h(m,g)});f.once("error",p),f.listen(s,r,()=>{try{let m=f.address(),g=typeof m=="object"&&m!==null?m.port:s,{fetch:y}=this.#u("listen",g,r);d?.(y),l||(l=!0,i({port:g,url:`http://localhost:${g}${this.#i()}`}))}catch(m){p(m)}}),this.#b=f})}async close(){this.#Q=!0,await Promise.allSettled([...this.#j]);let t=[],n=this.#Z.splice(0),r=await Promise.allSettled(n.map(i=>i.close()));for(let i of r)i.status==="rejected"&&t.push(i.reason);try{await this.#f?.close()}catch(i){t.push(i)}let s=this.#b;if(s!==void 0)try{await new Promise((i,a)=>{s.close(d=>d?a(d):i())}),this.#b=void 0}catch(i){t.push(i)}if(t.length>0)throw new AggregateError(t,"Failed to close MCP server cleanly")}#N(t){if(this.#Q)throw t!==void 0?new Error(`Cannot call ${t} after the server has closed.`):new Error("Cannot use the server after it has closed.")}#i(){return this.#e.basePath??"/mcp"}#ie(t,n,r){if(this.#e.oauth===void 0)return;if(this.#C)return this.#S;let s=r??this.#e.host??"127.0.0.1",i=t==="listen"&&n!==void 0&&["127.0.0.1","localhost","::1"].includes(s);if(this.#V&&i)return this.#S=dn(`http://localhost:${n}`,this.#i()),this.#C=!0,this.#S;throw new Error("OAuth requires an explicit resource or MCP_URL when using server.fetch or listening on a non-local host")}#ae(t){if(this.#e.oauth!==void 0&&!["127.0.0.1","localhost","::1"].includes(t)&&!this.#C)throw new Error("OAuth listen() on a public or wildcard host requires an explicit provider resource or valid MCP_URL.")}#n(t,n){if(this.#f!==void 0)throw new Error(`Cannot register ${t} "${n}" after the server has started: registrations are replayed per request from the registry, so register everything before listen()/server.fetch.`)}#ce(){ce("server","configured",{tools_total:this.#t.size,tools_local:this.#t.size-this.#v.size-this.#h.size,tools_openapi:this.#v.size,tools_proxied:this.#h.size,resources:this.#s.size,resource_templates:this.#P.size,prompts:this.#a.size,views:this.#c.size,proxy_servers_configured:this.#$,proxy_servers_connected:this.#J,proxy_tools_discovered:this.#G,proxy_resources_discovered:this.#Y,proxy_prompts_discovered:this.#X,proxy_tools_mounted:this.#h.size,proxy_resources_mounted:this.#A.size,proxy_prompts_mounted:this.#O.size,http_middleware:this.#K,mcp_middleware:this.#x.length,observers_before:this.#m.filter(({phase:t})=>t==="before").length,observers_complete:this.#m.filter(({phase:t})=>t==="complete").length,oauth_configured:this.#e.oauth!==void 0,cors_configured:this.#e.cors!==void 0,request_state_configured:this.#e.requestState!==void 0,legacy_policy:this.#e.legacy??"stateless"},{onceKey:`${this.#ee()}:server`,serverRoot:this.#d})}#de(t){let n=Fn(t);n!==void 0&&ce("client","observed",{...n},{onceKey:`${this.#ee()}:client:${JSON.stringify(n)}`,serverRoot:this.#d})}#ee(){return this.#W??=crypto.randomUUID(),this.#W}#ue(t,n,r,s){let i=this.#e.oauth?.setup;if(i===void 0||this.#B)return;if(this.#L!==void 0)throw this.#L.error;let a=!0,d=o(u=>{if(!a)throw new Error(`[mcp-use] OAuthProviderHost.${u}() called after the provider's setup hook returned; call it from setup().`)},"assertActive"),c={resourceUrl:t,basePath:n,mixedAuth:this.#e.mixedAuth===!0,mode:r,listenHost:r==="listen"?s:void 0,route:o((u,l,p)=>{if(d("route"),u!=="GET"&&u!=="POST"&&u!=="OPTIONS")throw new TypeError("[mcp-use] OAuthProviderHost.route() method must be GET, POST, or OPTIONS");if(typeof p!="function")throw new TypeError("[mcp-use] OAuthProviderHost.route() handler must be a function");let h=n==="/"?"/":`${n}/`;if(typeof l!="string"||!l.startsWith(h)||l.length===h.length||/[?#*:]/.test(l)||l.split("/").some(f=>f==="."||f===".."))throw new TypeError(`[mcp-use] OAuthProviderHost.route() path must be a literal pathname under ${h}`);if(this.#R.some(f=>f.method===u&&f.path===l))throw new Error(`[mcp-use] OAuth provider route ${u} ${l} is already registered`);this.#R.push({method:u,path:l,handler:p})},"route"),use:o((u,l)=>{d("use"),this.use(u,l)},"use"),tool:o((u,l)=>{if(d("tool"),this.#t.has(u.name))throw new Error(`[mcp-use] Tool "${u.name}" is reserved by the OAuth provider; rename the application tool.`);return this.tool(u,l)},"tool"),resource:o((u,l)=>{if(d("resource"),this.#s.has(u.name))throw new Error(`[mcp-use] Resource "${u.name}" is reserved by the OAuth provider; rename the application resource.`);this.resource(u,l)},"resource"),resourceTemplate:o((u,l)=>{if(d("resourceTemplate"),this.#P.has(u.name))throw new Error(`[mcp-use] Resource template "${u.name}" is reserved by the OAuth provider; rename the application resource template.`);this.resourceTemplate(u,l)},"resourceTemplate"),prompt:o((u,l)=>{if(d("prompt"),this.#a.has(u.name))throw new Error(`[mcp-use] Prompt "${u.name}" is reserved by the OAuth provider; rename the application prompt.`);this.prompt(u,l)},"prompt"),listTools:o(()=>(d("listTools"),[...this.#t.values()].map(({definition:u})=>u)),"listTools"),instructions:o(u=>{d("instructions"),this.#I=u(this.#I??this.#e.instructions)},"instructions")};try{let u=i(c);if(typeof u?.then=="function")throw Promise.resolve(u).catch(()=>{}),new TypeError("[mcp-use] The OAuth provider's setup hook must be synchronous but returned a promise. Do async work before creating the provider.")}catch(u){throw this.#L={error:u},u}finally{a=!1}this.#B=!0}#te(){return{isStarted:o(()=>this.#f!==void 0,"isStarted"),hasTool:o(t=>this.#t.has(t),"hasTool"),hasResource:o(t=>this.#s.has(t),"hasResource"),hasPrompt:o(t=>this.#a.has(t),"hasPrompt"),registerTool:o((t,n)=>{this.#n("tool",t.name),this.#h.add(t.name),this.#t.set(t.name,{definition:t,callback:n,schemes:this.#re(t)})},"registerTool"),registerResource:o((t,n)=>{this.#n("resource",t.name),this.#A.add(t.uri),this.#s.set(t.name,{definition:t,callback:n})},"registerResource"),registerPrompt:o((t,n)=>{this.#n("prompt",t.name),this.#O.add(t.name),this.#a.set(t.name,{definition:t,callback:n})},"registerPrompt"),trackOwner:o(t=>{this.#Z.push(t)},"trackOwner"),trackNamespace:o(({tools:t,resources:n,prompts:r})=>{this.#J+=1,this.#G+=t,this.#Y+=n,this.#X+=r},"trackNamespace")}}async#g(){this.#U||(this.#D??=this.#se(typeof process>"u"?".":process.cwd(),"skills").then(()=>{}),await this.#D)}#ne(t,n){let{allowedHosts:r,allowedOrigins:s}=this.#e,i=n??this.#e.host??"127.0.0.1",a=["127.0.0.1","localhost","::1"].includes(i),d=r!==void 0?[...new Set([...Hn(),...r])]:t==="listen"&&a?Hn():void 0,c=s!==void 0?[...new Set([...Ms(),...s])]:void 0;return{hosts:d,origins:c}}#u(t,n,r){if(this.#N(),this.#_===void 0||this.#f===void 0){let{hosts:s,origins:i}=this.#ne(t,r),a=this.#i(),d=a==="/"?"":a,c=new Dn,u=[Ie({...this.#e.logging,mcpPath:a,prefix:this.#q}),me()],l=this.#e.cors;l!==void 0&&u.unshift($t(l));let p=jt(l);s!==void 0&&u.unshift(he(s)),i!==void 0&&u.push(ge(i,!0,w=>{if(this.#R.length===0)return!1;let R=new URL(w.url).pathname;return this.#R.some(U=>U.method===w.method&&U.path===R)})),s===void 0&&t==="listen"&&console.warn(`[mcp-use] listen() is serving on ${r} without Host validation. Behind a platform edge that only routes your own domains this is expected; if this process is reachable directly, set allowedHosts to restrict it.`);let h=this.#ie(t,n,r);if(h!==void 0){let w=this.#e.oauth;u.push(Ve(w,h))}for(let w of u)Os(c,w);if(h!==void 0){this.#ue(h,a,t,r);for(let w of this.#R)c.on(w.method,w.path,R=>w.handler(R))}for(let w of this.#r?.layout??[])for(let R of w.items)if(R.kind==="tool"&&!this.#t.has(R.tool))throw new Error(`Settings action tool "${R.tool}" is not registered on this server`);this.#pe();let{handler:f,fetch:m}=Le(w=>this.#fe(w),{path:a,...(this.#e.legacy!==void 0||this.#k!==void 0)&&{handler:{...this.#e.legacy!==void 0&&{legacy:this.#e.legacy},...this.#k!==void 0&&{bus:this.#k}}},...h!==void 0&&{authInfo:o(w=>mn(w),"authInfo")}});if(h!==void 0){let w=this.#e.oauth,R=ie(w),U=this.#e.mixedAuth===!0,Wn={verifier:qe(w,h),resourceMetadataUrl:wn(h),baselineScopes:R.requiredScopes??[],mixedAuth:U,toolSchemes:o(_=>this.#t.get(_)?.schemes,"toolSchemes"),openResourceUris:[...this.#l.keys()].map(I)},ut;c.use("*",async(_,le)=>{if(new URL(_.req.url).pathname!==a){await le();return}if((this.#e.publicLandingPage===!0||U)&&fe(_.req.raw)){await le();return}ut??=import("./gate-5X3JUL36.js").then(({createOAuthGate:Kn})=>Kn(Wn));let lt=await(await ut)(_.req.raw,async()=>(await le(),_.res));return _.res=lt,lt})}let g=o(w=>{let R=v(w).parsedBody;return Bn(R)&&(this.#ce(),this.#de(R)),m(w)},"mcpRouteHandler"),y=o(async w=>fe(w)?o(async()=>{let{createLandingPageResponse:U}=await import("./landing-handler-3ZBRKAI2.js");return U(w,a,this.#e,this.#o,this.#t.values(),this.#a.values(),this.#s.values())},"respond")():g(w),"endpointHandler"),T=this.#w?this.#p:process.env.NODE_ENV!=="production",x=Mt(this.#o,{dev:T,projectRoot:this.#d,deferCors:p});x!==void 0&&this.app.all("/favicon.ico",w=>x(w.req.raw));let b=rt(a,this.#c,{dev:this.#w?this.#p:T,projectRoot:this.#d,enabled:xe(this.#o)||[...this.#t.values()].some(w=>w.definition.icons!==void 0&&xe({icons:w.definition.icons})),deferCors:p,...this.#T!==void 0&&{assets:this.#T}});if(b!==void 0&&this.app.on(["GET","HEAD"],`${d}/_mcp-use/public/*`,w=>b(w.req.raw)),!this.#p){let w=nt(a,this.#c,{projectRoot:this.#d,deferCors:p,...this.#T!==void 0&&{assets:this.#T}});w!==void 0&&this.app.on(["GET","HEAD"],`${d}/_mcp-use/views/*`,R=>w(R.req.raw))}this.app.all(a,w=>y(w.req.raw)),c.route("/",this.app),this.#F=c,this.#_=async w=>c.fetch(w),this.#f=f,this.#z=s!==void 0}else if(t==="listen"&&!this.#z&&this.#ne("listen",r).hosts!==void 0)throw new Error("Cannot listen() on a localhost bind after server.fetch mounted the app without Host validation (server.fetch expects a platform edge in front). Call listen() first, or set allowedHosts.");return{fetch:this.#_,handler:this.#f}}#le(t){let n=t.view;if(n===void 0)return;if(t.outputSchema===void 0)throw new Error(`Tool "${t.name}" declares view "${n.name}" but has no outputSchema. View-bound tools require an outputSchema \u2014 the view reads structuredContent typed from it. Use outputSchema: z.object({}) for a view that takes no structured output.`);let r=this.#l.get(n.name);if(r!==void 0)throw new Error(`View "${n.name}" is already bound to tool "${r.toolName}"; tool "${t.name}" cannot bind the same view. Each view may be bound to one tool.`);this.#l.set(n.name,{toolName:t.name,config:n})}#pe(){if(this.#l.size>0&&!this.#w){let t=[...this.#t.values()].find(r=>r.definition.view!==void 0),n=t?.definition.view?.name??"unknown";throw new Error(`Tool "${t?.definition.name??"unknown"}" is bound to view "${n}" but no views were primed. Run \`mcp-use build\` and deploy the built entry, or in dev let the CLI prime views automatically.`)}for(let t of this.#t.values()){let n=t.definition.view?.name;if(n!==void 0&&!this.#c.has(n))throw new Error(`Tool "${t.definition.name}" is bound to view "${n}" which is not in the primed views registry. Run \`mcp-use build\` and deploy the built entry, or in dev let the CLI prime views automatically.`)}for(let t of this.#c.keys())this.#l.has(t)||console.warn(`[mcp-use] View "${t}" is registered but no tool binds it.`)}#fe(t){let{name:n,version:r,title:s,description:i}=this.#e,a=this.#I??this.#e.instructions,d=t.authInfo,c=new Es({name:n,version:r,...s!==void 0&&{title:s},...i!==void 0&&{description:i},...this.#o.websiteUrl!==void 0&&{websiteUrl:this.#o.websiteUrl},...this.#o.icons!==void 0&&{icons:Re(this.#o.icons,t.requestInfo,this.#i())}},{capabilities:{logging:{},tools:{listChanged:!0},prompts:{listChanged:!0},resources:{listChanged:!0,subscribe:!0},...(this.#y!==void 0||this.#r!==void 0)&&{extensions:{...this.#y!==void 0&&{[Ze]:{directoryRead:!0}},...this.#r!==void 0&&{"openai/settings":this.#r.capability}}},...this.#r!==void 0&&{experimental:{"openai/settings":this.#r.capability}}},...a!==void 0&&{instructions:a},...d!==void 0&&{authInfo:d},...this.#e.requestState!==void 0&&{requestState:this.#e.requestState}}),u=t.requestInfo,l=u!==void 0?{request:u,hmrWs:this.#p}:{hmrWs:this.#p},p=this.#i();for(let h of this.#t.values())this.#ge(c,h,u);for(let h of this.#s.values())this.#we(c,h);for(let h of this.#P.values())this.#Te(c,h);for(let h of this.#a.values())this.#Re(c,h);for(let[h,f]of this.#c.entries())this.#ye(c,h,f,l,p);return this.#y!==void 0&&On(c,this.#y),this.#he(c),c}#M(t,n,r){let s=B(r);return Object.assign(s,{method:t,params:n,...r.sessionId!==void 0&&{session:{sessionId:r.sessionId}},...r.http?.authInfo!==void 0&&{auth:r.http.authInfo},state:new Map})}#E(t,n,r){let s=t==="tools/call"&&this.#x.length===0&&this.#m.length===0?r:()=>Dt(this.#x,this.#m,t,n,r);if(kn())return s();let i=performance.now(),a=this.#x.filter(p=>j(p.pattern,t)).length,d=o(p=>this.#m.filter(h=>h.phase===p&&j(h.pattern,t)).length,"matchedObservers"),c=n.request?.raw,u=c===void 0?void 0:Fn(v(c).parsedBody),l=o((p,h)=>{ce("operation","completed",{method:t,outcome:p,duration_ms:Math.max(0,Math.round(performance.now()-i)),primitive_origin:this.#me(t,n.params),matched_middleware:a,observers_before:d("before"),observers_complete:h?d("complete"):0,...u?.protocol_era==="modern"?u:{client_name:"unknown",protocol_era:"legacy"}},{sampleRate:p==="success"?.1:1,serverRoot:this.#d})},"capture");return s().then(p=>{let h=qn(p)?"input_required":t==="tools/call"&&typeof p=="object"&&p!==null&&"isError"in p&&p.isError===!0?"error":"success";return l(h,!0),p},p=>{throw l("error",!1),p})}#me(t,n){if(t==="tools/call"){let r=String(n.name);return this.#h.has(r)?"proxied":this.#v.has(r)?"openapi":"local"}return t==="resources/read"?this.#A.has(String(n.uri))?"proxied":"local":t==="prompts/get"?this.#O.has(String(n.name))?"proxied":"local":"mixed"}#he(t){let n=t.server._requestHandlers;if(n===void 0)return;let r=o((s,i,a)=>{let d=n.get(s);if(d===void 0||d.__mcpListWrapped)return;let c=o(async(u,l)=>{let p=l,h=u.params??{},f=this.#M(s,h,p),m,g=o(async()=>{let x=Ht(u,f.params),b=await d(x,l);if(typeof b!="object"||b===null)throw new TypeError(`[mcp-use] ${s} handler returned a non-object result`);m=b;let w=m[i];if(!Array.isArray(w))throw new TypeError(`[mcp-use] ${s} handler result is missing a ${i} array`);return w},"innerFn"),y=await this.#E(s,f,g);if(!Array.isArray(y))throw new TypeError(`[mcp-use] ${s} middleware must return a ${i} array`);let T=a?.(y)??y;return{...m,[i]:T}},"wrapped");c.__mcpListWrapped=!0,n.set(s,c)},"wrapListMethod");r("tools/list","tools",s=>s.map(i=>{let a=this.#t.get(i.name),d=a!==void 0&&this.#oe(a)?a.schemes:void 0;return d===void 0?i:{...i,securitySchemes:d}})),r("resources/list","resources"),r("prompts/list","prompts")}#ge(t,n,r){let{definition:s,callback:i,schemes:a}=n,d=s.view,c=ot(d?.name,s.visibility,Rn(s)),u=n.mentions?tn(s,c):c,l=this.#oe(n)?{...u,[ye]:a}:u,p={...s.title!==void 0&&{title:s.title},...s.icons!==void 0&&{icons:Re(s.icons,r,this.#i())},...s.description!==void 0&&{description:s.description},...s.annotations!==void 0&&{annotations:s.annotations},...s.outputSchema!==void 0&&{outputSchema:s.outputSchema},...l!==void 0&&{_meta:l}},h=d!==void 0?st(d.name):void 0,f=ae(s),m=o(async(g,y)=>{let T=this.#M("tools/call",{name:s.name,arguments:g,...y.mcpReq._meta!==void 0&&{_meta:y.mcpReq._meta}},y),x=o(async()=>{let b=T.params.arguments??{},w=await i(b,this.#xe(y,a));return qn(w)||h===void 0||w.isError===!0?w:{...w,_meta:{...w._meta,...h}}},"innerFn");return await this.#E("tools/call",T,x)},"invokeTool");f!==void 0?t.registerTool(s.name,{...p,inputSchema:f},async(g,y)=>m(g,y)):t.registerTool(s.name,p,async g=>m({},g))}#ye(t,n,r,s,i){let a=I(n),d=we(r.viewConfig),c={...this.#be(this.#l.get(n)?.config),displayModes:d.displayModes,...d.preferredDisplayMode!==void 0&&{preferredDisplayMode:d.preferredDisplayMode}},u=it(n,r,c,s);t.registerResource(n,a,u,async(l,p)=>{let h=p.http?.req,f=h!==void 0?{request:h,...s.hmrWs===!0?{hmrWs:!0}:{}}:s.hmrWs===!0?{hmrWs:!0}:{},m=h!==void 0?S(h):s.request!==void 0?S(s.request):"",g=tt(r,m,i,n),y=await at(ue(c,f),ve(p),(h??s.request)?.headers.get("user-agent"));return{contents:[{uri:l.href,mimeType:u.mimeType,text:g,_meta:y}]}})}#we(t,{definition:n,callback:r}){t.registerResource(n.name,n.uri,{...n.title!==void 0&&{title:n.title},...n.description!==void 0&&{description:n.description},...n.mimeType!==void 0&&{mimeType:n.mimeType},...n.annotations!==void 0&&{annotations:n.annotations},...n._meta!==void 0&&{_meta:{...n._meta}}},async(s,i)=>{let a=this.#M("resources/read",{uri:s.href,...i.mcpReq._meta!==void 0&&{_meta:i.mcpReq._meta}},i),d=o(async()=>Ee(await r(s,this.#H(i)),s.href),"innerFn");return await this.#E("resources/read",a,d)})}#Te(t,{definition:n,callback:r,complete:s}){let i=new Ps(n.uriTemplate,{list:void 0,...s!==void 0&&{complete:s}});t.registerResource(n.name,i,{...n.title!==void 0&&{title:n.title},...n.description!==void 0&&{description:n.description},...n.mimeType!==void 0&&{mimeType:n.mimeType},...n.annotations!==void 0&&{annotations:n.annotations},...n._meta!==void 0&&{_meta:{...n._meta}}},async(a,d,c)=>{let u=this.#M("resources/read",{uri:a.href,...c.mcpReq._meta!==void 0&&{_meta:c.mcpReq._meta}},c),l=o(async()=>Ee(await r(a,d,this.#H(c)),a.href),"innerFn");return await this.#E("resources/read",u,l)})}#be(t){if(t!==void 0)return{...t.description!==void 0&&{description:t.description},...t.csp!==void 0&&{csp:t.csp},...t.permissions!==void 0&&{permissions:t.permissions},...t.domain!==void 0&&{domain:t.domain},...t.prefersBorder!==void 0&&{prefersBorder:t.prefersBorder}}}#Re(t,{definition:n,callback:r}){let s={...n.title!==void 0&&{title:n.title},...n.description!==void 0&&{description:n.description}},i=o(async(a,d)=>{let c=this.#M("prompts/get",{name:n.name,arguments:a,...d.mcpReq._meta!==void 0&&{_meta:d.mcpReq._meta}},d),u=o(async()=>{let l=c.params.arguments??{};return Lt(await r(l,this.#H(d)))},"innerFn");return await this.#E("prompts/get",c,u)},"invokePrompt");if(n.schema!==void 0)t.registerPrompt(n.name,{...s,argsSchema:n.schema},async(a,d)=>i(a,d));else{let a=o(async d=>i({},d),"handler");t.registerPrompt(n.name,s,a)}}#H(t){return this.#e.oauth===void 0?B(t):Me(t)}#xe(t,n){return this.#e.oauth===void 0||!wt(n)&&t.http?.authInfo===void 0?B(t):Me(t)}#ve(){return{hasOAuth:this.#e.oauth!==void 0,mixedAuth:this.#e.mixedAuth===!0,baselineScopes:this.#e.oauth?.requiredScopes??[]}}#re(t){let n=this.#ve(),r=yt(t.name,t.securitySchemes,n),s=Tt(t.name,t,n);return s!==void 0&&console.warn(s),r}#oe(t){let{definition:n}=t;return n.securitySchemes!==void 0?!0:this.#e.mixedAuth===!0&&n._meta?.[ye]===void 0}};import{acceptedContent as rl,createRequestStateCodec as ol,inputRequired as sl,inputResponse as il,isInputRequiredResult as al}from"@modelcontextprotocol/server";function Us(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/plain"}}}o(Us,"text");function _s(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/markdown"}}}o(_s,"markdown");function Is(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/html"}}}o(Is,"html");function Ls(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/xml"}}}o(Ls,"xml");function $s(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/css"}}}o($s,"css");function js(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/javascript"}}}o(js,"javascript");function Ns(e,t="image/png"){return{content:[{type:"image",data:e,mimeType:t}],_meta:{mimeType:t,isImage:!0}}}o(Ns,"image");function Hs(e,t="audio/wav"){return{content:[{type:"audio",data:e,mimeType:t}],_meta:{mimeType:t,isAudio:!0}}}o(Hs,"audio");function qs(e,t){return{content:[{type:"text",text:e}],_meta:{mimeType:t,isBinary:!0}}}o(qs,"binary");function Ds(e,t,n){if(typeof t=="object"&&t!==null&&"content"in t){let s=t,i,a;if(s._meta&&typeof s._meta=="object"){let c=s._meta;typeof c.mimeType=="string"&&(a=c.mimeType)}let d=s.content?.[0];return d?.type==="text"&&"text"in d&&(i=d.text),{content:[{type:"resource",resource:{uri:e,...a!==void 0&&{mimeType:a},text:i??""}}]}}let r=t;return{content:[{type:"resource",resource:{uri:e,...r!==void 0&&r!==""&&{mimeType:r},text:n??""}}]}}o(Ds,"resource");function Fs(e){return{isError:!0,content:[{type:"text",text:e}]}}o(Fs,"error");function Vs(e){return Array.isArray(e)?zn(e):{content:[{type:"text",text:JSON.stringify(e,null,2)}],structuredContent:e,_meta:{mimeType:"application/json"}}}o(Vs,"object");function zn(e){return{content:[{type:"text",text:JSON.stringify(e,null,2)}],structuredContent:e}}o(zn,"array");function Bs(e){let t=e.props??e.data??{},{output:n,message:r,metadata:s}=e,a={content:r?[{type:"text",text:r}]:Array.isArray(n?.content)&&n.content.length>0?n.content:[{type:"text",text:""}]};return s!==void 0&&Object.keys(s).length>0&&(a._meta=s),n?.structuredContent!==void 0?a.structuredContent=n.structuredContent:Object.keys(t).length>0&&(a.structuredContent=t),a}o(Bs,"widget");function zs(...e){let t=e.filter(i=>i.structuredContent!==void 0),n=t.length>0?t.map(i=>i.structuredContent).reduce((i,a)=>({...i,...typeof a=="object"&&a!==null?a:{}}),{}):void 0,r=e.filter(i=>i._meta!==void 0),s=r.length>0?r.map(i=>i._meta).reduce((i,a)=>({...i,...a!==void 0?a:{}}),{}):void 0;return{content:e.flatMap(i=>i.content),...n!==void 0&&Object.keys(n).length>0&&{structuredContent:n},...s!==void 0&&Object.keys(s).length>0&&{_meta:s}}}o(zs,"mix");export{dt as MCPServer,Ze as SKILLS_EXTENSION_ID,rl as acceptedContent,zn as array,Hs as audio,qs as binary,uo as completable,Jn as composeFetch,qt as composeMiddleware,Ce as createMcpEventListenerEntry,Se as createMcpMiddlewareEntry,Le as createMcpMount,ol as createRequestStateCodec,$s as css,Fs as error,v as getRequestBag,he as hostValidationMiddleware,Is as html,Ns as image,sl as inputRequired,il as inputResponse,Be as isBuilding,al as isInputRequiredResult,js as javascript,me as jsonBodyMiddleware,_s as markdown,pe as matchesPath,Q as matchesPathPrefix,j as matchesPattern,zs as mix,Vs as object,ge as originValidationMiddleware,Z as pathnameOf,G as registerSkills,Y as registerViews,Ie as requestLogger,Ds as resource,Us as text,Bs as widget,Ls as xml};
|
|
43
|
+
</html>`}o(tt,"synthesizeViewDocument");var fs=".mcp-use/build/views/public",ms="public",hs=".mcp-use/build/views",In=new WeakMap;function Ln(e,t,n,r){let s;try{s=decodeURIComponent(t)}catch{return new Response("Not Found",{status:404})}if(s.includes("\\")||s.split("/").includes(".."))return new Response("Not Found",{status:404});let i=Object.hasOwn(e,s)?e[s]:void 0;if(i===void 0)return new Response("Not Found",{status:404});let a=null;return n.method!=="HEAD"&&(a=In.get(i)??null,a===null&&(a=Uint8Array.from(atob(i.body),d=>d.charCodeAt(0)),In.set(i,a))),new Response(a,{headers:{"Content-Type":i.contentType,"Cache-Control":"public, max-age=0, must-revalidate",...r!==!0&&{"Access-Control-Allow-Origin":"*"}}})}o(Ln,"serveEmbeddedAsset");function nt(e,t,n){if(t.size===0)return;let r=C(e,"_mcp-use/views"),s=n?.projectRoot??process.cwd();return async i=>{if(i.method!=="GET"&&i.method!=="HEAD")return new Response("Method Not Allowed",{status:405});if(!Q(i,r))return new Response("Not Found",{status:404});let d=Z(i).slice(r.length+1),c=d.indexOf("/");if(c<=0||c===d.length-1)return new Response("Not Found",{status:404});let u=d.slice(0,c),l=d.slice(c+1),p=t.get(u);if(p===void 0||p.kind!=="external")return new Response("Not Found",{status:404});if(n?.assets!==void 0)return Ln(n.assets,d,i,n.deferCors);let[{join:h},{resolvePublicFilePath:f,servePublicFile:m}]=await Promise.all([import("path"),import("./public-route-AVKCGJDQ.js")]),g=h(s,hs,u),y=await f(g,l);return y===null?new Response("Not Found",{status:404}):await m(y,{...n?.deferCors===!0&&{deferCors:!0},...i.method==="HEAD"&&{head:!0}})}}o(nt,"createViewAssetsHandler");function rt(e,t,n){if(t.size===0&&n?.enabled!==!0)return;let r=C(e,"_mcp-use/public"),s=n?.dev===!0?ms:fs,i=n?.projectRoot??process.cwd();return async a=>{if(a.method!=="GET"&&a.method!=="HEAD")return new Response("Method Not Allowed",{status:405});if(!Q(a,r))return new Response("Not Found",{status:404});let c=Z(a).slice(r.length+1),u;try{u=decodeURIComponent(c)}catch{return new Response("Not Found",{status:404})}if(u.length===0)return new Response("Not Found",{status:404});if(n?.assets!==void 0)return Ln(n.assets,`public/${c}`,a,n.deferCors);let[{join:l},{resolvePublicFilePath:p,servePublicFile:h}]=await Promise.all([import("path"),import("./public-route-AVKCGJDQ.js")]),f=l(i,s),m=await p(f,u);return m===null?new Response("Not Found",{status:404}):await h(m,{...n?.deferCors===!0&&{deferCors:!0},...a.method==="HEAD"&&{head:!0}})}}o(rt,"createViewPublicHandler");var gs={connectDomains:"CSP_CONNECT_DOMAINS",resourceDomains:"CSP_RESOURCE_DOMAINS",frameDomains:"CSP_FRAME_DOMAINS",baseUriDomains:"CSP_BASE_URI_DOMAINS"};function ys(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim()).filter(t=>t.length>0)}o(ys,"parseDomainList");function $n(e){if(typeof process>"u")return;let t=process.env[e];if(!(t===void 0||t.trim()===""))return ys(t)}o($n,"readEnvDomains");function ws(){return $n("CSP_URLS")??[]}o(ws,"readCspUrlsShortcut");function de(e){let t=$n(gs[e]);return t!==void 0?t:ws()}o(de,"readEnvDomainsForCategory");function X(...e){let t=new Set,n=[];for(let r of e)for(let s of r)t.has(s)||(t.add(s),n.push(s));return n}o(X,"mergeDomainLists");function Ts(e){return e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e}o(Ts,"toWebSocketOrigin");function jn(e,t){let n=e?.csp,r=[];t.serverOrigin!==""&&(r.push(t.serverOrigin),t.hmrWs===!0&&r.push(Ts(t.serverOrigin)));let s=[],i=t.explicitAssetsBase?t.assetsOrigin:t.serverOrigin;i!==""&&s.push(i);let a=X(n?.connectDomains??[],de("connectDomains"),r),d=X(n?.resourceDomains??[],de("resourceDomains"),s),c=X(n?.frameDomains??[],de("frameDomains")),u=X(n?.baseUriDomains??[],de("baseUriDomains")),l=X(n?.scriptDirectives??[],t.hmrWs===!0?["'unsafe-eval'"]:[]);return{...n,connectDomains:a,resourceDomains:d,frameDomains:c,baseUriDomains:u,...l.length>0?{scriptDirectives:l}:{}}}o(jn,"buildMergedResourceCsp");function ot(e,t,n){if(e===void 0&&t===void 0&&n===void 0)return;let r={...n},s=n?.["ui"],i=typeof s=="object"&&s!==null&&!Array.isArray(s),a=i?{...s}:{};if(e!==void 0){let d=I(e);a.resourceUri=d,r[te]=d}else delete a.resourceUri,delete r[te];return t!==void 0?a.visibility=[t]:delete a.visibility,(e!==void 0||t!==void 0||i)&&(r["ui"]=a),r}o(ot,"buildToolUiMeta");function st(e){let t=I(e);return{ui:{resourceUri:t},[te]:t}}o(st,"buildToolResultUiMeta");function bs(e){let t=e?.request,n=e?.serverOrigin??(t!==void 0?pt(t):""),r=e?.assetsBase??(t!==void 0?S(t):n);return{serverOrigin:n,assetsOrigin:ft(r),explicitAssetsBase:mt(),...e?.hmrWs===!0?{hmrWs:!0}:{}}}o(bs,"resolveCspOptions");function ue(e,t){let r={csp:jn(e,bs(t))};return e?.permissions!==void 0&&(r.permissions=e.permissions),e?.domain!==void 0&&(r.domain=e.domain),e?.prefersBorder!==void 0&&(r.prefersBorder=e.prefersBorder),{ui:r,...e?.displayModes!==void 0&&{"openai/ui":{availableDisplayModes:e.displayModes.filter(s=>s==="inline"||s==="fullscreen"),...e.preferredDisplayMode!==void 0&&{preferredDisplayMode:e.preferredDisplayMode}}}}}o(ue,"buildResourceUiMeta");function it(e,t,n,r){return{mimeType:ee,...n?.description!==void 0&&{description:n.description},_meta:ue(n,r)}}o(it,"viewResourceConfig");var Nn=".claudemcpcontent.com",Rs=32;function xs(e){let t=e?.name;return typeof t=="string"&&t.toLowerCase().includes("claude")}o(xs,"isClaudeClient");async function vs(e){if(e.endsWith(Nn))return e;let t=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(e));return`${Array.from(new Uint8Array(t),r=>r.toString(16).padStart(2,"0")).join("").slice(0,Rs)}${Nn}`}o(vs,"computeClaudeResourceDomain");async function at(e,t,n){let r=typeof t?.name=="string"||typeof n!="string"||n.trim().length===0?t:{...t,name:n.trim()};if(!xs(r))return e;let s=e["ui"];if(typeof s!="object"||s===null||Array.isArray(s))return e;let i=s.domain;return typeof i!="string"||i.length===0?e:{...e,ui:{...s,domain:await vs(i)}}}o(at,"applyClaudeResourceDomain");function V(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}o(V,"record");function ct(e,t){if(typeof e!="string")return t;let n=e.trim();return n.length>0&&n.length<=64&&![...n].some(r=>{let s=r.charCodeAt(0);return s<32||s===127})?n:t}o(ct,"productId");function Fn(e){if(!Bn(e))return;let t=V(e.params);if(e.method==="initialize"){let i=V(t?.clientInfo),a=V(t?.capabilities)??{};return Vn(i,a,t?.protocolVersion,"legacy")}let n=V(t?._meta),r=V(n?.[Ss]),s=V(n?.[ks]);if(!(r===void 0||s===void 0))return Vn(r,s,n?.[Cs],"modern")}o(Fn,"clientUsageFromBody");function Vn(e,t,n,r){let s=t;return{client_name:ct(e?.name,"other"),client_version:ct(e?.version,"unknown"),protocol_era:r,protocol_version:ct(n,"unknown"),connection_mode:r==="modern"?"stateless_request":"legacy_session",sampling_capability:Object.hasOwn(t,"sampling"),elicitation_capability:Object.hasOwn(t,"elicitation"),roots_capability:Object.hasOwn(t,"roots"),extensions_capability:Object.hasOwn(t,"extensions"),views_capability:ne(s),capability_count:Object.keys(t).length}}o(Vn,"clientUsage");function Os(e,t){e.use("*",async(n,r)=>{let s=await t(n.req.raw,async()=>(await r(),n.res));return n.res=s,s})}o(Os,"registerFetchMiddleware");var dt=class e{static{o(this,"MCPServer")}#e;#q;#o;#t=new Map;#s=new Map;#P=new Map;#a=new Map;#c=new Map;#r;#y;#U=!1;#D;#l=new Map;#w=!1;#T;#p=!1;#d=process.cwd();#_;#F;#f;#k;#b;#S;#C=!1;#V=!1;#I;#B=!1;#L;#R=[];#z=!1;#x=[];#m=[];#W;#v=new Set;#h=new Set;#A=new Set;#O=new Set;#K=0;#$=0;#J=0;#G=0;#Y=0;#X=0;#Z=[];#j=new Set;#Q=!1;app;get;post;put;patch;delete;all;fetch;static fromOpenAPI(t){let n=new e({name:t.name??t.spec.info.title,version:t.version??t.spec.info.version??"1.0.0"});sn(n,t);for(let r of n.#t.keys())n.#v.add(r);return n}constructor(t){if(Et(t),this.#e=t,this.#o=vt(t),this.app=new Dn,this.app.use("*",async(n,r)=>{v(n.req.raw).honoContext=n,await r()}),this.get=this.app.get.bind(this.app),this.post=this.app.post.bind(this.app),this.put=this.app.put.bind(this.app),this.patch=this.app.patch.bind(this.app),this.delete=this.app.delete.bind(this.app),this.all=this.app.all.bind(this.app),this.fetch=async(n,r,s)=>(await this.#g(),this.#u("handler"),this.#F.fetch(n,r,s)),t.oauth!==void 0){let n=typeof process>"u"?void 0:process.env.MCP_URL,r=cn({provider:t.oauth,basePath:this.#i(),...n!==void 0&&{mcpUrl:n}});this.#S=r,this.#C=r!==void 0,this.#V=r===void 0}}get basePath(){return this.#i()}get host(){return this.#e.host}get port(){return this.#e.port}get branding(){return this.#o}getHandler(){return this.fetch}tool(t,n){if(this.#n("tool",t.name),this.#r!==void 0&&[this.#r.capability.readTool,this.#r.capability.updateTool].includes(t.name))throw new Error(`Tool "${t.name}" is reserved for settings`);let r=this.#re(t);return bn(t),this.#le(t),this.#v.delete(t.name),this.#h.delete(t.name),this.#t.set(t.name,{definition:t,callback:n,schemes:r}),Object.freeze({name:t.name})}settings(t){if(this.#n("settings",t.readTool??"settings.read"),this.#r!==void 0)throw new Error("Settings are already registered on this server");let n=Yt(t);for(let i of[n.capability.readTool,n.capability.updateTool])if(this.#t.has(i))throw new Error(`Settings tool "${i}" is already registered`);let r=t.read,s=t.update;this.tool(n.readDefinition,async(i,a)=>({content:[],structuredContent:{schema:n.schema,...n.layout!==void 0&&{layout:n.layout},values:await r(a)}})),this.tool(n.updateDefinition,async({set:i},a)=>({content:[],structuredContent:{values:await s(i,a)}})),this.#r=n}mentions(t){this.#n("mentions",t.name);let n=en(t);if(this.#t.has(t.name))throw new Error(`Mention tool "${t.name}" is already registered`);let r=t.search,s=this.tool(n,async(i,a)=>({content:[],structuredContent:await r(i,a)}));return this.#t.get(t.name).mentions=!0,s}[Y](t,n){if(this.#w)throw new Error("Cannot prime views: the views registry is already primed on this server instance.");this.#n("views","manifest");for(let[r,s]of Object.entries(t))try{we(s.viewConfig)}catch(i){throw new Error(`View "${r}" has an invalid viewConfig: ${i instanceof Error?i.message:String(i)}`,{cause:i})}this.#p=n?.dev===!0,this.#T=n?.assets,n?.projectRoot!==void 0&&(this.#d=n.projectRoot);for(let[r,s]of Object.entries(t))this.#c.set(r,s);this.#w=!0}__primeViews(t,n){this[Y](t,n)}[G](t){this.#n("skills","snapshot"),this.#y=t,this.#U=!0}__primeSkills(t){this[G](t)}__skillsConfig(){return this.#e.skills}async#se(t,n){let{discoverConfiguredSkills:r}=await import("#mcp-use-skills-loader"),s=r(this.#e.skills,t,n);return this[G](s),s}resource(t,n){this.#n("resource",t.name);let r=this.#s.get(t.name);return r!==void 0&&this.#A.delete(r.definition.uri),this.#s.set(t.name,{definition:t,callback:n}),this}resourceTemplate(t,n){this.#n("resourceTemplate",t.name);let r=t.complete===void 0?void 0:Zt(t.complete);return this.#P.set(t.name,{definition:t,...r!==void 0&&{complete:r},callback:n}),this}prompt(t,n){return this.#n("prompt",t.name),this.#O.delete(t.name),this.#a.set(t.name,{definition:t,callback:n}),this}async proxy(t){this.#N("proxy()");let n=(async()=>{let{isProxyConnection:r,mountProxyConnection:s,mountProxyServers:i}=await import("./mcp-proxy-YSI2UFBY.js");if(r(t)){this.#$+=1,await s(this.#te(),t);return}this.#$+=Object.keys(t).length,await i(this.#te(),t)})();this.#j.add(n);try{await n}finally{this.#j.delete(n)}}use(t,...n){if(typeof t=="string"&&t.startsWith("mcp:")){this.#n("middleware",t);let s=n[0];return this.#x.push(Se(t,s)),this}return this.app.use.call(this.app,t,...n),this.#K+=typeof t=="function"?1:n.length,this}on(t,n){return this.#n("event listener",t),this.#m.push(Ce(t,n)),this}__setEventBus(t){this.#n("event bus","shared"),this.#k=t}__setRequestLogPrefix(t){this.#n("request log prefix","development"),this.#q=t}__mount(){if(!this.#U)throw new Error("Cannot mount before skills discovery. CLI tooling must call __primeSkills first.");this.#u("handler")}async notifyToolsChanged(){await this.#g(),await this.#u("handler").handler.notify.toolsChanged()}async notifyPromptsChanged(){await this.#g(),await this.#u("handler").handler.notify.promptsChanged()}async notifyResourcesChanged(){await this.#g(),await this.#u("handler").handler.notify.resourcesChanged()}async notifyResourceUpdated(t){await this.#g(),await this.#u("handler").handler.notify.resourceUpdated(t)}async listen(t=void 0,n={}){this.#N("listen()"),await this.#g();let r=Pt(n.host,this.#e.host),s=kt(t,this.#e.port);return this.#ae(r),new Promise((i,a)=>{let d,c,u=new Promise((m,g)=>{d=m,c=g});u.catch(()=>{});let l=!1,p=o(m=>{l||(l=!0,a(m)),c?.(m),new Promise(g=>f.close(()=>g())).catch(()=>{}).finally(()=>{this.#b===f&&(this.#b=void 0)})},"rejectAndClose"),h=Ct({fetch:o(async m=>(await u)(m),"fetch")}),f=As((m,g)=>{h(m,g)});f.once("error",p),f.listen(s,r,()=>{try{let m=f.address(),g=typeof m=="object"&&m!==null?m.port:s,{fetch:y}=this.#u("listen",g,r);d?.(y),l||(l=!0,i({port:g,url:`http://localhost:${g}${this.#i()}`}))}catch(m){p(m)}}),this.#b=f})}async close(){this.#Q=!0,await Promise.allSettled([...this.#j]);let t=[],n=this.#Z.splice(0),r=await Promise.allSettled(n.map(i=>i.close()));for(let i of r)i.status==="rejected"&&t.push(i.reason);try{await this.#f?.close()}catch(i){t.push(i)}let s=this.#b;if(s!==void 0)try{await new Promise((i,a)=>{s.close(d=>d?a(d):i())}),this.#b=void 0}catch(i){t.push(i)}if(t.length>0)throw new AggregateError(t,"Failed to close MCP server cleanly")}#N(t){if(this.#Q)throw t!==void 0?new Error(`Cannot call ${t} after the server has closed.`):new Error("Cannot use the server after it has closed.")}#i(){return this.#e.basePath??"/mcp"}#ie(t,n,r){if(this.#e.oauth===void 0)return;if(this.#C)return this.#S;let s=r??this.#e.host??"127.0.0.1",i=t==="listen"&&n!==void 0&&["127.0.0.1","localhost","::1"].includes(s);if(this.#V&&i)return this.#S=dn(`http://localhost:${n}`,this.#i()),this.#C=!0,this.#S;throw new Error("OAuth requires an explicit resource or MCP_URL when using server.fetch or listening on a non-local host")}#ae(t){if(this.#e.oauth!==void 0&&!["127.0.0.1","localhost","::1"].includes(t)&&!this.#C)throw new Error("OAuth listen() on a public or wildcard host requires an explicit provider resource or valid MCP_URL.")}#n(t,n){if(this.#f!==void 0)throw new Error(`Cannot register ${t} "${n}" after the server has started: registrations are replayed per request from the registry, so register everything before listen()/server.fetch.`)}#ce(){ce("server","configured",{tools_total:this.#t.size,tools_local:this.#t.size-this.#v.size-this.#h.size,tools_openapi:this.#v.size,tools_proxied:this.#h.size,resources:this.#s.size,resource_templates:this.#P.size,prompts:this.#a.size,views:this.#c.size,proxy_servers_configured:this.#$,proxy_servers_connected:this.#J,proxy_tools_discovered:this.#G,proxy_resources_discovered:this.#Y,proxy_prompts_discovered:this.#X,proxy_tools_mounted:this.#h.size,proxy_resources_mounted:this.#A.size,proxy_prompts_mounted:this.#O.size,http_middleware:this.#K,mcp_middleware:this.#x.length,observers_before:this.#m.filter(({phase:t})=>t==="before").length,observers_complete:this.#m.filter(({phase:t})=>t==="complete").length,oauth_configured:this.#e.oauth!==void 0,cors_configured:this.#e.cors!==void 0,request_state_configured:this.#e.requestState!==void 0,legacy_policy:this.#e.legacy??"stateless"},{onceKey:`${this.#ee()}:server`,serverRoot:this.#d})}#de(t){let n=Fn(t);n!==void 0&&ce("client","observed",{...n},{onceKey:`${this.#ee()}:client:${JSON.stringify(n)}`,serverRoot:this.#d})}#ee(){return this.#W??=crypto.randomUUID(),this.#W}#ue(t,n,r,s){let i=this.#e.oauth?.setup;if(i===void 0||this.#B)return;if(this.#L!==void 0)throw this.#L.error;let a=!0,d=o(u=>{if(!a)throw new Error(`[mcp-use] OAuthProviderHost.${u}() called after the provider's setup hook returned; call it from setup().`)},"assertActive"),c={resourceUrl:t,basePath:n,mixedAuth:this.#e.mixedAuth===!0,mode:r,listenHost:r==="listen"?s:void 0,route:o((u,l,p)=>{if(d("route"),u!=="GET"&&u!=="POST"&&u!=="OPTIONS")throw new TypeError("[mcp-use] OAuthProviderHost.route() method must be GET, POST, or OPTIONS");if(typeof p!="function")throw new TypeError("[mcp-use] OAuthProviderHost.route() handler must be a function");let h=n==="/"?"/":`${n}/`;if(typeof l!="string"||!l.startsWith(h)||l.length===h.length||/[?#*:]/.test(l)||l.split("/").some(f=>f==="."||f===".."))throw new TypeError(`[mcp-use] OAuthProviderHost.route() path must be a literal pathname under ${h}`);if(this.#R.some(f=>f.method===u&&f.path===l))throw new Error(`[mcp-use] OAuth provider route ${u} ${l} is already registered`);this.#R.push({method:u,path:l,handler:p})},"route"),use:o((u,l)=>{d("use"),this.use(u,l)},"use"),tool:o((u,l)=>{if(d("tool"),this.#t.has(u.name))throw new Error(`[mcp-use] Tool "${u.name}" is reserved by the OAuth provider; rename the application tool.`);return this.tool(u,l)},"tool"),resource:o((u,l)=>{if(d("resource"),this.#s.has(u.name))throw new Error(`[mcp-use] Resource "${u.name}" is reserved by the OAuth provider; rename the application resource.`);this.resource(u,l)},"resource"),resourceTemplate:o((u,l)=>{if(d("resourceTemplate"),this.#P.has(u.name))throw new Error(`[mcp-use] Resource template "${u.name}" is reserved by the OAuth provider; rename the application resource template.`);this.resourceTemplate(u,l)},"resourceTemplate"),prompt:o((u,l)=>{if(d("prompt"),this.#a.has(u.name))throw new Error(`[mcp-use] Prompt "${u.name}" is reserved by the OAuth provider; rename the application prompt.`);this.prompt(u,l)},"prompt"),listTools:o(()=>(d("listTools"),[...this.#t.values()].map(({definition:u})=>u)),"listTools"),instructions:o(u=>{d("instructions"),this.#I=u(this.#I??this.#e.instructions)},"instructions")};try{let u=i(c);if(typeof u?.then=="function")throw Promise.resolve(u).catch(()=>{}),new TypeError("[mcp-use] The OAuth provider's setup hook must be synchronous but returned a promise. Do async work before creating the provider.")}catch(u){throw this.#L={error:u},u}finally{a=!1}this.#B=!0}#te(){return{isStarted:o(()=>this.#f!==void 0,"isStarted"),hasTool:o(t=>this.#t.has(t),"hasTool"),hasResource:o(t=>this.#s.has(t),"hasResource"),hasPrompt:o(t=>this.#a.has(t),"hasPrompt"),registerTool:o((t,n)=>{this.#n("tool",t.name),this.#h.add(t.name),this.#t.set(t.name,{definition:t,callback:n,schemes:this.#re(t)})},"registerTool"),registerResource:o((t,n)=>{this.#n("resource",t.name),this.#A.add(t.uri),this.#s.set(t.name,{definition:t,callback:n})},"registerResource"),registerPrompt:o((t,n)=>{this.#n("prompt",t.name),this.#O.add(t.name),this.#a.set(t.name,{definition:t,callback:n})},"registerPrompt"),trackOwner:o(t=>{this.#Z.push(t)},"trackOwner"),trackNamespace:o(({tools:t,resources:n,prompts:r})=>{this.#J+=1,this.#G+=t,this.#Y+=n,this.#X+=r},"trackNamespace")}}async#g(){this.#U||(this.#D??=this.#se(typeof process>"u"?".":process.cwd(),"skills").then(()=>{}),await this.#D)}#ne(t,n){let{allowedHosts:r,allowedOrigins:s}=this.#e,i=n??this.#e.host??"127.0.0.1",a=["127.0.0.1","localhost","::1"].includes(i),d=r!==void 0?[...new Set([...Hn(),...r])]:t==="listen"&&a?Hn():void 0,c=s!==void 0?[...new Set([...Ms(),...s])]:void 0;return{hosts:d,origins:c}}#u(t,n,r){if(this.#N(),this.#_===void 0||this.#f===void 0){let{hosts:s,origins:i}=this.#ne(t,r),a=this.#i(),d=a==="/"?"":a,c=new Dn,u=[Ie({...this.#e.logging,mcpPath:a,prefix:this.#q}),me()],l=this.#e.cors;l!==void 0&&u.unshift($t(l));let p=jt(l);s!==void 0&&u.unshift(he(s)),i!==void 0&&u.push(ge(i,!0,w=>{if(this.#R.length===0)return!1;let R=new URL(w.url).pathname;return this.#R.some(U=>U.method===w.method&&U.path===R)})),s===void 0&&t==="listen"&&console.warn(`[mcp-use] listen() is serving on ${r} without Host validation. Behind a platform edge that only routes your own domains this is expected; if this process is reachable directly, set allowedHosts to restrict it.`);let h=this.#ie(t,n,r);if(h!==void 0){let w=this.#e.oauth;u.push(Ve(w,h))}for(let w of u)Os(c,w);if(h!==void 0){this.#ue(h,a,t,r);for(let w of this.#R)c.on(w.method,w.path,R=>w.handler(R))}for(let w of this.#r?.layout??[])for(let R of w.items)if(R.kind==="tool"&&!this.#t.has(R.tool))throw new Error(`Settings action tool "${R.tool}" is not registered on this server`);this.#pe();let{handler:f,fetch:m}=Le(w=>this.#fe(w),{path:a,...(this.#e.legacy!==void 0||this.#k!==void 0)&&{handler:{...this.#e.legacy!==void 0&&{legacy:this.#e.legacy},...this.#k!==void 0&&{bus:this.#k}}},...h!==void 0&&{authInfo:o(w=>mn(w),"authInfo")}});if(h!==void 0){let w=this.#e.oauth,R=ie(w),U=this.#e.mixedAuth===!0,Wn={verifier:qe(w,h),resourceMetadataUrl:wn(h),baselineScopes:R.requiredScopes??[],mixedAuth:U,toolSchemes:o(_=>this.#t.get(_)?.schemes,"toolSchemes"),openResourceUris:[...this.#l.keys()].map(I)},ut;c.use("*",async(_,le)=>{if(new URL(_.req.url).pathname!==a){await le();return}if((this.#e.publicLandingPage===!0||U)&&fe(_.req.raw)){await le();return}ut??=import("./gate-5X3JUL36.js").then(({createOAuthGate:Kn})=>Kn(Wn));let lt=await(await ut)(_.req.raw,async()=>(await le(),_.res));return _.res=lt,lt})}let g=o(w=>{let R=v(w).parsedBody;return Bn(R)&&(this.#ce(),this.#de(R)),m(w)},"mcpRouteHandler"),y=o(async w=>fe(w)?o(async()=>{let{createLandingPageResponse:U}=await import("./landing-handler-3ZBRKAI2.js");return U(w,a,this.#e,this.#o,this.#t.values(),this.#a.values(),this.#s.values())},"respond")():g(w),"endpointHandler"),T=this.#w?this.#p:process.env.NODE_ENV!=="production",x=Mt(this.#o,{dev:T,projectRoot:this.#d,deferCors:p});x!==void 0&&this.app.all("/favicon.ico",w=>x(w.req.raw));let b=rt(a,this.#c,{dev:this.#w?this.#p:T,projectRoot:this.#d,enabled:xe(this.#o)||[...this.#t.values()].some(w=>w.definition.icons!==void 0&&xe({icons:w.definition.icons})),deferCors:p,...this.#T!==void 0&&{assets:this.#T}});if(b!==void 0&&this.app.on(["GET","HEAD"],`${d}/_mcp-use/public/*`,w=>b(w.req.raw)),!this.#p){let w=nt(a,this.#c,{projectRoot:this.#d,deferCors:p,...this.#T!==void 0&&{assets:this.#T}});w!==void 0&&this.app.on(["GET","HEAD"],`${d}/_mcp-use/views/*`,R=>w(R.req.raw))}this.app.all(a,w=>y(w.req.raw)),c.route("/",this.app),this.#F=c,this.#_=async w=>c.fetch(w),this.#f=f,this.#z=s!==void 0}else if(t==="listen"&&!this.#z&&this.#ne("listen",r).hosts!==void 0)throw new Error("Cannot listen() on a localhost bind after server.fetch mounted the app without Host validation (server.fetch expects a platform edge in front). Call listen() first, or set allowedHosts.");return{fetch:this.#_,handler:this.#f}}#le(t){let n=t.view;if(n===void 0)return;if(t.outputSchema===void 0)throw new Error(`Tool "${t.name}" declares view "${n.name}" but has no outputSchema. View-bound tools require an outputSchema \u2014 the view reads structuredContent typed from it. Use outputSchema: z.object({}) for a view that takes no structured output.`);let r=this.#l.get(n.name);if(r!==void 0)throw new Error(`View "${n.name}" is already bound to tool "${r.toolName}"; tool "${t.name}" cannot bind the same view. Each view may be bound to one tool.`);this.#l.set(n.name,{toolName:t.name,config:n})}#pe(){if(this.#l.size>0&&!this.#w){let t=[...this.#t.values()].find(r=>r.definition.view!==void 0),n=t?.definition.view?.name??"unknown";throw new Error(`Tool "${t?.definition.name??"unknown"}" is bound to view "${n}" but no views were primed. Run \`mcp-use build\` and deploy the built entry, or in dev let the CLI prime views automatically.`)}for(let t of this.#t.values()){let n=t.definition.view?.name;if(n!==void 0&&!this.#c.has(n))throw new Error(`Tool "${t.definition.name}" is bound to view "${n}" which is not in the primed views registry. Run \`mcp-use build\` and deploy the built entry, or in dev let the CLI prime views automatically.`)}for(let t of this.#c.keys())this.#l.has(t)||console.warn(`[mcp-use] View "${t}" is registered but no tool binds it.`)}#fe(t){let{name:n,version:r,title:s,description:i}=this.#e,a=this.#I??this.#e.instructions,d=t.authInfo,c=new Es({name:n,version:r,...s!==void 0&&{title:s},...i!==void 0&&{description:i},...this.#o.websiteUrl!==void 0&&{websiteUrl:this.#o.websiteUrl},...this.#o.icons!==void 0&&{icons:Re(this.#o.icons,t.requestInfo,this.#i())}},{capabilities:{logging:{},tools:{listChanged:!0},prompts:{listChanged:!0},resources:{listChanged:!0,subscribe:!0},...(this.#y!==void 0||this.#r!==void 0)&&{extensions:{...this.#y!==void 0&&{[Ze]:{directoryRead:!0}},...this.#r!==void 0&&{"openai/settings":this.#r.capability}}},...this.#r!==void 0&&{experimental:{"openai/settings":this.#r.capability}}},...a!==void 0&&{instructions:a},...d!==void 0&&{authInfo:d},...this.#e.requestState!==void 0&&{requestState:this.#e.requestState}}),u=t.requestInfo,l=u!==void 0?{request:u,hmrWs:this.#p}:{hmrWs:this.#p},p=this.#i();for(let h of this.#t.values())this.#ge(c,h,u);for(let h of this.#s.values())this.#we(c,h);for(let h of this.#P.values())this.#Te(c,h);for(let h of this.#a.values())this.#Re(c,h);for(let[h,f]of this.#c.entries())this.#ye(c,h,f,l,p);return this.#y!==void 0&&On(c,this.#y),this.#he(c),c}#M(t,n,r){let s=B(r);return Object.assign(s,{method:t,params:n,...r.sessionId!==void 0&&{session:{sessionId:r.sessionId}},...r.http?.authInfo!==void 0&&{auth:r.http.authInfo},state:new Map})}#E(t,n,r){let s=t==="tools/call"&&this.#x.length===0&&this.#m.length===0?r:()=>Dt(this.#x,this.#m,t,n,r);if(kn())return s();let i=performance.now(),a=this.#x.filter(p=>j(p.pattern,t)).length,d=o(p=>this.#m.filter(h=>h.phase===p&&j(h.pattern,t)).length,"matchedObservers"),c=n.request?.raw,u=c===void 0?void 0:Fn(v(c).parsedBody),l=o((p,h)=>{ce("operation","completed",{method:t,outcome:p,duration_ms:Math.max(0,Math.round(performance.now()-i)),primitive_origin:this.#me(t,n.params),matched_middleware:a,observers_before:d("before"),observers_complete:h?d("complete"):0,...u?.protocol_era==="modern"?u:{client_name:"unknown",protocol_era:"legacy"}},{sampleRate:p==="success"?.1:1,serverRoot:this.#d})},"capture");return s().then(p=>{let h=qn(p)?"input_required":t==="tools/call"&&typeof p=="object"&&p!==null&&"isError"in p&&p.isError===!0?"error":"success";return l(h,!0),p},p=>{throw l("error",!1),p})}#me(t,n){if(t==="tools/call"){let r=String(n.name);return this.#h.has(r)?"proxied":this.#v.has(r)?"openapi":"local"}return t==="resources/read"?this.#A.has(String(n.uri))?"proxied":"local":t==="prompts/get"?this.#O.has(String(n.name))?"proxied":"local":"mixed"}#he(t){let n=t.server._requestHandlers;if(n===void 0)return;let r=o((s,i,a)=>{let d=n.get(s);if(d===void 0||d.__mcpListWrapped)return;let c=o(async(u,l)=>{let p=l,h=u.params??{},f=this.#M(s,h,p),m,g=o(async()=>{let x=Ht(u,f.params),b=await d(x,l);if(typeof b!="object"||b===null)throw new TypeError(`[mcp-use] ${s} handler returned a non-object result`);m=b;let w=m[i];if(!Array.isArray(w))throw new TypeError(`[mcp-use] ${s} handler result is missing a ${i} array`);return w},"innerFn"),y=await this.#E(s,f,g);if(!Array.isArray(y))throw new TypeError(`[mcp-use] ${s} middleware must return a ${i} array`);let T=a?.(y)??y;return{...m,[i]:T}},"wrapped");c.__mcpListWrapped=!0,n.set(s,c)},"wrapListMethod");r("tools/list","tools",s=>s.map(i=>{let a=this.#t.get(i.name),d=a!==void 0&&this.#oe(a)?a.schemes:void 0;return d===void 0?i:{...i,securitySchemes:d}})),r("resources/list","resources"),r("prompts/list","prompts")}#ge(t,n,r){let{definition:s,callback:i,schemes:a}=n,d=s.view,c=ot(d?.name,s.visibility,Rn(s)),u=n.mentions?tn(s,c):c,l=this.#oe(n)?{...u,[ye]:a}:u,p={...s.title!==void 0&&{title:s.title},...s.icons!==void 0&&{icons:Re(s.icons,r,this.#i())},...s.description!==void 0&&{description:s.description},...s.annotations!==void 0&&{annotations:s.annotations},...s.outputSchema!==void 0&&{outputSchema:s.outputSchema},...l!==void 0&&{_meta:l}},h=d!==void 0?st(d.name):void 0,f=ae(s),m=o(async(g,y)=>{let T=this.#M("tools/call",{name:s.name,arguments:g,...y.mcpReq._meta!==void 0&&{_meta:y.mcpReq._meta}},y),x=o(async()=>{let b=T.params.arguments??{},w=await i(b,this.#xe(y,a));return qn(w)||h===void 0||w.isError===!0?w:{...w,_meta:{...w._meta,...h}}},"innerFn");return await this.#E("tools/call",T,x)},"invokeTool");f!==void 0?t.registerTool(s.name,{...p,inputSchema:f},async(g,y)=>m(g,y)):t.registerTool(s.name,p,async g=>m({},g))}#ye(t,n,r,s,i){let a=I(n),d=we(r.viewConfig),c={...this.#be(this.#l.get(n)?.config),displayModes:d.displayModes,...d.preferredDisplayMode!==void 0&&{preferredDisplayMode:d.preferredDisplayMode}},u=it(n,r,c,s);t.registerResource(n,a,u,async(l,p)=>{let h=p.http?.req,f=h!==void 0?{request:h,...s.hmrWs===!0?{hmrWs:!0}:{}}:s.hmrWs===!0?{hmrWs:!0}:{},m=h!==void 0?S(h):s.request!==void 0?S(s.request):"",g=tt(r,m,i,n),y=await at(ue(c,f),ve(p),(h??s.request)?.headers.get("user-agent"));return{contents:[{uri:l.href,mimeType:u.mimeType,text:g,_meta:y}]}})}#we(t,{definition:n,callback:r}){t.registerResource(n.name,n.uri,{...n.title!==void 0&&{title:n.title},...n.description!==void 0&&{description:n.description},...n.mimeType!==void 0&&{mimeType:n.mimeType},...n.annotations!==void 0&&{annotations:n.annotations},...n._meta!==void 0&&{_meta:{...n._meta}}},async(s,i)=>{let a=this.#M("resources/read",{uri:s.href,...i.mcpReq._meta!==void 0&&{_meta:i.mcpReq._meta}},i),d=o(async()=>Ee(await r(s,this.#H(i)),s.href),"innerFn");return await this.#E("resources/read",a,d)})}#Te(t,{definition:n,callback:r,complete:s}){let i=new Ps(n.uriTemplate,{list:void 0,...s!==void 0&&{complete:s}});t.registerResource(n.name,i,{...n.title!==void 0&&{title:n.title},...n.description!==void 0&&{description:n.description},...n.mimeType!==void 0&&{mimeType:n.mimeType},...n.annotations!==void 0&&{annotations:n.annotations},...n._meta!==void 0&&{_meta:{...n._meta}}},async(a,d,c)=>{let u=this.#M("resources/read",{uri:a.href,...c.mcpReq._meta!==void 0&&{_meta:c.mcpReq._meta}},c),l=o(async()=>Ee(await r(a,d,this.#H(c)),a.href),"innerFn");return await this.#E("resources/read",u,l)})}#be(t){if(t!==void 0)return{...t.description!==void 0&&{description:t.description},...t.csp!==void 0&&{csp:t.csp},...t.permissions!==void 0&&{permissions:t.permissions},...t.domain!==void 0&&{domain:t.domain},...t.prefersBorder!==void 0&&{prefersBorder:t.prefersBorder}}}#Re(t,{definition:n,callback:r}){let s={...n.title!==void 0&&{title:n.title},...n.description!==void 0&&{description:n.description}},i=o(async(a,d)=>{let c=this.#M("prompts/get",{name:n.name,arguments:a,...d.mcpReq._meta!==void 0&&{_meta:d.mcpReq._meta}},d),u=o(async()=>{let l=c.params.arguments??{};return Lt(await r(l,this.#H(d)))},"innerFn");return await this.#E("prompts/get",c,u)},"invokePrompt");if(n.schema!==void 0)t.registerPrompt(n.name,{...s,argsSchema:n.schema},async(a,d)=>i(a,d));else{let a=o(async d=>i({},d),"handler");t.registerPrompt(n.name,s,a)}}#H(t){return this.#e.oauth===void 0?B(t):Me(t)}#xe(t,n){return this.#e.oauth===void 0||!wt(n)&&t.http?.authInfo===void 0?B(t):Me(t)}#ve(){return{hasOAuth:this.#e.oauth!==void 0,mixedAuth:this.#e.mixedAuth===!0,baselineScopes:this.#e.oauth?.requiredScopes??[]}}#re(t){let n=this.#ve(),r=yt(t.name,t.securitySchemes,n),s=Tt(t.name,t,n);return s!==void 0&&console.warn(s),r}#oe(t){let{definition:n}=t;return n.securitySchemes!==void 0?!0:this.#e.mixedAuth===!0&&n._meta?.[ye]===void 0}};import{acceptedContent as ol,createRequestStateCodec as sl,inputRequired as il,inputResponse as al,isInputRequiredResult as cl}from"@modelcontextprotocol/server";function Us(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/plain"}}}o(Us,"text");function _s(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/markdown"}}}o(_s,"markdown");function Is(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/html"}}}o(Is,"html");function Ls(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/xml"}}}o(Ls,"xml");function $s(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/css"}}}o($s,"css");function js(e){return{content:[{type:"text",text:e}],_meta:{mimeType:"text/javascript"}}}o(js,"javascript");function Ns(e,t="image/png"){return{content:[{type:"image",data:e,mimeType:t}],_meta:{mimeType:t,isImage:!0}}}o(Ns,"image");function Hs(e,t="audio/wav"){return{content:[{type:"audio",data:e,mimeType:t}],_meta:{mimeType:t,isAudio:!0}}}o(Hs,"audio");function qs(e,t){return{content:[{type:"text",text:e}],_meta:{mimeType:t,isBinary:!0}}}o(qs,"binary");function Ds(e,t,n){if(typeof t=="object"&&t!==null&&"content"in t){let s=t,i,a;if(s._meta&&typeof s._meta=="object"){let c=s._meta;typeof c.mimeType=="string"&&(a=c.mimeType)}let d=s.content?.[0];return d?.type==="text"&&"text"in d&&(i=d.text),{content:[{type:"resource",resource:{uri:e,...a!==void 0&&{mimeType:a},text:i??""}}]}}let r=t;return{content:[{type:"resource",resource:{uri:e,...r!==void 0&&r!==""&&{mimeType:r},text:n??""}}]}}o(Ds,"resource");function Fs(e){return{isError:!0,content:[{type:"text",text:e}]}}o(Fs,"error");function Vs(e){return Array.isArray(e)?zn(e):{content:[{type:"text",text:JSON.stringify(e,null,2)}],structuredContent:e,_meta:{mimeType:"application/json"}}}o(Vs,"object");function zn(e){return{content:[{type:"text",text:JSON.stringify(e,null,2)}],structuredContent:e}}o(zn,"array");function Bs(e){let t=e.props??e.data??{},{output:n,message:r,metadata:s}=e,a={content:r?[{type:"text",text:r}]:Array.isArray(n?.content)&&n.content.length>0?n.content:[{type:"text",text:""}]};return s!==void 0&&Object.keys(s).length>0&&(a._meta=s),n?.structuredContent!==void 0?a.structuredContent=n.structuredContent:Object.keys(t).length>0&&(a.structuredContent=t),a}o(Bs,"widget");function zs(...e){let t=e.filter(i=>i.structuredContent!==void 0),n=t.length>0?t.map(i=>i.structuredContent).reduce((i,a)=>({...i,...typeof a=="object"&&a!==null?a:{}}),{}):void 0,r=e.filter(i=>i._meta!==void 0),s=r.length>0?r.map(i=>i._meta).reduce((i,a)=>({...i,...a!==void 0?a:{}}),{}):void 0;return{content:e.flatMap(i=>i.content),...n!==void 0&&Object.keys(n).length>0&&{structuredContent:n},...s!==void 0&&Object.keys(s).length>0&&{_meta:s}}}o(zs,"mix");export{dt as MCPServer,Ze as SKILLS_EXTENSION_ID,ol as acceptedContent,zn as array,Hs as audio,qs as binary,uo as completable,Jn as composeFetch,qt as composeMiddleware,Ce as createMcpEventListenerEntry,Se as createMcpMiddlewareEntry,Le as createMcpMount,sl as createRequestStateCodec,$s as css,Fs as error,v as getRequestBag,he as hostValidationMiddleware,Is as html,Ns as image,il as inputRequired,al as inputResponse,Be as isBuilding,cl as isInputRequiredResult,js as javascript,me as jsonBodyMiddleware,_s as markdown,pe as matchesPath,Q as matchesPathPrefix,j as matchesPattern,zs as mix,Vs as object,ge as originValidationMiddleware,Z as pathnameOf,G as registerSkills,Y as registerViews,Ie as requestLogger,Ds as resource,Us as text,Bs as widget,Ls as xml};
|
package/dist/internal/usage.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
var EVENT="mcp_use_sdk_event",ENDPOINT="https://eu.i.posthog.com/i/v0/e/",TOKEN="phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI",CONTENT=/(^|_)(arguments?|args|body|command|headers?|location|message|organization|path|query|response|secret|subject|token|uri|url|user_agent)(_|$)/i,RESERVED=new Set("feature action sdk_generation telemetry_schema_version sdk_package sdk_version server_id runtime_id identity_stability distinct_id validation_run_id is_validation".split(" ")),runtimeId;function getRuntimeId(){return runtimeId??=crypto.randomUUID(),runtimeId}var once=new Set,pending=new Set,identities=new Map;function hasControl(value){return[...value].some(character=>{let code=character.charCodeAt(0);return code<32||code===127})}function env(name){return typeof process>"u"?void 0:process.env?.[name]}function safeEnv(name){let value=env(name);return value!==void 0&&value.length>0&&value.length<=128&&!hasControl(value)?value:void 0}function canPersistTelemetryIdentity(){return typeof process>"u"||process.versions?.node===void 0?!1:!("Deno"in globalThis)}function disabled(){if(env("MCP_USE_ANONYMIZED_TELEMETRY")==="false")return!0;try{return globalThis.__MCP_USE_ANONYMIZED_TELEMETRY__===!1||typeof localStorage<"u"&&localStorage.getItem("MCP_USE_ANONYMIZED_TELEMETRY")==="false"}catch{return!1}}function isUsageDisabled(){return disabled()}function clean(properties){return Object.fromEntries(Object.entries(properties).filter(([key,value])=>key.length>128||hasControl(key)||key.startsWith("$")||RESERVED.has(key)||CONTENT.test(key)||value===void 0?!1:typeof value=="string"?value.length<=128&&!hasControl(value):typeof value=="boolean"||typeof value=="number"&&Number.isFinite(value)))}async function identity(serverRoot){let projectId=safeEnv("MCP_USE_TELEMETRY_PROJECT_ID");if(projectId!==void 0)return{id:projectId,stability:"project"};if(serverRoot===void 0||!canPersistTelemetryIdentity())return{id:getRuntimeId(),stability:"process"};let existing=identities.get(serverRoot);if(existing!==void 0)return existing;let resolving=(async()=>{try{let fs=await import("fs/promises"),directory=`${serverRoot}/.mcp-use`,file=`${directory}/usage.json`,read=async()=>{try{let value=JSON.parse(await fs.readFile(file,"utf8"));if(typeof value=="object"&&value!==null&&"schemaVersion"in value&&value.schemaVersion===1&&"serverId"in value&&typeof value.serverId=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value.serverId))return value.serverId}catch{}},stored=await read();if(stored!==void 0)return{id:stored,stability:"server"};await fs.mkdir(directory,{recursive:!0,mode:448});let created=crypto.randomUUID();try{return await fs.writeFile(file,`${JSON.stringify({schemaVersion:1,serverId:created})}
|
|
2
|
-
`,{flag:"wx",mode:384}),{id:created,stability:"server"}}catch{let raced=await read();if(raced!==void 0)return{id:raced,stability:"server"}}}catch{}return{id:getRuntimeId(),stability:"process"}})();return identities.set(serverRoot,resolving),resolving}function capture(feature,action,properties,options,resolveIdentity){let validationId=safeEnv("MCP_USE_TELEMETRY_VALIDATION_ID");if(disabled()||env("NODE_ENV")==="test"&&validationId===void 0||pending.size>=16)return;if(options.onceKey!==void 0){if(once.has(options.onceKey))return;once.add(options.onceKey)}let rate=Math.max(0,Math.min(1,options.sampleRate??1));if(validationId===void 0&&Math.random()>=rate)return;let request=(async()=>{try{let resolvedIdentity=await resolveIdentity(),body=JSON.stringify({api_key:TOKEN,event:EVENT,properties:{...clean(properties),feature,action,sdk_generation:"v2",telemetry_schema_version:2,sdk_package:"mcp-use",sdk_version:"2.10.0
|
|
2
|
+
`,{flag:"wx",mode:384}),{id:created,stability:"server"}}catch{let raced=await read();if(raced!==void 0)return{id:raced,stability:"server"}}}catch{}return{id:getRuntimeId(),stability:"process"}})();return identities.set(serverRoot,resolving),resolving}function capture(feature,action,properties,options,resolveIdentity){let validationId=safeEnv("MCP_USE_TELEMETRY_VALIDATION_ID");if(disabled()||env("NODE_ENV")==="test"&&validationId===void 0||pending.size>=16)return;if(options.onceKey!==void 0){if(once.has(options.onceKey))return;once.add(options.onceKey)}let rate=Math.max(0,Math.min(1,options.sampleRate??1));if(validationId===void 0&&Math.random()>=rate)return;let request=(async()=>{try{let resolvedIdentity=await resolveIdentity(),body=JSON.stringify({api_key:TOKEN,event:EVENT,properties:{...clean(properties),feature,action,sdk_generation:"v2",telemetry_schema_version:2,sdk_package:"mcp-use",sdk_version:"2.10.0",server_id:resolvedIdentity.id,runtime_id:getRuntimeId(),identity_stability:resolvedIdentity.stability,distinct_id:resolvedIdentity.id,sample_rate:validationId===void 0?rate:1,$process_person_profile:!1,$geoip_disable:!0,...validationId!==void 0&&{is_validation:!0,validation_run_id:validationId}}});await fetch(ENDPOINT,{method:"POST",headers:{"content-type":"application/json"},keepalive:!0,body})}catch{return}})();pending.add(request),request.then(()=>pending.delete(request))}function recordUsage(feature,action,properties={},options={}){capture(feature,action,properties,options,()=>identity(options.serverRoot))}async function flushUsage(){await Promise.all([...pending])}export{flushUsage,isUsageDisabled,recordUsage};
|
package/dist/next/config.d.ts
CHANGED
|
@@ -29,13 +29,17 @@ export interface WithMcpUseOptions {
|
|
|
29
29
|
/**
|
|
30
30
|
* Authored MCP server entry, relative to `projectRoot`.
|
|
31
31
|
*
|
|
32
|
-
* @defaultValue `
|
|
32
|
+
* @defaultValue Conventional discovery in `mcpDir`, or in `projectRoot`
|
|
33
|
+
* when `mcpDir` is omitted: `src/index.ts`, `src/index.tsx`,
|
|
34
|
+
* `src/server.ts`, `src/server.tsx`, `index.ts`, `index.tsx`, `server.ts`,
|
|
35
|
+
* `server.tsx` — first hit wins.
|
|
33
36
|
*/
|
|
34
37
|
entry?: string;
|
|
35
38
|
/**
|
|
36
39
|
* Conventional MCP source directory containing the entry and `views/`.
|
|
37
40
|
*
|
|
38
|
-
* @defaultValue `
|
|
41
|
+
* @defaultValue None: the entry is discovered in `projectRoot` and views
|
|
42
|
+
* are read from `views/`.
|
|
39
43
|
*/
|
|
40
44
|
mcpDir?: string;
|
|
41
45
|
/** Explicit views directory, relative to `projectRoot`. */
|
package/dist/oauth/auth0.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-
|
|
1
|
+
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-4ICJVJOI.js";import"../chunk-JX52OYMQ.js";function oauthAuth0Provider(options={}){let domain=options.domain??oauthEnvironmentValue("MCP_USE_OAUTH_AUTH0_DOMAIN"),audience=oauthEnvironmentValue("MCP_USE_OAUTH_AUTH0_AUDIENCE");if(domain===void 0)throw new Error("Auth0 domain is required.");let resolvedOptions={...options,...options.resource===void 0&&audience!==void 0&&{resource:audience}},issuer=normalizedProviderUrl(domain,"Auth0 domain").href;return oauthCustomProvider({...resolvedOptions,createTokenVerifier:resource=>createJwtVerifier({issuer,jwksUrl:new URL(providerEndpoint(issuer,".well-known/jwks.json")),resource}),oauthMetadata:{issuer,authorization_endpoint:providerEndpoint(issuer,"authorize"),token_endpoint:providerEndpoint(issuer,"oauth/token"),registration_endpoint:providerEndpoint(issuer,"oidc/register"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"]},mapAuthInfo:mapUser})}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub");if(id===void 0)throw invalidToken("Missing Auth0 subject");return{user:{id,...optional("email",stringValue(payload,"email")),...optional("name",stringValue(payload,"name")),...optional("nickname",stringValue(payload,"nickname")),...optional("picture",stringValue(payload,"picture")),...optional("emailVerified",booleanValue(payload,"email_verified")),...optional("updatedAt",stringValue(payload,"updated_at")),roles:normalizedStrings(payload.roles)},payload,permissions:normalizedStrings(payload.permissions)}}function optional(key,value){return value===void 0?{}:{[key]:value}}export{oauthAuth0Provider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-
|
|
1
|
+
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-4ICJVJOI.js";import"../chunk-JX52OYMQ.js";function oauthBetterAuthProvider(options={}){let authURL=options.authURL??oauthEnvironmentValue("MCP_USE_OAUTH_BETTER_AUTH_URL");if(authURL===void 0)throw new Error("Better Auth authURL is required.");let issuer=normalizedProviderUrl(authURL,"Better Auth authURL").href.replace(/\/$/,"");return oauthCustomProvider({...options,createTokenVerifier:resource=>createJwtVerifier({issuer,jwksUrl:new URL(providerEndpoint(issuer,"jwks")),resource}),oauthMetadata:metadata(issuer,options.scopesSupported),mapAuthInfo:mapUser})}function metadata(issuer,scopesSupported){return{issuer,authorization_endpoint:providerEndpoint(issuer,"oauth2/authorize"),token_endpoint:providerEndpoint(issuer,"oauth2/token"),registration_endpoint:providerEndpoint(issuer,"oauth2/register"),jwks_uri:providerEndpoint(issuer,"jwks"),response_types_supported:["code"],grant_types_supported:["authorization_code","client_credentials","refresh_token"],code_challenge_methods_supported:["S256"],scopes_supported:scopesSupported===void 0?["openid","profile","email","offline_access"]:[...scopesSupported]}}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub");if(id===void 0)throw invalidToken("Missing Better Auth subject");return{user:{id,...optional("email",stringValue(payload,"email")),...optional("name",stringValue(payload,"name")),...optional("picture",stringValue(payload,"picture")),...optional("emailVerified",booleanValue(payload,"email_verified")),...optional("sessionId",stringValue(payload,"sid")),...optional("isAnonymous",booleanValue(payload,"is_anonymous")??booleanValue(payload,"isAnonymous")),roles:normalizedStrings(payload.roles)},payload,permissions:normalizedStrings(payload.permissions)}}function optional(key,value){return value===void 0?{}:{[key]:value}}export{oauthBetterAuthProvider};
|
package/dist/oauth/clerk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-
|
|
1
|
+
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-4ICJVJOI.js";import"../chunk-JX52OYMQ.js";function oauthClerkProvider(options={}){if(options.audience!==void 0&&(typeof options.audience!="string"||options.audience.trim().length===0))throw new TypeError("Clerk audience must be non-empty");let frontendApiUrl=options.frontendApiUrl??oauthEnvironmentValue("MCP_USE_OAUTH_CLERK_FRONTEND_API_URL");if(frontendApiUrl===void 0)throw new Error("Clerk frontendApiUrl is required.");let issuer=normalizedProviderUrl(frontendApiUrl,"Clerk frontendApiUrl").href.replace(/\/$/,"");return oauthCustomProvider({...options,createTokenVerifier:resource=>createJwtVerifier({issuer,jwksUrl:new URL(providerEndpoint(issuer,".well-known/jwks.json")),resource,...options.audience!==void 0?{audience:options.audience}:{issuerBoundAccessTokens:!0}}),oauthMetadata:metadata(issuer),mapAuthInfo:authInfo=>mapUser(authInfo)})}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub");if(id===void 0)throw invalidToken("Missing Clerk subject");let organizationRole=stringValue(payload,"org_role");return{user:{id,...optional("email",stringValue(payload,"email")),...optional("name",stringValue(payload,"name")),...optional("username",stringValue(payload,"username")),...optional("picture",stringValue(payload,"picture")),...optional("emailVerified",booleanValue(payload,"email_verified")),...optional("organizationId",stringValue(payload,"org_id")),...optional("organizationRole",organizationRole),...optional("organizationSlug",stringValue(payload,"org_slug")),roles:organizationRole===void 0?[]:[organizationRole]},payload,permissions:normalizedStrings(payload.org_permissions)}}function metadata(issuer){return{issuer,authorization_endpoint:providerEndpoint(issuer,"oauth/authorize"),token_endpoint:providerEndpoint(issuer,"oauth/token"),registration_endpoint:providerEndpoint(issuer,"oauth/register"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"]}}function optional(key,value){return value===void 0?{}:{[key]:value}}export{oauthClerkProvider};
|
package/dist/oauth/convex.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createJwtVerifier,invalidToken,normalizedProviderUrl,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-
|
|
1
|
+
import{createJwtVerifier,invalidToken,normalizedProviderUrl,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-4ICJVJOI.js";import"../chunk-JX52OYMQ.js";function oauthConvexProvider(options={}){let authURL=options.authURL??oauthEnvironmentValue("MCP_USE_OAUTH_CONVEX_AUTH_URL");if(authURL===void 0)throw new Error("Convex authURL is required.");let issuer=normalizedProviderUrl(authURL,"Convex authURL").href.replace(/\/$/,"");return oauthCustomProvider({...options,createTokenVerifier:resource=>createJwtVerifier({issuer,jwksUrl:new URL(providerEndpoint(issuer,".well-known/jwks.json")),resource}),oauthMetadata:metadata(issuer,options.scopesSupported),mapAuthInfo:mapUser})}function metadata(issuer,scopesSupported){return{issuer,authorization_endpoint:providerEndpoint(issuer,"authorize"),token_endpoint:providerEndpoint(issuer,"token"),registration_endpoint:providerEndpoint(issuer,"register"),jwks_uri:providerEndpoint(issuer,".well-known/jwks.json"),userinfo_endpoint:providerEndpoint(issuer,"userinfo"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"],scopes_supported:scopesSupported===void 0?["openid","profile","email","offline_access"]:[...scopesSupported]}}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub");if(id===void 0)throw invalidToken("Missing Convex subject");let clientId=stringValue(payload,"cid")??stringValue(payload,"client_id");return{user:{id,...optional("clientId",clientId)},payload,permissions:[]}}function optional(key,value){return value===void 0?{}:{[key]:value}}export{oauthConvexProvider};
|
package/dist/oauth/guards.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/** @internal Narrows unknown values to plain object records. */
|
|
2
2
|
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* @internal Removes trailing slashes. A loop instead of `/\/+$/`, which
|
|
5
|
+
* backtracks quadratically on long runs of `/`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function trimTrailingSlashes(value: string): string;
|
|
3
8
|
/** @internal Checks if a URL points to localhost or a loopback address. */
|
|
4
9
|
export declare function isLocalhost(url: URL): boolean;
|
|
5
10
|
/** @internal Parses and validates an absolute URL without credentials. */
|
package/dist/oauth/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{SecureStore,UpstreamError,assertEndpoint,assertRedirectUpstream,assertStorage,deriveKeyring,exchangeUpstreamCode,isBuilding,isMemoryStorage,memoryStorage,normalizeSecrets,pkceChallenge,printable,randomKeyring,randomToken,refreshUpstreamTokens,sha256,timingSafeEqual,upstream}from"../chunk-KVVGKJR2.js";import{createJwtVerifier,invalidToken,oauthCustomProvider,oauthEnvironmentValue}from"../chunk-H7AMD7SA.js";import{assertOAuthMetadata,isLocalhost,isRecord}from"../chunk-4VRUHDIY.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 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 resolveOAuthMetadata(provider,resource){let metadata=provider.oauthMetadata;if(typeof metadata!="function")return metadata;let resolved=metadata(new URL(resource.href));return assertOAuthMetadata(resolved),resolved}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 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),metadata=resolveOAuthMetadata(provider,resource);return async(request,next)=>{let response=oauthMetadataResponse(request,{oauthMetadata:metadata,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()}}import{OAuthClientMetadataSchema}from"@modelcontextprotocol/core";var keys={client:id=>`client:${id}`,transaction:id=>`txn:${id}`,upstreamState:hash=>`ustate:${hash}`,code:hash=>`code:${hash}`,codeUsed:hash=>`codeused:${hash}`,grant:id=>`grant:${id}`,revokedGrant:id=>`revoked:${id}`,access:hash=>`at:${hash}`,refresh:hash=>`rt:${hash}`,refreshLock:hash=>`lock:rt:${hash}`,upstream:userKey=>`up:${userKey}`,upstreamLock:userKey=>`lock:up:${userKey}`};var BLOCKED_SCHEMES=new Set(["javascript:","data:","file:","vbscript:","blob:","about:","ftp:","ws:","wss:"]),DCR_CLIENT_TTL=365*24*60*60,MAX_REDIRECT_URIS=20,MAX_NAME_LENGTH=200;function isLoopbackRedirect(uri){try{let url=new URL(uri);return url.protocol==="http:"&&isLoopbackHost(url.hostname)}catch{return!1}}function isLoopbackHost(hostname){return hostname==="127.0.0.1"||hostname==="[::1]"||hostname==="localhost"}function redirectUriProblem(uri){if(typeof uri!="string"||uri.length>2e3)return"redirect_uris must be strings";let url;try{url=new URL(uri)}catch{return`redirect URI is not an absolute URI: ${uri}`}if(url.hash!=="")return"redirect URIs must not have a fragment";if(url.username!==""||url.password!=="")return"redirect URIs must not contain credentials";if(url.protocol!=="https:"){if(url.protocol==="http:")return isLoopbackHost(url.hostname)?void 0:"HTTP redirect URIs are allowed only on loopback addresses";if(BLOCKED_SCHEMES.has(url.protocol))return`redirect URI scheme ${url.protocol} is not allowed`}}function matchRedirectUri(requested,registered){if(registered.includes(requested))return!0;if(!isLoopbackRedirect(requested))return!1;let withoutPort=uri=>{let url=new URL(uri);return url.port="",url.href},target=withoutPort(requested);return registered.some(uri=>isLoopbackRedirect(uri)&&withoutPort(uri)===target)}function configuredClients(clients){let byId=new Map;if(clients===void 0)return{byId,allow:void 0};if(!Array.isArray(clients)||clients.length===0)throw new TypeError("oauthProxy clients must list at least one client; leave it unset to let any client connect");let allow={urls:new Set,origins:new Set};for(let client of clients){if(typeof client=="string"){let origin=httpsOrigin(client);if(isCimdClientId(client))allow.urls.add(client);else if(origin!==void 0)allow.origins.add(origin);else throw new TypeError(`oauthProxy clients: ${client} is neither a client ID metadata document URL (https with a path) nor an https origin`);continue}let redirectUris=client?.redirectUris;if(client===null||typeof client!="object"||typeof client.clientId!="string"||client.clientId.length===0||!isStringArray(redirectUris)||redirectUris.length===0)throw new TypeError("oauthProxy clients entries must be a URL or an object with a clientId and redirectUris");if(client.clientId.startsWith("https://")||client.clientId.startsWith("mcp_client_"))throw new TypeError(`oauthProxy clients: client ${client.clientId} must not look like a metadata document URL or a registered client_id; list metadata documents as strings`);if(byId.has(client.clientId))throw new TypeError(`oauthProxy clients: client ${client.clientId} is listed twice`);for(let uri of redirectUris){let problem=redirectUriProblem(uri);if(problem!==void 0)throw new TypeError(`oauthProxy clients: ${problem}`)}byId.set(client.clientId,{clientId:client.clientId,redirectUris:[...redirectUris],...client.clientName!==void 0&&{clientName:client.clientName},source:"pre-registered"})}return{byId,allow}}function httpsOrigin(value){if(value.startsWith("https://"))try{let url=new URL(value);return url.pathname==="/"&&url.search===""&&url.hash===""&&url.username===""&&url.password===""&&value.replace(/\/$/,"")===url.origin?url.origin:void 0}catch{return}}function isStringArray(value){return Array.isArray(value)&&value.every(item=>typeof item=="string")}function isCimdClientId(clientId){if(!clientId.startsWith("https://"))return!1;try{let url=new URL(clientId);return url.pathname!=="/"&&url.hash===""&&url.username===""&&url.password===""}catch{return!1}}async function registerClient(store,body){let parsed=OAuthClientMetadataSchema.safeParse(body);if(!parsed.success)return invalidMetadata(parsed.error.issues[0]?.message??"invalid metadata");let metadata=parsed.data;if(metadata.redirect_uris.length===0||metadata.redirect_uris.length>MAX_REDIRECT_URIS)return{ok:!1,error:"invalid_redirect_uri",description:`register 1 to ${MAX_REDIRECT_URIS} redirect URIs`};for(let uri of metadata.redirect_uris){let problem=redirectUriProblem(uri);if(problem!==void 0)return{ok:!1,error:"invalid_redirect_uri",description:problem}}let grantTypes=metadata.grant_types??["authorization_code","refresh_token"];if(!grantTypes.includes("authorization_code")||grantTypes.some(grant=>grant!=="authorization_code"&&grant!=="refresh_token"))return invalidMetadata("grant_types must be authorization_code, optionally with refresh_token");if((metadata.response_types??["code"]).some(type=>type!=="code"))return invalidMetadata("response_types must be code");let clientName=typeof metadata.client_name=="string"?metadata.client_name.slice(0,MAX_NAME_LENGTH):void 0,client={clientId:`mcp_client_${randomToken(16)}`,redirectUris:[...metadata.redirect_uris],...clientName!==void 0&&{clientName},source:"dcr"};return await store.set(keys.client(client.clientId),client,DCR_CLIENT_TTL),{ok:!0,client,response:{client_id:client.clientId,client_id_issued_at:Math.floor(Date.now()/1e3),redirect_uris:client.redirectUris,grant_types:grantTypes,response_types:["code"],token_endpoint_auth_method:"none",...clientName!==void 0&&{client_name:clientName},...metadata.scope!==void 0&&{scope:metadata.scope}}}}function invalidMetadata(description){return{ok:!1,error:"invalid_client_metadata",description}}function isClientAdmitted(resolver,clientId){if(isCimdClientId(clientId)){let allow=resolver.allow;return allow===void 0||allow.urls.has(clientId)||allow.origins.has(new URL(clientId).origin)}return resolver.configured.has(clientId)?!0:resolver.dcr&&(clientId.startsWith("mcp_client_")||clientId===resolver.upstreamClientId)}async function resolveClient(resolver,clientId,redirectUri){if(isCimdClientId(clientId)){if(!isClientAdmitted(resolver,clientId))return"this app is not allowed to connect to this server";try{return await resolver.fetchCimd(clientId)}catch(error){let reason=`client metadata document could not be used: ${error instanceof Error?error.message:String(error)}`,cause=error instanceof Error&&error.cause!==void 0?` (${error.cause instanceof Error?error.cause.message:String(error.cause)})`:"";return console.warn(`[mcp-use] oauthProxy: refused ${printable(clientId)}: ${printable(reason+cause)}`),reason}}let configured=resolver.configured.get(clientId);if(configured!==void 0)return configured;if(resolver.dcr&&clientId.startsWith("mcp_client_")){let registered=await resolver.store.get(keys.client(clientId));if(isClientRecord(registered))return registered}if(resolver.dcr&&clientId===resolver.upstreamClientId){if(typeof redirectUri!="string")return"redirect_uri is required for this client";let problem=redirectUriProblem(redirectUri);return problem!==void 0?problem:{clientId,redirectUris:[redirectUri],source:"dcr"}}return"unknown client_id"}function isClientRecord(value){return isRecord(value)&&typeof value.clientId=="string"&&Array.isArray(value.redirectUris)}var CIMD_MAX_BYTES=5*1024,CIMD_TIMEOUT_MS=1e4,CIMD_CACHE_MS=300*1e3,CIMD_CACHE_SIZE=256,CIMD_UNAVAILABLE="metadata document could not be loaded",CIMD_HEADERS={accept:"application/json","user-agent":"mcp-use-oauth-proxy"};function createCimdFetcher(fetchImpl,resolver,transport=defaultPinnedTransport){let cache=new Map;return async clientId=>{let cached=cache.get(clientId);if(cached!==void 0&&cached.expiresAt>Date.now())return cached.client;let url=new URL(clientId),pinned=resolver===!1?void 0:{addresses:await resolvePublicAddresses(url.hostname,await resolver()),transport:await transport()},signal=AbortSignal.timeout(CIMD_TIMEOUT_MS),response;try{response=pinned?.transport===void 0?await fetchImpl(url.href,{redirect:"manual",headers:{...CIMD_HEADERS},signal}):await requestPinned(pinned.transport,url,pinned.addresses,signal)}catch(error){throw new Error(CIMD_UNAVAILABLE,{cause:error})}if(response.status!==200)throw new Error(CIMD_UNAVAILABLE,{cause:new Error(`HTTP ${response.status}`)});let text=await readLimited(response,CIMD_MAX_BYTES),document;try{document=JSON.parse(text)}catch{throw new Error("metadata document is not JSON")}if(!isRecord(document)||document.client_id!==clientId)throw new Error("metadata document client_id does not match its URL");let parsed=OAuthClientMetadataSchema.safeParse(document);if(!parsed.success||parsed.data.redirect_uris.length===0)throw new Error("metadata document has no valid redirect_uris");let methods=document.token_endpoint_auth_methods_supported,supportsNone=Array.isArray(methods)?methods.includes("none"):parsed.data.token_endpoint_auth_method===void 0||parsed.data.token_endpoint_auth_method==="none";if(document.client_secret!==void 0||!supportsNone)throw new Error("only public clients (token_endpoint_auth_method none) are supported");for(let uri of parsed.data.redirect_uris){let problem=redirectUriProblem(uri);if(problem!==void 0)throw new Error(problem)}let client={clientId,redirectUris:[...parsed.data.redirect_uris],...typeof parsed.data.client_name=="string"&&{clientName:parsed.data.client_name.slice(0,MAX_NAME_LENGTH)},source:"cimd"};if(cache.size>=CIMD_CACHE_SIZE){let oldest=cache.keys().next().value;oldest!==void 0&&cache.delete(oldest)}return cache.set(clientId,{client,expiresAt:Date.now()+CIMD_CACHE_MS}),client}}async function readLimited(response,limit){if(Number(response.headers.get("content-length")??"0")>limit)throw new Error("metadata document is too large");if(response.body===null)return"";let reader=response.body.getReader(),chunks=[],total=0;for(;;){let{done,value}=await reader.read();if(done)break;if(total+=value.byteLength,total>limit)throw await reader.cancel(),new Error("metadata document is too large");chunks.push(value)}let bytes=new Uint8Array(total),offset=0;for(let chunk of chunks)bytes.set(chunk,offset),offset+=chunk.byteLength;return new TextDecoder().decode(bytes)}function requestPinned(transport,url,addresses,signal){let entries=addresses.map(address=>({address,family:address.includes(":")?6:4})),lookup=(_hostname,options,callback)=>{let first=entries[0];options.all===!0?callback(null,entries):first!==void 0?callback(null,first.address,first.family):callback(new Error("no checked address"),"")};return new Promise((resolve,reject)=>{let request=transport.request(url,{headers:{...CIMD_HEADERS},signal,lookup},response=>{let status=response.statusCode??0;if(status!==200){response.destroy(),reject(new Error(`HTTP ${status}`));return}let headers=new Headers;for(let[name,value]of Object.entries(response.headers))typeof value=="string"&&headers.set(name,value);resolve(new Response(transport.toWeb(response),{status:200,headers}))});request.on("error",reject),request.end()})}var defaultTransport;function defaultPinnedTransport(){return defaultTransport??=(async()=>{let versions=globalThis.process?.versions,userAgent=globalThis.navigator?.userAgent;if(typeof versions?.bun=="string"||typeof versions?.node=="string"&&!("Deno"in globalThis)&&userAgent!=="Cloudflare-Workers")try{let[https,stream]=await Promise.all([import(["node","https"].join(":")),import(["node","stream"].join(":"))]),request=https.request??https.default?.request,readable=stream.Readable??stream.default?.Readable,toWeb=readable?.toWeb?.bind(readable);return typeof request!="function"||typeof toWeb!="function"?void 0:{request:(url,options,onResponse)=>request(url,options,onResponse),toWeb}}catch{return}})(),defaultTransport}async function resolvePublicAddresses(hostname,resolve){let host=hostname.replace(/^\[|\]$/g,"");if(host==="localhost"||host.endsWith(".localhost"))throw new Error("metadata document host is not public");if(isIpLiteral(host)){if(isPrivateAddress(host))throw new Error("metadata document host is not public");return[host]}if(resolve===void 0)throw new Error("metadata document host cannot be checked: this runtime has no node:dns to resolve it. Enable node:dns (nodejs_compat on Cloudflare Workers), or pass oauthProxy a fetch that enforces your own network policy");let addresses;try{addresses=await resolve(host)}catch{throw new Error("metadata document host does not resolve")}if(addresses.length===0||addresses.some(address=>isPrivateAddress(address)))throw new Error("metadata document host is not public");return addresses}function hostResolverFrom(dns,userAgent){let namespace=dns,promises=namespace?.promises??namespace?.default?.promises;if(promises===void 0)return;if(userAgent==="Cloudflare-Workers"){let{resolve4,resolve6}=promises;return typeof resolve4!="function"||typeof resolve6!="function"?void 0:async hostname=>{let results=await Promise.allSettled([resolve4(hostname),resolve6(hostname)]);if(results.every(result=>result.status==="rejected"))throw new Error("host does not resolve");return results.flatMap(result=>result.status==="fulfilled"?result.value:[])}}let lookup=promises.lookup;if(typeof lookup=="function")return async hostname=>(await lookup(hostname,{all:!0,verbatim:!0})).map(entry=>entry.address)}var defaultResolver;function defaultHostResolver(){return defaultResolver??=(async()=>{let specifier=["node","dns"].join(":"),dns;try{dns=await import(specifier)}catch{return}let userAgent=globalThis.navigator?.userAgent;return hostResolverFrom(dns,typeof userAgent=="string"?userAgent:void 0)})(),defaultResolver}function isIpLiteral(host){return/^\d{1,3}(?:\.\d{1,3}){3}$/.test(host)||host.includes(":")}function isPrivateAddress(address){let ipv4=address.match(/^(?:::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/i);if(ipv4!==null){let[a,b]=[Number(ipv4[1]),Number(ipv4[2])];return a===0||a===10||a===127||a===100&&b>=64&&b<=127||a===169&&b===254||a===172&&b>=16&&b<=31||a===192&&b===0&&Number(ipv4[3])===0||a===192&&b===168||a===198&&(b===18||b===19)||a>=224}let ipv6=address.toLowerCase();return ipv6==="::"||ipv6==="::1"||/^f[cd]/.test(ipv6)||/^fe[89a-f]/.test(ipv6)||ipv6.startsWith("ff")||ipv6.startsWith("64:ff9b:")||ipv6.startsWith("::ffff:")}import{deleteCookie,getCookie,getSignedCookie,setSignedCookie}from"hono/cookie";var PAGE_CSP="default-src 'none'; style-src 'unsafe-inline'; img-src https: data:; frame-ancestors 'none'; base-uri 'none'";function renderDefaultConsentPage(props){let clientName=props.client.name??"An app",upstream2=escapeHtml(props.upstream),target=escapeHtml(props.serverHost),scopes=props.scopes.length===0?"":`<dt>Scopes</dt><dd><span class="chips">${props.scopes.map(scope=>`<code>${escapeHtml(scope)}</code>`).join("")}</span></dd>`;return page(`Allow ${clientName}?`,`<h1>Allow <span>${escapeHtml(clientName)}</span> to connect to ${target}?</h1>
|
|
1
|
+
import{SecureStore,UpstreamError,assertEndpoint,assertRedirectUpstream,assertStorage,deriveKeyring,exchangeUpstreamCode,isBuilding,isMemoryStorage,memoryStorage,normalizeSecrets,pkceChallenge,printable,randomKeyring,randomToken,refreshUpstreamTokens,sha256,timingSafeEqual,upstream}from"../chunk-3XIIMBWV.js";import{createJwtVerifier,invalidToken,oauthCustomProvider,oauthEnvironmentValue}from"../chunk-4ICJVJOI.js";import{assertOAuthMetadata,isLocalhost,isRecord,trimTrailingSlashes}from"../chunk-JX52OYMQ.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 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 resolveOAuthMetadata(provider,resource){let metadata=provider.oauthMetadata;if(typeof metadata!="function")return metadata;let resolved=metadata(new URL(resource.href));return assertOAuthMetadata(resolved),resolved}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 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),metadata=resolveOAuthMetadata(provider,resource);return async(request,next)=>{let response=oauthMetadataResponse(request,{oauthMetadata:metadata,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()}}import{OAuthClientMetadataSchema}from"@modelcontextprotocol/core";var keys={client:id=>`client:${id}`,transaction:id=>`txn:${id}`,upstreamState:hash=>`ustate:${hash}`,code:hash=>`code:${hash}`,codeUsed:hash=>`codeused:${hash}`,grant:id=>`grant:${id}`,revokedGrant:id=>`revoked:${id}`,access:hash=>`at:${hash}`,refresh:hash=>`rt:${hash}`,refreshLock:hash=>`lock:rt:${hash}`,upstream:userKey=>`up:${userKey}`,upstreamLock:userKey=>`lock:up:${userKey}`};var BLOCKED_SCHEMES=new Set(["javascript:","data:","file:","vbscript:","blob:","about:","ftp:","ws:","wss:"]),DCR_CLIENT_TTL=365*24*60*60,MAX_REDIRECT_URIS=20,MAX_NAME_LENGTH=200;function isLoopbackRedirect(uri){try{let url=new URL(uri);return url.protocol==="http:"&&isLoopbackHost(url.hostname)}catch{return!1}}function isLoopbackHost(hostname){return hostname==="127.0.0.1"||hostname==="[::1]"||hostname==="localhost"}function redirectUriProblem(uri){if(typeof uri!="string"||uri.length>2e3)return"redirect_uris must be strings";let url;try{url=new URL(uri)}catch{return`redirect URI is not an absolute URI: ${uri}`}if(url.hash!=="")return"redirect URIs must not have a fragment";if(url.username!==""||url.password!=="")return"redirect URIs must not contain credentials";if(url.protocol!=="https:"){if(url.protocol==="http:")return isLoopbackHost(url.hostname)?void 0:"HTTP redirect URIs are allowed only on loopback addresses";if(BLOCKED_SCHEMES.has(url.protocol))return`redirect URI scheme ${url.protocol} is not allowed`}}function matchRedirectUri(requested,registered){if(registered.includes(requested))return!0;if(!isLoopbackRedirect(requested))return!1;let withoutPort=uri=>{let url=new URL(uri);return url.port="",url.href},target=withoutPort(requested);return registered.some(uri=>isLoopbackRedirect(uri)&&withoutPort(uri)===target)}function configuredClients(clients){let byId=new Map;if(clients===void 0)return{byId,allow:void 0};if(!Array.isArray(clients)||clients.length===0)throw new TypeError("oauthProxy clients must list at least one client; leave it unset to let any client connect");let allow={urls:new Set,origins:new Set};for(let client of clients){if(typeof client=="string"){let origin=httpsOrigin(client);if(isCimdClientId(client))allow.urls.add(client);else if(origin!==void 0)allow.origins.add(origin);else throw new TypeError(`oauthProxy clients: ${client} is neither a client ID metadata document URL (https with a path) nor an https origin`);continue}let redirectUris=client?.redirectUris;if(client===null||typeof client!="object"||typeof client.clientId!="string"||client.clientId.length===0||!isStringArray(redirectUris)||redirectUris.length===0)throw new TypeError("oauthProxy clients entries must be a URL or an object with a clientId and redirectUris");if(client.clientId.startsWith("https://")||client.clientId.startsWith("mcp_client_"))throw new TypeError(`oauthProxy clients: client ${client.clientId} must not look like a metadata document URL or a registered client_id; list metadata documents as strings`);if(byId.has(client.clientId))throw new TypeError(`oauthProxy clients: client ${client.clientId} is listed twice`);for(let uri of redirectUris){let problem=redirectUriProblem(uri);if(problem!==void 0)throw new TypeError(`oauthProxy clients: ${problem}`)}byId.set(client.clientId,{clientId:client.clientId,redirectUris:[...redirectUris],...client.clientName!==void 0&&{clientName:client.clientName},source:"pre-registered"})}return{byId,allow}}function httpsOrigin(value){if(value.startsWith("https://"))try{let url=new URL(value);return url.pathname==="/"&&url.search===""&&url.hash===""&&url.username===""&&url.password===""&&value.replace(/\/$/,"")===url.origin?url.origin:void 0}catch{return}}function isStringArray(value){return Array.isArray(value)&&value.every(item=>typeof item=="string")}function isCimdClientId(clientId){if(!clientId.startsWith("https://"))return!1;try{let url=new URL(clientId);return url.pathname!=="/"&&url.hash===""&&url.username===""&&url.password===""}catch{return!1}}async function registerClient(store,body){let parsed=OAuthClientMetadataSchema.safeParse(body);if(!parsed.success)return invalidMetadata(parsed.error.issues[0]?.message??"invalid metadata");let metadata=parsed.data;if(metadata.redirect_uris.length===0||metadata.redirect_uris.length>MAX_REDIRECT_URIS)return{ok:!1,error:"invalid_redirect_uri",description:`register 1 to ${MAX_REDIRECT_URIS} redirect URIs`};for(let uri of metadata.redirect_uris){let problem=redirectUriProblem(uri);if(problem!==void 0)return{ok:!1,error:"invalid_redirect_uri",description:problem}}let grantTypes=metadata.grant_types??["authorization_code","refresh_token"];if(!grantTypes.includes("authorization_code")||grantTypes.some(grant=>grant!=="authorization_code"&&grant!=="refresh_token"))return invalidMetadata("grant_types must be authorization_code, optionally with refresh_token");if((metadata.response_types??["code"]).some(type=>type!=="code"))return invalidMetadata("response_types must be code");let clientName=typeof metadata.client_name=="string"?metadata.client_name.slice(0,MAX_NAME_LENGTH):void 0,client={clientId:`mcp_client_${randomToken(16)}`,redirectUris:[...metadata.redirect_uris],...clientName!==void 0&&{clientName},source:"dcr"};return await store.set(keys.client(client.clientId),client,DCR_CLIENT_TTL),{ok:!0,client,response:{client_id:client.clientId,client_id_issued_at:Math.floor(Date.now()/1e3),redirect_uris:client.redirectUris,grant_types:grantTypes,response_types:["code"],token_endpoint_auth_method:"none",...clientName!==void 0&&{client_name:clientName},...metadata.scope!==void 0&&{scope:metadata.scope}}}}function invalidMetadata(description){return{ok:!1,error:"invalid_client_metadata",description}}function isClientAdmitted(resolver,clientId){if(isCimdClientId(clientId)){let allow=resolver.allow;return allow===void 0||allow.urls.has(clientId)||allow.origins.has(new URL(clientId).origin)}return resolver.configured.has(clientId)?!0:resolver.dcr&&(clientId.startsWith("mcp_client_")||clientId===resolver.upstreamClientId)}async function resolveClient(resolver,clientId,redirectUri){if(isCimdClientId(clientId)){if(!isClientAdmitted(resolver,clientId))return"this app is not allowed to connect to this server";try{return await resolver.fetchCimd(clientId)}catch(error){let reason=`client metadata document could not be used: ${error instanceof Error?error.message:String(error)}`,cause=error instanceof Error&&error.cause!==void 0?` (${error.cause instanceof Error?error.cause.message:String(error.cause)})`:"";return console.warn(`[mcp-use] oauthProxy: refused ${printable(clientId)}: ${printable(reason+cause)}`),reason}}let configured=resolver.configured.get(clientId);if(configured!==void 0)return configured;if(resolver.dcr&&clientId.startsWith("mcp_client_")){let registered=await resolver.store.get(keys.client(clientId));if(isClientRecord(registered))return registered}if(resolver.dcr&&clientId===resolver.upstreamClientId){if(typeof redirectUri!="string")return"redirect_uri is required for this client";let problem=redirectUriProblem(redirectUri);return problem!==void 0?problem:{clientId,redirectUris:[redirectUri],source:"dcr"}}return"unknown client_id"}function isClientRecord(value){return isRecord(value)&&typeof value.clientId=="string"&&Array.isArray(value.redirectUris)}var CIMD_MAX_BYTES=5*1024,CIMD_TIMEOUT_MS=1e4,CIMD_CACHE_MS=300*1e3,CIMD_CACHE_SIZE=256,CIMD_UNAVAILABLE="metadata document could not be loaded",CIMD_HEADERS={accept:"application/json","user-agent":"mcp-use-oauth-proxy"};function createCimdFetcher(fetchImpl,resolver,transport=defaultPinnedTransport){let cache=new Map;return async clientId=>{let cached=cache.get(clientId);if(cached!==void 0&&cached.expiresAt>Date.now())return cached.client;let url=new URL(clientId),pinned=resolver===!1?void 0:{addresses:await resolvePublicAddresses(url.hostname,await resolver()),transport:await transport()},signal=AbortSignal.timeout(CIMD_TIMEOUT_MS),response;try{response=pinned?.transport===void 0?await fetchImpl(url.href,{redirect:"manual",headers:{...CIMD_HEADERS},signal}):await requestPinned(pinned.transport,url,pinned.addresses,signal)}catch(error){throw new Error(CIMD_UNAVAILABLE,{cause:error})}if(response.status!==200)throw new Error(CIMD_UNAVAILABLE,{cause:new Error(`HTTP ${response.status}`)});let text=await readLimited(response,CIMD_MAX_BYTES),document;try{document=JSON.parse(text)}catch{throw new Error("metadata document is not JSON")}if(!isRecord(document)||document.client_id!==clientId)throw new Error("metadata document client_id does not match its URL");let parsed=OAuthClientMetadataSchema.safeParse(document);if(!parsed.success||parsed.data.redirect_uris.length===0)throw new Error("metadata document has no valid redirect_uris");let methods=document.token_endpoint_auth_methods_supported,supportsNone=Array.isArray(methods)?methods.includes("none"):parsed.data.token_endpoint_auth_method===void 0||parsed.data.token_endpoint_auth_method==="none";if(document.client_secret!==void 0||!supportsNone)throw new Error("only public clients (token_endpoint_auth_method none) are supported");for(let uri of parsed.data.redirect_uris){let problem=redirectUriProblem(uri);if(problem!==void 0)throw new Error(problem)}let client={clientId,redirectUris:[...parsed.data.redirect_uris],...typeof parsed.data.client_name=="string"&&{clientName:parsed.data.client_name.slice(0,MAX_NAME_LENGTH)},source:"cimd"};if(cache.size>=CIMD_CACHE_SIZE){let oldest=cache.keys().next().value;oldest!==void 0&&cache.delete(oldest)}return cache.set(clientId,{client,expiresAt:Date.now()+CIMD_CACHE_MS}),client}}async function readLimited(response,limit){if(Number(response.headers.get("content-length")??"0")>limit)throw new Error("metadata document is too large");if(response.body===null)return"";let reader=response.body.getReader(),chunks=[],total=0;for(;;){let{done,value}=await reader.read();if(done)break;if(total+=value.byteLength,total>limit)throw await reader.cancel(),new Error("metadata document is too large");chunks.push(value)}let bytes=new Uint8Array(total),offset=0;for(let chunk of chunks)bytes.set(chunk,offset),offset+=chunk.byteLength;return new TextDecoder().decode(bytes)}function requestPinned(transport,url,addresses,signal){let entries=addresses.map(address=>({address,family:address.includes(":")?6:4})),lookup=(_hostname,options,callback)=>{let first=entries[0];options.all===!0?callback(null,entries):first!==void 0?callback(null,first.address,first.family):callback(new Error("no checked address"),"")};return new Promise((resolve,reject)=>{let request=transport.request(url,{headers:{...CIMD_HEADERS},signal,lookup},response=>{let status=response.statusCode??0;if(status!==200){response.destroy(),reject(new Error(`HTTP ${status}`));return}let headers=new Headers;for(let[name,value]of Object.entries(response.headers))typeof value=="string"&&headers.set(name,value);resolve(new Response(transport.toWeb(response),{status:200,headers}))});request.on("error",reject),request.end()})}var defaultTransport;function defaultPinnedTransport(){return defaultTransport??=(async()=>{let versions=globalThis.process?.versions,userAgent=globalThis.navigator?.userAgent;if(typeof versions?.bun=="string"||typeof versions?.node=="string"&&!("Deno"in globalThis)&&userAgent!=="Cloudflare-Workers")try{let[https,stream]=await Promise.all([import(["node","https"].join(":")),import(["node","stream"].join(":"))]),request=https.request??https.default?.request,readable=stream.Readable??stream.default?.Readable,toWeb=readable?.toWeb?.bind(readable);return typeof request!="function"||typeof toWeb!="function"?void 0:{request:(url,options,onResponse)=>request(url,options,onResponse),toWeb}}catch{return}})(),defaultTransport}async function resolvePublicAddresses(hostname,resolve){let host=hostname.replace(/^\[|\]$/g,"");if(host==="localhost"||host.endsWith(".localhost"))throw new Error("metadata document host is not public");if(isIpLiteral(host)){if(isPrivateAddress(host))throw new Error("metadata document host is not public");return[host]}if(resolve===void 0)throw new Error("metadata document host cannot be checked: this runtime has no node:dns to resolve it. Enable node:dns (nodejs_compat on Cloudflare Workers), or pass oauthProxy a fetch that enforces your own network policy");let addresses;try{addresses=await resolve(host)}catch{throw new Error("metadata document host does not resolve")}if(addresses.length===0||addresses.some(address=>isPrivateAddress(address)))throw new Error("metadata document host is not public");return addresses}function hostResolverFrom(dns,userAgent){let namespace=dns,promises=namespace?.promises??namespace?.default?.promises;if(promises===void 0)return;if(userAgent==="Cloudflare-Workers"){let{resolve4,resolve6}=promises;return typeof resolve4!="function"||typeof resolve6!="function"?void 0:async hostname=>{let results=await Promise.allSettled([resolve4(hostname),resolve6(hostname)]);if(results.every(result=>result.status==="rejected"))throw new Error("host does not resolve");return results.flatMap(result=>result.status==="fulfilled"?result.value:[])}}let lookup=promises.lookup;if(typeof lookup=="function")return async hostname=>(await lookup(hostname,{all:!0,verbatim:!0})).map(entry=>entry.address)}var defaultResolver;function defaultHostResolver(){return defaultResolver??=(async()=>{let specifier=["node","dns"].join(":"),dns;try{dns=await import(specifier)}catch{return}let userAgent=globalThis.navigator?.userAgent;return hostResolverFrom(dns,typeof userAgent=="string"?userAgent:void 0)})(),defaultResolver}function isIpLiteral(host){return/^\d{1,3}(?:\.\d{1,3}){3}$/.test(host)||host.includes(":")}function isPrivateAddress(address){let ipv4=address.match(/^(?:::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/i);if(ipv4!==null){let[a,b]=[Number(ipv4[1]),Number(ipv4[2])];return a===0||a===10||a===127||a===100&&b>=64&&b<=127||a===169&&b===254||a===172&&b>=16&&b<=31||a===192&&b===0&&Number(ipv4[3])===0||a===192&&b===168||a===198&&(b===18||b===19)||a>=224}let ipv6=address.toLowerCase();return ipv6==="::"||ipv6==="::1"||/^f[cd]/.test(ipv6)||/^fe[89a-f]/.test(ipv6)||ipv6.startsWith("ff")||ipv6.startsWith("64:ff9b:")||ipv6.startsWith("::ffff:")}import{deleteCookie,getCookie,getSignedCookie,setSignedCookie}from"hono/cookie";var PAGE_CSP="default-src 'none'; style-src 'unsafe-inline'; img-src https: data:; frame-ancestors 'none'; base-uri 'none'";function renderDefaultConsentPage(props){let clientName=props.client.name??"An app",upstream2=escapeHtml(props.upstream),target=escapeHtml(props.serverHost),scopes=props.scopes.length===0?"":`<dt>Scopes</dt><dd><span class="chips">${props.scopes.map(scope=>`<code>${escapeHtml(scope)}</code>`).join("")}</span></dd>`;return page(`Allow ${clientName}?`,`<h1>Allow <span>${escapeHtml(clientName)}</span> to connect to ${target}?</h1>
|
|
2
2
|
<dl>
|
|
3
3
|
<dt>App</dt><dd><b>${escapeHtml(clientName)}</b></dd>
|
|
4
4
|
<dt>Returns to</dt><dd>After sign-in, you return to <b>${escapeHtml(props.redirectHost)}</b>.</dd>
|
|
@@ -50,4 +50,4 @@ button.secondary{background:var(--btn2);color:var(--fg);border-color:var(--btn2-
|
|
|
50
50
|
${body}
|
|
51
51
|
</main></body>
|
|
52
52
|
</html>`}function escapeHtml(value){return value.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var TRANSACTION_TTL=600,CODE_TTL=60,REFRESH_TTL=720*60*60,REFRESH_GRACE=60,UPSTREAM_TTL=1440*60*60,REMEMBER_TTL=365*24*60*60,ROUND_COOKIE_LIMIT=5,UPSTREAM_REFRESH_MARGIN=60,REVOKED_GRANT_TTL=3600,LOCK_TTL=60,LOCK_DEADLINE=30,GrantError=class extends Error{constructor(kind,message){super(message);this.kind=kind}},ProxyRuntime=class{config;issuer;paths;#secure;#cookies;constructor(config){this.config=config,this.issuer=config.resource.origin;let base=`${config.basePath==="/"?"":config.basePath}/oauth`;this.paths={authorize:`${base}/authorize`,consent:`${base}/consent`,callback:`${base}/callback`,token:`${base}/token`,register:`${base}/register`,revoke:`${base}/revoke`},this.#secure=config.resource.protocol==="https:";let prefix=this.#secure?"__Host-":"";this.#cookies={bind:`${prefix}mcp-oauth-bind`,csrf:`${prefix}mcp-oauth-csrf`,remember:`${prefix}mcp-oauth-consent`}}url(path){return new URL(path,this.issuer).href}static metadata(resource,basePath,options){let base=`${resource.origin}${basePath==="/"?"":basePath}/oauth`;return{issuer:resource.origin,authorization_endpoint:`${base}/authorize`,token_endpoint:`${base}/token`,...options.dcr&&{registration_endpoint:`${base}/register`},revocation_endpoint:`${base}/revoke`,response_types_supported:["code"],response_modes_supported:["query"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"],token_endpoint_auth_methods_supported:["none"],revocation_endpoint_auth_methods_supported:["none"],...options.scopes.length>0&&{scopes_supported:[...options.scopes]},client_id_metadata_document_supported:options.cimd,authorization_response_iss_parameter_supported:!0}}async authorize(c){let query=new URL(c.req.url).searchParams,clientId=query.get("client_id");if(clientId===null||clientId==="")return this.#errorPage(c,400,"Missing client","The request has no client_id.");let requestedRedirect=query.get("redirect_uri"),client=await resolveClient(this.config.clients,clientId,requestedRedirect);if(typeof client=="string")return this.#errorPage(c,400,"Unknown app",client);let redirectUri=requestedRedirect??(client.redirectUris.length===1?client.redirectUris[0]:void 0);if(redirectUri===void 0||!matchRedirectUri(redirectUri,client.redirectUris))return this.#errorPage(c,400,"Invalid redirect","The redirect_uri is not registered for this app.");let state=query.get("state")??void 0,fail=(error,description)=>this.#redirectToClient(c,redirectUri,{error,error_description:description,...state!==void 0&&{state}});if(query.get("response_type")!=="code")return fail("unsupported_response_type","response_type must be code");let codeChallenge=query.get("code_challenge");if(codeChallenge===null||query.get("code_challenge_method")!=="S256"||!/^[A-Za-z0-9_-]{43}$/.test(codeChallenge))return fail("invalid_request","PKCE with code_challenge_method S256 is required");let resources=query.getAll("resource");if(resources.length>1||resources.length===1&&!this.#isOwnResource(resources[0]))return fail("invalid_target","resource must be this MCP server");let scopes=this.#grantScopes(query.get("scope")),transactionId=randomToken(24),transaction={clientId:client.clientId,redirectUri,...state!==void 0&&{clientState:state},codeChallenge,resource:this.config.resource.href,scopes,upstreamVerifier:randomToken(32)};return await this.config.store.set(keys.transaction(transactionId),transaction,TRANSACTION_TTL),await this.#skipConsent(c,client,redirectUri)?this.#startUpstream(c,transactionId,transaction):this.#consentPage(c,transactionId,client,redirectUri)}async#skipConsent(c,client,redirectUri){let consent=this.config.consent;if(consent===!1)return!0;if(!redirectUri.startsWith("https://")||consent.mode!=="remember")return!1;let remembered=await this.#readCookie(c,this.#cookies.remember);if(remembered===void 0)return!1;let entry=await sha256(`${client.clientId} ${redirectUri}`);return remembered.split(".").includes(entry)}async#consentPage(c,transactionId,client,redirectUri){let csrf=randomToken(24);await this.#setRoundCookie(c,this.#cookies.csrf,transactionId,`${transactionId}.${csrf}`);let upstream2=this.config.upstream,props={client:{id:client.clientId,...client.clientName!==void 0&&{name:client.clientName},...client.source==="cimd"&&{host:new URL(client.clientId).host},verified:client.source!=="dcr"},redirectHost:redirectHost(redirectUri),upstream:upstream2.name,scopes:[...upstream2.scopes],serverHost:this.config.serverHost,form:{action:`${this.paths.consent}?${new URLSearchParams({txn:transactionId,csrf})}`}},consent=this.config.consent,html=consent!==!1&&consent.page!==void 0?await renderCustomConsentPage(consent.page,props):renderDefaultConsentPage(props);return this.#html(c,200,html)}async consent(c){let query=new URL(c.req.url).searchParams,transactionId=query.get("txn")??"",csrf=query.get("csrf")??"",form=await formBody(c),csrfCookie=await this.#roundCookie(this.#cookies.csrf,transactionId),cookie=await this.#readCookie(c,csrfCookie);if(transactionId===""||csrf===""||cookie===void 0||!timingSafeEqual(cookie,`${transactionId}.${csrf}`))return this.#errorPage(c,403,"Sign-in expired","This approval form is no longer valid.");deleteCookie(c,csrfCookie,this.#cookieOptions(0));let transaction=await this.config.store.get(keys.transaction(transactionId));return transaction===void 0?this.#errorPage(c,400,"Sign-in expired","This sign-in took too long."):form.get("decision")!=="allow"?(await this.config.store.delete(keys.transaction(transactionId)),this.#redirectToClient(c,transaction.redirectUri,{error:"access_denied",error_description:"The user denied access",...transaction.clientState!==void 0&&{state:transaction.clientState}})):(await this.#rememberIfAsked(c,transaction),this.#startUpstream(c,transactionId,transaction))}async#rememberIfAsked(c,transaction){let consent=this.config.consent;consent!==!1&&consent.mode==="remember"&&transaction.redirectUri.startsWith("https://")&&await this.#remember(c,transaction)}async#remember(c,transaction){let entry=await sha256(`${transaction.clientId} ${transaction.redirectUri}`),current=await this.#readCookie(c,this.#cookies.remember)??"",entries=[entry,...current.split(".").filter(item=>item!==""&&item!==entry)];await this.#setCookie(c,this.#cookies.remember,entries.slice(0,20).join("."),REMEMBER_TTL)}async#startUpstream(c,transactionId,transaction,extraParams={}){let upstream2=this.config.upstream,state=randomToken(32);await this.config.store.set(keys.upstreamState(await sha256(state)),transactionId,TRANSACTION_TTL),await this.#setRoundCookie(c,this.#cookies.bind,state,state);let target=new URL(upstream2.authorizationEndpoint),params=target.searchParams;params.set("response_type","code"),params.set("client_id",upstream2.clientId),params.set("redirect_uri",this.url(this.paths.callback)),params.set("state",state),upstream2.scopes.length>0&¶ms.set("scope",upstream2.scopes.join(" ")),upstream2.pkce!==!1&&(params.set("code_challenge",await pkceChallenge(transaction.upstreamVerifier)),params.set("code_challenge_method","S256"));for(let[name,value]of Object.entries({...upstream2.authorizeParams,...extraParams}))params.set(name,value);return this.#redirect(c,target.href)}async callback(c){let upstream2=this.config.upstream,params=new URL(c.req.url).searchParams,state=params.get("state");if(state===null||state==="")return this.#errorPage(c,400,"Sign-in failed","The sign-in response has no state.");let transactionId=await this.config.store.take(keys.upstreamState(await sha256(state)));if(typeof transactionId!="string")return this.#errorPage(c,400,"Sign-in expired","This sign-in expired or was already used.");let bindCookie=await this.#roundCookie(this.#cookies.bind,state),bound=await this.#readCookie(c,bindCookie);if(bound===void 0||!timingSafeEqual(bound,state))return this.#errorPage(c,403,"Sign-in not recognized","This sign-in was not started in this browser.");deleteCookie(c,bindCookie,this.#cookieOptions(0));let transaction=await this.config.store.get(keys.transaction(transactionId));if(transaction===void 0)return this.#errorPage(c,400,"Sign-in expired","This sign-in took too long.");let finish=values=>this.#finish(c,transactionId,transaction,values),upstreamError=params.get("error");if(upstreamError!==null){let code=printable(upstreamError,64),description=params.get("error_description"),reason=`${upstream2.name} returned ${code}${description===null?"":`: ${printable(description)}`}`;return code==="access_denied"?console.info(`[mcp-use] oauthProxy: sign-in declined. ${reason}`):console.error(`[mcp-use] oauthProxy: sign-in failed. ${reason}`),finish({error:code==="access_denied"?"access_denied":"server_error",error_description:errorDescription(`${upstream2.name} sign-in did not complete (${code})`)})}let tokens,user;try{if(tokens=await exchangeUpstreamCode(upstream2,this.config.fetch,{callbackParams:params,redirectUri:this.url(this.paths.callback),codeVerifier:upstream2.pkce===!1?void 0:transaction.upstreamVerifier}),user=await upstream2.fetchUser(tokens,this.config.fetch),typeof user?.subject!="string"||user.subject==="")throw new Error("fetchUser returned no subject")}catch(error){return console.error(`[mcp-use] oauthProxy: ${upstream2.name} sign-in failed:`,describe(error)),finish(signInFailure(upstream2.name,error))}let userKey=`${upstream2.id}:${user.subject}`;if(tokens.refreshToken===void 0&&upstream2.retryWithoutRefreshToken!==void 0&&transaction.retried!==!0&&(await this.config.store.get(keys.upstream(userKey)))?.tokens.refreshToken===void 0){let retry={...transaction,retried:!0,upstreamVerifier:randomToken(32)};return await this.config.store.set(keys.transaction(transactionId),retry,TRANSACTION_TTL),this.#startUpstream(c,transactionId,retry,upstream2.retryWithoutRefreshToken)}return this.#completeSignIn(c,transactionId,transaction,user,tokens)}async#completeSignIn(c,transactionId,transaction,user,tokens){let userKey=`${this.config.upstream.id}:${user.subject}`,record=await this.#saveUpstream(userKey,tokens,user),code=randomToken(32),codeRecord={clientId:transaction.clientId,redirectUri:transaction.redirectUri,codeChallenge:transaction.codeChallenge,resource:transaction.resource,scopes:transaction.scopes,userKey,generation:record.generation};return await this.config.store.set(keys.code(await sha256(code)),codeRecord,CODE_TTL),this.#finish(c,transactionId,transaction,{code})}async#finish(c,transactionId,transaction,values){return await this.config.store.delete(keys.transaction(transactionId)),this.#redirectToClient(c,transaction.redirectUri,{...values,...transaction.clientState!==void 0&&{state:transaction.clientState}})}async#saveUpstream(userKey,tokens,user){let existing=await this.config.store.get(keys.upstream(userKey)),refreshToken=tokens.refreshToken??existing?.tokens.refreshToken,record={userKey,generation:existing?.generation??randomToken(16),version:(existing?.version??0)+1,tokens:{...tokens,...refreshToken!==void 0&&{refreshToken}},user};return await this.config.store.set(keys.upstream(userKey),record,UPSTREAM_TTL),record}async token(c){let form=await formBody(c);try{switch(form.get("grant_type")){case"authorization_code":return await this.#authorizationCodeGrant(c,form);case"refresh_token":return await this.#refreshTokenGrant(c,form);default:return this.#tokenError(c,"unsupported_grant_type","grant_type must be authorization_code or refresh_token")}}catch(error){if(error instanceof GrantError)return error.kind==="transient"?this.#tokenError(c,"temporarily_unavailable",error.message,503):this.#tokenError(c,"invalid_grant",error.message);throw error}}async#authorizationCodeGrant(c,form){let code=form.get("code")??"",codeHash=await sha256(code),record=code===""?void 0:await this.config.store.take(keys.code(codeHash));if(record===void 0){let grantId=await this.config.store.get(keys.codeUsed(codeHash));return typeof grantId=="string"&&await this.#endGrant(grantId),this.#tokenError(c,"invalid_grant","The authorization code is invalid, expired, or used")}if(form.get("client_id")!==record.clientId)return this.#tokenError(c,"invalid_grant","The code was issued to another client");if(!isClientAdmitted(this.config.clients,record.clientId))return this.#clientNotAllowed(c);if(form.get("redirect_uri")!==null&&form.get("redirect_uri")!==record.redirectUri)return this.#tokenError(c,"invalid_grant","redirect_uri does not match the authorization request");let resources=form.getAll("resource");if(resources.length>1||resources.length===1&&!this.#isOwnResource(resources[0]))return this.#tokenError(c,"invalid_target","resource must be this MCP server");let verifier=form.get("code_verifier")??"";if(!/^[A-Za-z0-9._~-]{43,128}$/.test(verifier)||!timingSafeEqual(await pkceChallenge(verifier),record.codeChallenge))return this.#tokenError(c,"invalid_grant","code_verifier does not match the code challenge");let upstream2=await this.#liveUpstream(record.userKey,record.generation);await this.#freshUpstream(upstream2);let grant={id:randomToken(16),clientId:record.clientId,userKey:record.userKey,generation:record.generation,scopes:record.scopes,resource:record.resource};return await this.config.store.set(keys.grant(grant.id),grant,REFRESH_TTL),await this.config.store.add(keys.codeUsed(codeHash),grant.id,CODE_TTL),this.#tokenResponse(c,grant,grant.scopes)}async#refreshTokenGrant(c,form){let token=form.get("refresh_token")??"";if(!token.startsWith("mcp_rt_"))return this.#tokenError(c,"invalid_grant","The refresh token is invalid");let hash=await sha256(token),lock=await this.#lock(keys.refreshLock(hash));try{let record=await this.config.store.get(keys.refresh(hash));if(record===void 0)return this.#tokenError(c,"invalid_grant","The refresh token is invalid or expired");let grant=await this.config.store.get(keys.grant(record.grantId));if(grant===void 0)return this.#tokenError(c,"invalid_grant","The grant was revoked");if(form.get("client_id")!==record.clientId)return this.#tokenError(c,"invalid_grant","The refresh token was issued to another client");if(!isClientAdmitted(this.config.clients,record.clientId))return await this.#endGrant(grant.id),await this.config.store.delete(keys.refresh(hash)),this.#clientNotAllowed(c);let asked=(form.get("scope")??"").split(" ").filter(Boolean);if(!asked.every(scope=>grant.scopes.includes(scope)))return this.#tokenError(c,"invalid_scope","scope exceeds the original grant");let scopes=asked.length===0?grant.scopes:grant.scopes.filter(scope=>asked.includes(scope)),resources=form.getAll("resource");if(resources.length>1||resources.length===1&&!this.#isOwnResource(resources[0]))return this.#tokenError(c,"invalid_target","resource must be this MCP server");let now=seconds();if(record.state==="rotated"&&!(record.graceUsed!==!0&&record.rotatedAt!==void 0&&now-record.rotatedAt<=REFRESH_GRACE))return await this.#endGrant(grant.id),await this.config.store.delete(keys.refresh(hash)),this.#tokenError(c,"invalid_grant","The refresh token was already used");let upstream2=await this.#liveUpstream(grant.userKey,grant.generation),fresh=await this.#freshUpstream(upstream2);if(fresh.tokens.expiresAt!==void 0&&fresh.tokens.expiresAt<=now&&fresh.tokens.refreshToken===void 0)throw new GrantError("expired",`The ${this.config.upstream.name} sign-in expired`);if(!await lock.held())throw new GrantError("transient","The token refresh took too long; try again");let rotated=record.state==="active"?{...record,state:"rotated",rotatedAt:now}:{...record,graceUsed:!0};return await this.config.store.set(keys.refresh(hash),rotated,REFRESH_TTL),await this.config.store.set(keys.grant(grant.id),grant,REFRESH_TTL),await this.config.store.get(keys.revokedGrant(grant.id))!==void 0?(await this.config.store.delete(keys.grant(grant.id)),this.#tokenError(c,"invalid_grant","The grant was revoked")):(await this.#touchUpstream(fresh),this.#tokenResponse(c,grant,scopes))}finally{await lock.release()}}async#tokenResponse(c,grant,scopes){let ttl=this.config.accessTokenTtl,accessToken=`mcp_at_${randomToken(32)}`,refreshToken=`mcp_rt_${randomToken(32)}`,access={grantId:grant.id,expiresAt:seconds()+ttl,scopes},refresh={grantId:grant.id,clientId:grant.clientId,state:"active"};return await this.config.store.set(keys.access(await sha256(accessToken)),access,ttl),await this.config.store.set(keys.refresh(await sha256(refreshToken)),refresh,REFRESH_TTL),this.#json(c,200,{access_token:accessToken,token_type:"Bearer",expires_in:ttl,refresh_token:refreshToken,...scopes.length>0&&{scope:scopes.join(" ")}})}async register(c){let body;try{body=await c.req.json()}catch{return this.#json(c,400,{error:"invalid_client_metadata",error_description:"The body must be JSON client metadata"})}let result=await registerClient(this.config.store,body);return result.ok?this.#json(c,201,result.response):this.#json(c,400,{error:result.error,error_description:result.description})}async revoke(c){let form=await formBody(c),token=form.get("token")??"",clientId=form.get("client_id"),grantId;if(token.startsWith("mcp_at_")?grantId=(await this.config.store.get(keys.access(await sha256(token))))?.grantId:token.startsWith("mcp_rt_")&&(grantId=(await this.config.store.get(keys.refresh(await sha256(token))))?.grantId),grantId!==void 0){let grant=await this.config.store.get(keys.grant(grantId));grant!==void 0&&grant.clientId===clientId&&await this.#endGrant(grantId)}return this.#json(c,200,{})}preflight(c){return c.header("access-control-allow-origin","*"),c.header("access-control-allow-methods","POST, OPTIONS"),c.header("access-control-allow-headers","content-type, authorization, mcp-protocol-version"),c.header("access-control-max-age","86400"),c.body(null,204)}async verifyAccessToken(token){if(!token.startsWith("mcp_at_"))throw invalidToken("The access token was not issued by this server");let access=await this.config.store.get(keys.access(await sha256(token)));if(access===void 0||access.expiresAt<=seconds())throw invalidToken("The access token is invalid or expired");let grant=await this.config.store.get(keys.grant(access.grantId));if(grant===void 0)throw invalidToken("The grant was revoked");if(!this.#isOwnResource(grant.resource))throw invalidToken("The access token is for another MCP server");if(!isClientAdmitted(this.config.clients,grant.clientId))throw await this.#endGrant(grant.id),invalidToken("The app is no longer allowed on this server");let upstream2;try{upstream2=await this.#freshUpstream(await this.#liveUpstream(grant.userKey,grant.generation))}catch(error){throw error instanceof GrantError&&error.kind!=="transient"?invalidToken(error.message):error}if(upstream2.tokens.expiresAt!==void 0&&upstream2.tokens.expiresAt<=seconds())throw invalidToken(`The ${this.config.upstream.name} sign-in expired`);let extra={upstreamUser:upstream2.user,upstream:{accessToken:upstream2.tokens.accessToken,scopes:[...upstream2.tokens.scopes],...upstream2.tokens.expiresAt!==void 0&&{expiresAt:upstream2.tokens.expiresAt}},userKey:grant.userKey};return{token,clientId:grant.clientId,scopes:[...access.scopes??grant.scopes],expiresAt:access.expiresAt,resource:new URL(grant.resource),extra}}async#liveUpstream(userKey,generation){let record=await this.config.store.get(keys.upstream(userKey));if(record===void 0||record.generation!==generation)throw new GrantError("revoked",`The ${this.config.upstream.name} sign-in was revoked`);return record}async#freshUpstream(record){let now=seconds(),expiresAt=record.tokens.expiresAt;if(expiresAt===void 0||expiresAt-UPSTREAM_REFRESH_MARGIN>now)return record;let refreshToken=record.tokens.refreshToken;if(refreshToken===void 0)return record;let lock=await this.#tryLock(keys.upstreamLock(record.userKey));if(lock===void 0){for(let attempt=0;attempt<25;attempt++){await sleep(200);let current=await this.#liveUpstream(record.userKey,record.generation);if(current.version!==record.version)return current}if(expiresAt>seconds())return record;throw new GrantError("transient",`${this.config.upstream.name} refresh is taking too long`)}try{let current=await this.#liveUpstream(record.userKey,record.generation);if(current.version!==record.version)return current;let tokens;try{tokens=await refreshUpstreamTokens(this.config.upstream,this.config.fetch,refreshToken)}catch(error){if(error instanceof UpstreamError&&!error.transient&&error.code==="invalid_grant"){console.warn(`[mcp-use] oauthProxy: ${describe(error)}. The user's sign-ins end; they must sign in again.`);let latest2=await this.config.store.get(keys.upstream(record.userKey));throw latest2?.generation===current.generation&&latest2.version===current.version&&await this.config.store.delete(keys.upstream(record.userKey)),new GrantError("revoked",`The ${this.config.upstream.name} sign-in was revoked`)}if(console.error(`[mcp-use] oauthProxy: ${this.config.upstream.name} refresh failed:`,describe(error)),expiresAt>seconds())return current;throw new GrantError("transient",`${this.config.upstream.name} is unavailable`)}let latest=await this.config.store.get(keys.upstream(record.userKey));if(latest===void 0||latest.generation!==current.generation)throw new GrantError("revoked",`The ${this.config.upstream.name} sign-in was revoked`);if(latest.version!==current.version)return latest;if(!await lock.held())throw new GrantError("transient",`${this.config.upstream.name} refresh took too long`);let next={...current,version:current.version+1,tokens:{...tokens,refreshToken:tokens.refreshToken??refreshToken}};return await this.config.store.set(keys.upstream(record.userKey),next,UPSTREAM_TTL),next}finally{await lock.release()}}async#touchUpstream(record){let lock=await this.#tryLock(keys.upstreamLock(record.userKey));if(lock!==void 0)try{let current=await this.config.store.get(keys.upstream(record.userKey));current!==void 0&¤t.generation===record.generation&¤t.version===record.version&&await this.config.store.set(keys.upstream(record.userKey),current,UPSTREAM_TTL)}finally{await lock.release()}}async#endGrant(grantId){await this.config.store.set(keys.revokedGrant(grantId),!0,REVOKED_GRANT_TTL),await this.config.store.delete(keys.grant(grantId))}async#lock(key){for(let attempt=0;attempt<50;attempt++){let lock=await this.#tryLock(key);if(lock!==void 0)return lock;await sleep(100)}throw new GrantError("transient","The token is in use by another request")}async#tryLock(key){let store=this.config.store,owner=randomToken(16);if(!await store.add(key,owner,LOCK_TTL))return;let deadline=Date.now()+LOCK_DEADLINE*1e3,owned=async()=>await store.get(key)===owner;return{held:async()=>Date.now()<deadline&&await owned(),release:async()=>{await owned()&&await store.delete(key)}}}#isOwnResource(value){let url;try{url=new URL(value)}catch{return!1}let strip=pathname=>pathname==="/"?"/":pathname.replace(/\/+$/,"");return url.origin===this.config.resource.origin&&(strip(url.pathname)===strip(this.config.resource.pathname)||strip(url.pathname)==="/")}#grantScopes(requested){let supported=this.config.scopes,asked=(requested??"").split(" ").filter(scope=>supported.includes(scope));return asked.length===0?[...supported]:[...new Set(asked)]}#cookieOptions(maxAge){return{path:"/",httpOnly:!0,secure:this.#secure,sameSite:"Lax",maxAge}}async#setCookie(c,name,value,maxAge){let keyring=await this.config.keyring();await setSignedCookie(c,name,value,keyring.current.cookie,this.#cookieOptions(maxAge))}async#readCookie(c,name){let keyring=await this.config.keyring();for(let key of keyring.all){let value=await getSignedCookie(c,key.cookie,name);if(typeof value=="string")return value}}async#roundCookie(base,key){return`${base}-${(await sha256(key)).slice(0,16)}`}async#setRoundCookie(c,base,key,value){let existing=Object.keys(getCookie(c)).filter(name=>name.startsWith(`${base}-`)),excess=existing.length-(ROUND_COOKIE_LIMIT-1);for(let name of existing.slice(0,Math.max(0,excess)))deleteCookie(c,name,this.#cookieOptions(0));await this.#setCookie(c,await this.#roundCookie(base,key),value,TRANSACTION_TTL)}#headers(c){c.header("cache-control","no-store"),c.header("pragma","no-cache"),c.header("referrer-policy","no-referrer"),c.header("x-content-type-options","nosniff")}#html(c,status,html){return this.#headers(c),c.header("content-security-policy",PAGE_CSP),c.header("x-frame-options","DENY"),c.html(html,status)}#errorPage(c,status,title,message){return this.#html(c,status,renderErrorPage(title,message))}#json(c,status,body){return this.#headers(c),c.header("access-control-allow-origin","*"),c.json(body,status)}#tokenError(c,error,description,status=400){return this.#json(c,status,{error,error_description:description})}#clientNotAllowed(c){return this.#tokenError(c,"invalid_client","This app is not allowed to connect to this server")}#redirect(c,location){return this.#headers(c),c.redirect(location,302)}#redirectToClient(c,redirectUri,values){let target=new URL(redirectUri);for(let[name,value]of Object.entries(values))target.searchParams.set(name,value);return target.searchParams.set("iss",this.issuer),this.#redirect(c,target.href)}};async function formBody(c){if((c.req.header("content-type")??"").includes("application/json"))try{let body=await c.req.json(),params=new URLSearchParams;if(body!==null&&typeof body=="object")for(let[name,value]of Object.entries(body))typeof value=="string"&¶ms.append(name,value);return params}catch{return new URLSearchParams}try{return new URLSearchParams(await c.req.text())}catch{return new URLSearchParams}}function redirectHost(uri){let url=new URL(uri);return url.host!==""?url.host:`${url.protocol}//`}function seconds(){return Math.floor(Date.now()/1e3)}function sleep(ms){return new Promise(resolve=>setTimeout(resolve,ms))}function describe(error){if(error instanceof UpstreamError)return`${error.message}${error.detail===void 0?"":` (${error.detail})`}`;if(!(error instanceof Error))return String(error);let text=error.stack??`${error.name}: ${error.message}`,cause=error.cause;for(let depth=0;cause instanceof Error&&depth<3;depth++){let code="code"in cause&&typeof cause.code=="string"?` [${cause.code}]`:"";text+=`
|
|
53
|
-
caused by ${cause.name}: ${cause.message}${code}`,cause=cause.cause}return text}function signInFailure(upstreamName,error){if(!(error instanceof UpstreamError))return{error:"server_error",error_description:`${upstreamName} sign-in failed`};let reason=error.upstreamCode===void 0?"":` (${error.upstreamCode})`;return{error:error.code==="access_denied"?"access_denied":error.transient?"temporarily_unavailable":"server_error",error_description:errorDescription(`${upstreamName} sign-in failed${reason}${error.description===void 0?"":`: ${error.description}`}`)}}function errorDescription(text){let safe=text.replace(/"/g,"'").replace(/[^\x20-\x21\x23-\x5b\x5d-\x7e]/g,"");return safe.length>300?`${safe.slice(0,299)}.`:safe}function github(options){options.apiUrl!==void 0&&assertEndpoint(options.apiUrl,"github apiUrl");let baseUrl=trimSlash(options.baseUrl??"https://github.com"),apiUrl=trimSlash(options.apiUrl??(options.baseUrl!==void 0?baseUrl:"https://api.github.com"));return upstream({id:"github",name:"GitHub",issuer:`${baseUrl}/login/oauth`,authorizationEndpoint:`${baseUrl}/login/oauth/authorize`,tokenEndpoint:`${baseUrl}/login/oauth/access_token`,clientId:options.clientId,clientSecret:options.clientSecret,scopes:[...options.scopes??["read:user"]],pkce:!0,fetchUser:async(tokens,fetch)=>{let response=await fetch(`${apiUrl}/user`,{headers:{authorization:`Bearer ${tokens.accessToken}`,accept:"application/vnd.github+json","user-agent":"mcp-use-oauth-proxy","x-github-api-version":"2022-11-28"},signal:AbortSignal.timeout(15e3)});if(!response.ok)throw new Error(`GitHub /user returned ${response.status}`);let user=await response.json();if(!isRecord(user)||typeof user.id!="number"&&typeof user.id!="string")throw new Error("GitHub /user returned no user id");return{subject:String(user.id),profile:pick(user,["id","login","name","email","avatar_url"])}}})}function google(options){let base=options.baseUrl===void 0?void 0:trimSlash(options.baseUrl),userinfo=base===void 0?"https://openidconnect.googleapis.com/v1/userinfo":`${base}/oauth2/v2/userinfo`,scopes=new Set(["openid",...options.scopes??["email","profile"]]);return upstream({id:"google",name:"Google",issuer:base??"https://accounts.google.com",authorizationEndpoint:base===void 0?"https://accounts.google.com/o/oauth2/v2/auth":`${base}/o/oauth2/v2/auth`,tokenEndpoint:base===void 0?"https://oauth2.googleapis.com/token":`${base}/oauth2/token`,clientId:options.clientId,clientSecret:options.clientSecret,scopes:[...scopes],pkce:!0,authorizeParams:{access_type:"offline",include_granted_scopes:"true"},retryWithoutRefreshToken:{prompt:"consent"},fetchUser:async(tokens,fetch)=>{let response=await fetch(userinfo,{headers:{authorization:`Bearer ${tokens.accessToken}`},signal:AbortSignal.timeout(15e3)});if(!response.ok)throw new Error(`Google userinfo returned ${response.status}`);let user=await response.json();if(!isRecord(user)||typeof user.sub!="string")throw new Error("Google userinfo returned no sub");return{subject:user.sub,profile:pick(user,["sub","email","email_verified","name","picture","hd"])}}})}function pick(source,keys2){let result={};for(let key of keys2)source[key]!==void 0&&(result[key]=source[key]);return result}function trimSlash(value){return value.replace(/\/+$/,"")}var LOOPBACK_BINDS=new Set(["127.0.0.1","localhost","::1"]);function oauthProxy(options){if(options===null||typeof options!="object")throw new TypeError("oauthProxy requires options");let upstream2=options.upstream;if(upstream2?.kind!=="redirect")throw new TypeError("oauthProxy upstream must be github(), google(), or upstream({...})");assertRedirectUpstream(upstream2);let configuredSecret=options.secret??oauthEnvironmentValue("MCP_USE_OAUTH_SECRET"),secrets=configuredSecret===void 0||configuredSecret===""?void 0:normalizeSecrets(configuredSecret);options.storage!==void 0&&assertStorage(options.storage);let consent=normalizeConsent(options.consent),clients=configuredClients(options.clients);if(options.dcr!==void 0&&typeof options.dcr!="boolean")throw new TypeError("oauthProxy dcr must be a boolean");if(options.dcr===!0&&clients.allow!==void 0)throw new TypeError("oauthProxy dcr cannot be on while clients is set: a registered client names itself, so it cannot be on the list");let dcr=options.dcr??clients.allow===void 0,cimd=clients.allow===void 0||clients.allow.urls.size>0||clients.allow.origins.size>0,accessTokenTtl=options.accessTokenTtl??3600;if(!Number.isInteger(accessTokenTtl)||accessTokenTtl<60||accessTokenTtl>720*60*60)throw new TypeError("oauthProxy accessTokenTtl must be an integer from 60 to 2592000 seconds");if(options.mapUser!==void 0&&typeof options.mapUser!="function")throw new TypeError("oauthProxy mapUser must be a function");if(options.fetch!==void 0&&typeof options.fetch!="function")throw new TypeError("oauthProxy fetch must be a function");let scopes=[...options.scopesSupported??options.requiredScopes??[]],fetchImpl=options.fetch??((input,init)=>globalThis.fetch(input,init)),mapUser=options.mapUser??(user=>user),runtime,runtimeFor=resource=>{if(runtime===void 0||runtime.config.resource.href!==resource.href)throw new Error("oauthProxy is not mounted: pass it as the oauth option of MCPServer");return runtime},setup=host=>{if(runtime!==void 0){if(runtime.config.resource.href!==host.resourceUrl.href)throw new Error("An oauthProxy provider can serve only one MCP resource");registerRoutes(host,runtime,dcr);return}let building=isBuilding(),localhost=isLocalhost(host.resourceUrl)&&(host.mode!=="listen"||LOOPBACK_BINDS.has(host.listenHost??"")),local=host.mode==="listen"&&localhost,storage=options.storage;if(storage===void 0){if(!local&&!building)throw new Error("oauthProxy needs storage outside a localhost listen() on 127.0.0.1, localhost, or ::1: pass a shared store from mcp-use/oauth/storage");storage=memoryStorage()}else if(isMemoryStorage(storage)&&!building&&!localhost)throw new Error("oauthProxy memoryStorage() works only on localhost, with listen() on 127.0.0.1, localhost, or ::1; use a shared store from mcp-use/oauth/storage");if(secrets===void 0&&!local&&!building)throw new Error("oauthProxy needs a secret outside a localhost listen() on 127.0.0.1, localhost, or ::1: set MCP_USE_OAUTH_SECRET or the secret option");if(consent===!1&&!localhost)throw new Error("oauthProxy consent: false is allowed only on localhost, with listen() on 127.0.0.1, localhost, or ::1");secrets===void 0&&!building&&console.warn("[mcp-use] oauthProxy: no secret set; using a random key for this process. Sign-ins end when the server restarts. Set MCP_USE_OAUTH_SECRET to keep them.");let keyring,loadKeyring=()=>(keyring??=secrets===void 0?randomKeyring():deriveKeyring(secrets),keyring),resource=new URL(host.resourceUrl.href),store=new SecureStore(storage,loadKeyring,resource);runtime=new ProxyRuntime({resource,basePath:host.basePath,store,keyring:loadKeyring,clients:{store,configured:clients.byId,allow:clients.allow,dcr,fetchCimd:createCimdFetcher(fetchImpl,options.fetch===void 0?defaultHostResolver:!1),upstreamClientId:upstream2.clientId},upstream:upstream2,fetch:fetchImpl,scopes,accessTokenTtl,consent,serverHost:host.resourceUrl.host}),registerRoutes(host,runtime,dcr)};return oauthCustomProvider({...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},oauthMetadata:resource=>ProxyRuntime.metadata(resource,resource.pathname,{dcr,cimd,scopes}),createTokenVerifier:resource=>({verifyAccessToken:token=>runtimeFor(resource).verifyAccessToken(token)}),mapAuthInfo:authInfo=>{let extra=authInfo.extra;return{user:mapUser(extra.upstreamUser),payload:{sub:extra.userKey,client_id:authInfo.clientId,scope:authInfo.scopes.join(" "),provider:upstream2.id,profile:extra.upstreamUser.profile},permissions:[]}},setup})}function normalizeConsent(consent){if(consent===!1)return!1;if(consent===void 0)return{mode:"always"};if(consent===null||typeof consent!="object")throw new TypeError("oauthProxy consent must be false or an object");let mode=consent.mode??"always";if(mode!=="always"&&mode!=="remember")throw new TypeError('oauthProxy consent.mode must be "always" or "remember"');if(consent.page!==void 0&&typeof consent.page!="function")throw new TypeError("oauthProxy consent.page must be a React component");return{mode,...consent.page!==void 0&&{page:consent.page}}}function registerRoutes(host,runtime,dcr){let guard=handler=>async c=>{try{return await handler(c)}catch(error){return console.error("[mcp-use] oauthProxy request failed:",describe(error)),c.header("cache-control","no-store"),c.json({error:"server_error",error_description:"The authorization server failed"},500)}},{paths}=runtime;host.route("GET",paths.authorize,guard(c=>runtime.authorize(c))),host.route("POST",paths.consent,guard(c=>runtime.consent(c))),host.route("GET",paths.callback,guard(c=>runtime.callback(c))),host.route("POST",paths.token,guard(c=>runtime.token(c))),host.route("OPTIONS",paths.token,c=>runtime.preflight(c)),host.route("POST",paths.revoke,guard(c=>runtime.revoke(c))),host.route("OPTIONS",paths.revoke,c=>runtime.preflight(c)),dcr&&(host.route("POST",paths.register,guard(c=>runtime.register(c))),host.route("OPTIONS",paths.register,c=>runtime.preflight(c)))}function upstreamToken(auth){let token=auth?.upstream?.accessToken;if(typeof token!="string")throw new Error("No upstream token: this request is not signed in through oauthProxy");return token}export{OAuthError,OAuthErrorCode,bearerAuth,bearerAuthChallengeResponse,createJwtVerifier,getOAuthProtectedResourceMetadataUrl2 as getOAuthProtectedResourceMetadataUrl,github,google,memoryStorage,oauthCustomProvider,oauthMetadata,oauthMetadataResponse2 as oauthMetadataResponse,oauthProxy,requireBearerAuth2 as requireBearerAuth,upstream,upstreamToken,verifyBearerToken};
|
|
53
|
+
caused by ${cause.name}: ${cause.message}${code}`,cause=cause.cause}return text}function signInFailure(upstreamName,error){if(!(error instanceof UpstreamError))return{error:"server_error",error_description:`${upstreamName} sign-in failed`};let reason=error.upstreamCode===void 0?"":` (${error.upstreamCode})`;return{error:error.code==="access_denied"?"access_denied":error.transient?"temporarily_unavailable":"server_error",error_description:errorDescription(`${upstreamName} sign-in failed${reason}${error.description===void 0?"":`: ${error.description}`}`)}}function errorDescription(text){let safe=text.replace(/"/g,"'").replace(/[^\x20-\x21\x23-\x5b\x5d-\x7e]/g,"");return safe.length>300?`${safe.slice(0,299)}.`:safe}function github(options){options.apiUrl!==void 0&&assertEndpoint(options.apiUrl,"github apiUrl");let baseUrl=trimTrailingSlashes(options.baseUrl??"https://github.com"),apiUrl=trimTrailingSlashes(options.apiUrl??(options.baseUrl!==void 0?baseUrl:"https://api.github.com"));return upstream({id:"github",name:"GitHub",issuer:`${baseUrl}/login/oauth`,authorizationEndpoint:`${baseUrl}/login/oauth/authorize`,tokenEndpoint:`${baseUrl}/login/oauth/access_token`,clientId:options.clientId,clientSecret:options.clientSecret,scopes:[...options.scopes??["read:user"]],pkce:!0,fetchUser:async(tokens,fetch)=>{let response=await fetch(`${apiUrl}/user`,{headers:{authorization:`Bearer ${tokens.accessToken}`,accept:"application/vnd.github+json","user-agent":"mcp-use-oauth-proxy","x-github-api-version":"2022-11-28"},signal:AbortSignal.timeout(15e3)});if(!response.ok)throw new Error(`GitHub /user returned ${response.status}`);let user=await response.json();if(!isRecord(user)||typeof user.id!="number"&&typeof user.id!="string")throw new Error("GitHub /user returned no user id");return{subject:String(user.id),profile:pick(user,["id","login","name","email","avatar_url"])}}})}function google(options){let base=options.baseUrl===void 0?void 0:trimTrailingSlashes(options.baseUrl),userinfo=base===void 0?"https://openidconnect.googleapis.com/v1/userinfo":`${base}/oauth2/v2/userinfo`,scopes=new Set(["openid",...options.scopes??["email","profile"]]);return upstream({id:"google",name:"Google",issuer:base??"https://accounts.google.com",authorizationEndpoint:base===void 0?"https://accounts.google.com/o/oauth2/v2/auth":`${base}/o/oauth2/v2/auth`,tokenEndpoint:base===void 0?"https://oauth2.googleapis.com/token":`${base}/oauth2/token`,clientId:options.clientId,clientSecret:options.clientSecret,scopes:[...scopes],pkce:!0,authorizeParams:{access_type:"offline",include_granted_scopes:"true"},retryWithoutRefreshToken:{prompt:"consent"},fetchUser:async(tokens,fetch)=>{let response=await fetch(userinfo,{headers:{authorization:`Bearer ${tokens.accessToken}`},signal:AbortSignal.timeout(15e3)});if(!response.ok)throw new Error(`Google userinfo returned ${response.status}`);let user=await response.json();if(!isRecord(user)||typeof user.sub!="string")throw new Error("Google userinfo returned no sub");return{subject:user.sub,profile:pick(user,["sub","email","email_verified","name","picture","hd"])}}})}function pick(source,keys2){let result={};for(let key of keys2)source[key]!==void 0&&(result[key]=source[key]);return result}var LOOPBACK_BINDS=new Set(["127.0.0.1","localhost","::1"]);function oauthProxy(options){if(options===null||typeof options!="object")throw new TypeError("oauthProxy requires options");let upstream2=options.upstream;if(upstream2?.kind!=="redirect")throw new TypeError("oauthProxy upstream must be github(), google(), or upstream({...})");assertRedirectUpstream(upstream2);let configuredSecret=options.secret??oauthEnvironmentValue("MCP_USE_OAUTH_SECRET"),secrets=configuredSecret===void 0||configuredSecret===""?void 0:normalizeSecrets(configuredSecret);options.storage!==void 0&&assertStorage(options.storage);let consent=normalizeConsent(options.consent),clients=configuredClients(options.clients);if(options.dcr!==void 0&&typeof options.dcr!="boolean")throw new TypeError("oauthProxy dcr must be a boolean");if(options.dcr===!0&&clients.allow!==void 0)throw new TypeError("oauthProxy dcr cannot be on while clients is set: a registered client names itself, so it cannot be on the list");let dcr=options.dcr??clients.allow===void 0,cimd=clients.allow===void 0||clients.allow.urls.size>0||clients.allow.origins.size>0,accessTokenTtl=options.accessTokenTtl??3600;if(!Number.isInteger(accessTokenTtl)||accessTokenTtl<60||accessTokenTtl>720*60*60)throw new TypeError("oauthProxy accessTokenTtl must be an integer from 60 to 2592000 seconds");if(options.mapUser!==void 0&&typeof options.mapUser!="function")throw new TypeError("oauthProxy mapUser must be a function");if(options.fetch!==void 0&&typeof options.fetch!="function")throw new TypeError("oauthProxy fetch must be a function");let scopes=[...options.scopesSupported??options.requiredScopes??[]],fetchImpl=options.fetch??((input,init)=>globalThis.fetch(input,init)),mapUser=options.mapUser??(user=>user),runtime,runtimeFor=resource=>{if(runtime===void 0||runtime.config.resource.href!==resource.href)throw new Error("oauthProxy is not mounted: pass it as the oauth option of MCPServer");return runtime},setup=host=>{if(runtime!==void 0){if(runtime.config.resource.href!==host.resourceUrl.href)throw new Error("An oauthProxy provider can serve only one MCP resource");registerRoutes(host,runtime,dcr);return}let building=isBuilding(),localhost=isLocalhost(host.resourceUrl)&&(host.mode!=="listen"||LOOPBACK_BINDS.has(host.listenHost??"")),local=host.mode==="listen"&&localhost,storage=options.storage;if(storage===void 0){if(!local&&!building)throw new Error("oauthProxy needs storage outside a localhost listen() on 127.0.0.1, localhost, or ::1: pass a shared store from mcp-use/oauth/storage");storage=memoryStorage()}else if(isMemoryStorage(storage)&&!building&&!localhost)throw new Error("oauthProxy memoryStorage() works only on localhost, with listen() on 127.0.0.1, localhost, or ::1; use a shared store from mcp-use/oauth/storage");if(secrets===void 0&&!local&&!building)throw new Error("oauthProxy needs a secret outside a localhost listen() on 127.0.0.1, localhost, or ::1: set MCP_USE_OAUTH_SECRET or the secret option");if(consent===!1&&!localhost)throw new Error("oauthProxy consent: false is allowed only on localhost, with listen() on 127.0.0.1, localhost, or ::1");secrets===void 0&&!building&&console.warn("[mcp-use] oauthProxy: no secret set; using a random key for this process. Sign-ins end when the server restarts. Set MCP_USE_OAUTH_SECRET to keep them.");let keyring,loadKeyring=()=>(keyring??=secrets===void 0?randomKeyring():deriveKeyring(secrets),keyring),resource=new URL(host.resourceUrl.href),store=new SecureStore(storage,loadKeyring,resource);runtime=new ProxyRuntime({resource,basePath:host.basePath,store,keyring:loadKeyring,clients:{store,configured:clients.byId,allow:clients.allow,dcr,fetchCimd:createCimdFetcher(fetchImpl,options.fetch===void 0?defaultHostResolver:!1),upstreamClientId:upstream2.clientId},upstream:upstream2,fetch:fetchImpl,scopes,accessTokenTtl,consent,serverHost:host.resourceUrl.host}),registerRoutes(host,runtime,dcr)};return oauthCustomProvider({...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},oauthMetadata:resource=>ProxyRuntime.metadata(resource,resource.pathname,{dcr,cimd,scopes}),createTokenVerifier:resource=>({verifyAccessToken:token=>runtimeFor(resource).verifyAccessToken(token)}),mapAuthInfo:authInfo=>{let extra=authInfo.extra;return{user:mapUser(extra.upstreamUser),payload:{sub:extra.userKey,client_id:authInfo.clientId,scope:authInfo.scopes.join(" "),provider:upstream2.id,profile:extra.upstreamUser.profile},permissions:[]}},setup})}function normalizeConsent(consent){if(consent===!1)return!1;if(consent===void 0)return{mode:"always"};if(consent===null||typeof consent!="object")throw new TypeError("oauthProxy consent must be false or an object");let mode=consent.mode??"always";if(mode!=="always"&&mode!=="remember")throw new TypeError('oauthProxy consent.mode must be "always" or "remember"');if(consent.page!==void 0&&typeof consent.page!="function")throw new TypeError("oauthProxy consent.page must be a React component");return{mode,...consent.page!==void 0&&{page:consent.page}}}function registerRoutes(host,runtime,dcr){let guard=handler=>async c=>{try{return await handler(c)}catch(error){return console.error("[mcp-use] oauthProxy request failed:",describe(error)),c.header("cache-control","no-store"),c.json({error:"server_error",error_description:"The authorization server failed"},500)}},{paths}=runtime;host.route("GET",paths.authorize,guard(c=>runtime.authorize(c))),host.route("POST",paths.consent,guard(c=>runtime.consent(c))),host.route("GET",paths.callback,guard(c=>runtime.callback(c))),host.route("POST",paths.token,guard(c=>runtime.token(c))),host.route("OPTIONS",paths.token,c=>runtime.preflight(c)),host.route("POST",paths.revoke,guard(c=>runtime.revoke(c))),host.route("OPTIONS",paths.revoke,c=>runtime.preflight(c)),dcr&&(host.route("POST",paths.register,guard(c=>runtime.register(c))),host.route("OPTIONS",paths.register,c=>runtime.preflight(c)))}function upstreamToken(auth){let token=auth?.upstream?.accessToken;if(typeof token!="string")throw new Error("No upstream token: this request is not signed in through oauthProxy");return token}export{OAuthError,OAuthErrorCode,bearerAuth,bearerAuthChallengeResponse,createJwtVerifier,getOAuthProtectedResourceMetadataUrl2 as getOAuthProtectedResourceMetadataUrl,github,google,memoryStorage,oauthCustomProvider,oauthMetadata,oauthMetadataResponse2 as oauthMetadataResponse,oauthProxy,requireBearerAuth2 as requireBearerAuth,upstream,upstreamToken,verifyBearerToken};
|
package/dist/oauth/keycloak.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,recordValue,requiredString,stringValue}from"../chunk-
|
|
1
|
+
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,recordValue,requiredString,stringValue}from"../chunk-4ICJVJOI.js";import{isRecord}from"../chunk-JX52OYMQ.js";function oauthKeycloakProvider(options={}){let serverUrlValue=options.serverUrl??oauthEnvironmentValue("MCP_USE_OAUTH_KEYCLOAK_SERVER_URL"),realm=options.realm??oauthEnvironmentValue("MCP_USE_OAUTH_KEYCLOAK_REALM"),audience=oauthEnvironmentValue("MCP_USE_OAUTH_KEYCLOAK_AUDIENCE");if(serverUrlValue===void 0||realm===void 0)throw new Error("Keycloak serverUrl and realm are required.");if(typeof realm!="string"||realm.trim().length===0||/[/?#]/.test(realm))throw new TypeError("Keycloak realm is invalid");let resolvedOptions={...options,...options.resource===void 0&&audience!==void 0&&{resource:audience}},serverUrl=normalizedProviderUrl(serverUrlValue,"Keycloak serverUrl"),issuer=providerEndpoint(serverUrl,`realms/${encodeURIComponent(realm)}`).replace(/\/$/,"");return oauthCustomProvider({...resolvedOptions,createTokenVerifier:resource=>createJwtVerifier({issuer,jwksUrl:new URL(providerEndpoint(issuer,"protocol/openid-connect/certs")),resource}),oauthMetadata:{issuer,authorization_endpoint:providerEndpoint(issuer,"protocol/openid-connect/auth"),token_endpoint:providerEndpoint(issuer,"protocol/openid-connect/token"),registration_endpoint:providerEndpoint(issuer,"clients-registrations/openid-connect"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"]},mapAuthInfo:mapUser})}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub");if(id===void 0)throw invalidToken("Missing Keycloak subject");let realmAccess=recordValue(payload,"realm_access"),resourceAccess=recordValue(payload,"resource_access");return{user:{id,...optional("email",stringValue(payload,"email")),...optional("name",stringValue(payload,"name")),...optional("preferredUsername",stringValue(payload,"preferred_username")),...optional("givenName",stringValue(payload,"given_name")),...optional("familyName",stringValue(payload,"family_name")),...optional("emailVerified",booleanValue(payload,"email_verified")),roles:realmAccess===void 0?[]:normalizedStrings(realmAccess.roles),...realmAccess!==void 0&&{realmAccess},...resourceAccess!==void 0&&{resourceAccess}},payload,permissions:resourcePermissions(resourceAccess)}}function optional(key,value){return value===void 0?{}:{[key]:value}}function resourcePermissions(resourceAccess){return resourceAccess===void 0?[]:Object.entries(resourceAccess).flatMap(([resource,value])=>isRecord(value)?normalizedStrings(value.roles).map(role=>`${resource}:${role}`):[])}export{oauthKeycloakProvider};
|
package/dist/oauth/scalekit.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString}from"../chunk-
|
|
1
|
+
import{createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString}from"../chunk-4ICJVJOI.js";import"../chunk-JX52OYMQ.js";function oauthScalekitProvider(options={}){if(options.audience!==void 0&&(typeof options.audience!="string"||options.audience.trim().length===0))throw new TypeError("audience must be a non-empty string");let environmentUrl=options.environmentUrl??oauthEnvironmentValue("MCP_USE_OAUTH_SCALEKIT_ENVIRONMENT_URL");if(environmentUrl===void 0)throw new Error("Scalekit environmentUrl is required.");let environmentIssuer=normalizedProviderUrl(environmentUrl,"environmentUrl").href.replace(/\/$/,""),resourceId=normalizeResourceId(options.resourceId??oauthEnvironmentValue("MCP_USE_OAUTH_SCALEKIT_RESOURCE_ID")),resourceIssuer=`${environmentIssuer}/resources/${resourceId}`,extraAudience=options.audience?.trim();return oauthCustomProvider({...options,createTokenVerifier:resource=>{let verifier=createJwtVerifier({issuer:[environmentIssuer,resourceIssuer],jwksUrl:new URL(providerEndpoint(environmentIssuer,"keys")),resource,audience:resourceId});return extraAudience===void 0?verifier:{async verifyAccessToken(token){let authInfo=await verifier.verifyAccessToken(token);return assertAudienceIncludes(payloadFromAuthInfo(authInfo),extraAudience),authInfo}}},oauthMetadata:metadata(environmentIssuer,resourceId,resourceIssuer),mapAuthInfo:mapUser})}function assertAudienceIncludes(payload,expected){let aud=payload.aud;if(!(typeof aud=="string"?[aud]:Array.isArray(aud)?aud:[]).includes(expected))throw invalidToken("Token audience does not include configured audience")}function normalizeResourceId(value){if(value===void 0)throw new Error("Scalekit resourceId is required.");if(typeof value!="string"||value.trim().length===0)throw new TypeError("resourceId is required. Copy the res_\u2026 id from Scalekit \u2192 MCP servers. It is the JWT audience.");let resourceId=value.trim();if(!resourceId.startsWith("res_"))throw new TypeError(`resourceId must start with "res_" (${resourceId}). A wrong value weakens audience binding.`);return resourceId}function metadata(environmentIssuer,resourceId,resourceIssuer){return{issuer:resourceIssuer,authorization_endpoint:providerEndpoint(resourceIssuer,"oauth/authorize"),token_endpoint:providerEndpoint(resourceIssuer,"oauth/token"),jwks_uri:providerEndpoint(environmentIssuer,"keys"),registration_endpoint:`${environmentIssuer}/api/v1/resources/${resourceId}/clients:register`,response_types_supported:["code"],grant_types_supported:["authorization_code","client_credentials","refresh_token"],code_challenge_methods_supported:["S256"],token_endpoint_auth_methods_supported:["none","client_secret_post","client_secret_basic"],client_id_metadata_document_supported:!0}}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub");if(id===void 0)throw invalidToken("Missing Scalekit subject");let clientId=requiredString(payload,"client_id")??requiredString(payload,"azp");return{user:{id,subjectType:clientId!==void 0&&id===clientId?"machine":"user",...optional("organizationId",requiredString(payload,"org_id")),...optional("sessionId",requiredString(payload,"sid"))},payload,permissions:normalizedStrings(payload.permissions)}}function optional(key,value){return value===void 0?{}:{[key]:value}}export{oauthScalekitProvider};
|
package/dist/oauth/storage.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isBuilding,memoryStorage}from"../chunk-
|
|
1
|
+
import{isBuilding,memoryStorage}from"../chunk-3XIIMBWV.js";import{isRecord,trimTrailingSlashes}from"../chunk-JX52OYMQ.js";function upstashStorage(options){if((typeof options?.url!="string"||typeof options.token!="string")&&!isBuilding())throw new TypeError("upstashStorage requires url and token");let url=trimTrailingSlashes(String(options?.url)),fetchImpl=options.fetch??((input,init)=>globalThis.fetch(input,init));return redisCommandStorage(async args=>{let response=await fetchImpl(url,{method:"POST",headers:{authorization:`Bearer ${options.token}`,"content-type":"application/json"},body:JSON.stringify(args.map(String))}),body=await response.json().catch(()=>({}));if(!response.ok||body.error!==void 0)throw new Error(`Upstash ${String(args[0])} failed: ${body.error??response.status}`);return body.result})}function redisStorage(client){if(typeof client!="function"){let command=redisCommand(client);return redisCommandStorage(command)}let connecting,connect=()=>(connecting??=Promise.resolve().then(client).then(redisCommand).catch(error=>{throw connecting=void 0,error}),connecting);return redisCommandStorage(async args=>(await connect())(args))}function redisCommand(client){if(client!==null&&typeof client=="object"){if(typeof client.sendCommand=="function"){let redis=client;return args=>redis.sendCommand(args.map(String))}if(typeof client.call=="function"){let redis=client;return([name,...args])=>redis.call(String(name),...args.map(String))}}throw new TypeError("redisStorage requires a node-redis or ioredis client")}function redisCommandStorage(command){let asString=value=>typeof value=="string"?value:value instanceof Uint8Array?new TextDecoder().decode(value):void 0;return{get:async key=>asString(await command(["GET",key])),set:async(key,value,ttlSeconds)=>{await command(["SET",key,value,"EX",ttlSeconds])},delete:async key=>{await command(["DEL",key])},take:async key=>asString(await command(["GETDEL",key])),add:async(key,value,ttlSeconds)=>await command(["SET",key,value,"NX","EX",ttlSeconds])!==null}}function postgresStorage(options){let client=options?.client;if(client===null||typeof client?.query!="function")throw new TypeError("postgresStorage requires a client with query()");let table=sqlIdentifier(options.table??"mcp_use_oauth"),ready,query=async(text,values)=>(ready??=client.query(`CREATE TABLE IF NOT EXISTS ${table} (key text PRIMARY KEY, value text NOT NULL, expires_at timestamptz NOT NULL)`).catch(error=>{throw ready=void 0,error}),await ready,client.query(text,values)),sweep=()=>{Math.random()<.01&&query(`DELETE FROM ${table} WHERE expires_at <= now()`,[]).catch(()=>{})},upsert=`INSERT INTO ${table} (key, value, expires_at) VALUES ($1, $2, now() + make_interval(secs => $3)) ON CONFLICT (key) DO UPDATE SET value = excluded.value, expires_at = excluded.expires_at`;return{get:async key=>{let{rows}=await query(`SELECT value FROM ${table} WHERE key = $1 AND expires_at > now()`,[key]);return stringColumn(rows[0],"value")},set:async(key,value,ttlSeconds)=>{await query(upsert,[key,value,ttlSeconds]),sweep()},delete:async key=>{await query(`DELETE FROM ${table} WHERE key = $1`,[key])},take:async key=>{let{rows}=await query(`DELETE FROM ${table} WHERE key = $1 RETURNING value, expires_at > now() AS live`,[key]);return rows[0]?.live===!0?stringColumn(rows[0],"value"):void 0},add:async(key,value,ttlSeconds)=>{let{rows}=await query(`${upsert} WHERE ${table}.expires_at <= now() RETURNING key`,[key,value,ttlSeconds]);return sweep(),rows.length>0}}}function firestoreStorage(options){let firestore=options?.firestore;if(firestore===null||typeof firestore?.collection!="function"||typeof firestore.runTransaction!="function")throw new TypeError("firestoreStorage requires a Firestore database from firebase-admin or @google-cloud/firestore");let name=options.collection??"mcp_use_oauth";if(typeof name!="string"||!/^[^/]{1,1500}$/.test(name)||/^__.*__$/.test(name)||name==="."||name==="..")throw new TypeError("firestoreStorage collection must be a collection ID without slashes");let collection=firestore.collection(name),document=key=>collection.doc(encodeURIComponent(key)),live=snapshot=>{if(!snapshot.exists)return;let data=snapshot.data(),value=data?.value;return typeof value=="string"&&expiresAtMillis(data)>Date.now()?value:void 0},record=(value,ttlSeconds)=>({value,expiresAt:new Date(Date.now()+ttlSeconds*1e3)});return{get:async key=>live(await document(key).get()),set:async(key,value,ttlSeconds)=>{await document(key).set(record(value,ttlSeconds))},delete:async key=>{await document(key).delete()},take:key=>firestore.runTransaction(async transaction=>{let reference=document(key),snapshot=await transaction.get(reference);return snapshot.exists&&transaction.delete(reference),live(snapshot)}),add:(key,value,ttlSeconds)=>firestore.runTransaction(async transaction=>{let reference=document(key);return live(await transaction.get(reference))!==void 0?!1:(transaction.set(reference,record(value,ttlSeconds)),!0)})}}function expiresAtMillis(data){let expiresAt=data?.expiresAt;if(expiresAt instanceof Date)return expiresAt.getTime();if(isRecord(expiresAt)&&typeof expiresAt.toMillis=="function"){let millis=expiresAt.toMillis.call(expiresAt);return typeof millis=="number"?millis:0}return 0}function cloudflareStorage(options){if(options!==null&&typeof options=="object"&&"d1"in options)return d1Storage(options.d1,sqlIdentifier(options.table??"mcp_use_oauth"));if(options!==null&&typeof options=="object"&&"durableObject"in options){let namespace=options.durableObject,stub=namespace.get(namespace.idFromName("mcp-use-oauth")),call=async body=>{let response=await stub.fetch("https://oauth-storage/",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(body)});if(!response.ok)throw new Error(`OAuth storage Durable Object returned ${response.status}`);return(await response.json()).result};return{get:async key=>await call({op:"get",key}),set:async(key,value,ttlSeconds)=>{await call({op:"set",key,value,ttl:ttlSeconds})},delete:async key=>{await call({op:"delete",key})},take:async key=>await call({op:"take",key}),add:async(key,value,ttlSeconds)=>await call({op:"add",key,value,ttl:ttlSeconds})===!0}}throw new TypeError("cloudflareStorage requires a d1 or durableObject binding")}function d1Storage(db,table){if(db===null||typeof db?.prepare!="function")throw new TypeError("cloudflareStorage d1 must be a D1 database binding");let ready,statement=async(query,...values)=>(ready??=db.prepare(`CREATE TABLE IF NOT EXISTS ${table} (key TEXT PRIMARY KEY, value TEXT NOT NULL, expires_at INTEGER NOT NULL)`).bind().run().catch(error=>{throw ready=void 0,error}),await ready,db.prepare(query).bind(...values)),now=()=>Date.now(),upsert=`INSERT INTO ${table} (key, value, expires_at) VALUES (?1, ?2, ?3) ON CONFLICT (key) DO UPDATE SET value = excluded.value, expires_at = excluded.expires_at`,sweep=()=>{Math.random()<.01&&statement(`DELETE FROM ${table} WHERE expires_at <= ?1`,now()).then(query=>query.run()).catch(()=>{})};return{get:async key=>stringColumn(await(await statement(`SELECT value FROM ${table} WHERE key = ?1 AND expires_at > ?2`,key,now())).first(),"value"),set:async(key,value,ttlSeconds)=>{await(await statement(upsert,key,value,now()+ttlSeconds*1e3)).run(),sweep()},delete:async key=>{await(await statement(`DELETE FROM ${table} WHERE key = ?1`,key)).run()},take:async key=>{let row=await(await statement(`DELETE FROM ${table} WHERE key = ?1 RETURNING value, expires_at`,key)).first();return row!==null&&Number(row.expires_at)>now()?stringColumn(row,"value"):void 0},add:async(key,value,ttlSeconds)=>{let row=await(await statement(`${upsert} WHERE ${table}.expires_at <= ?4 RETURNING key`,key,value,now()+ttlSeconds*1e3,now())).first();return sweep(),row!==null}}}var SWEEP_CURSOR_KEY="mcp-use-sweep-cursor",OAuthProxyDurableObject=class{#storage;#writes=0;constructor(state,_env){this.#storage=state.storage}async fetch(request){let body=await request.json();if(typeof body.key!="string")return new Response("key required",{status:400});let key=body.key,read=async()=>{let entry=await this.#storage.get(key);if(entry!==void 0){if(entry.expiresAt<=Date.now()){await this.#storage.delete(key);return}return entry.value}},write=async()=>{await this.#storage.put(key,{value:String(body.value),expiresAt:Date.now()+Number(body.ttl)*1e3}),++this.#writes%200===0&&await this.#sweep()},result;switch(body.op){case"get":result=await read();break;case"set":await write();break;case"delete":await this.#storage.delete(key);break;case"take":result=await read(),await this.#storage.delete(key);break;case"add":result=await read()===void 0,result===!0&&await write();break;default:return new Response("unknown op",{status:400})}return Response.json({result})}async#sweep(){let cursor=await this.#storage.get(SWEEP_CURSOR_KEY),entries=await this.#storage.list({limit:1e3,...cursor!==void 0&&{startAfter:cursor}}),now=Date.now(),last;for(let[key,entry]of entries)last=key,key!==SWEEP_CURSOR_KEY&&entry.expiresAt<=now&&await this.#storage.delete(key);entries.size<1e3||last===void 0?await this.#storage.delete(SWEEP_CURSOR_KEY):await this.#storage.put(SWEEP_CURSOR_KEY,last)}};function sqlIdentifier(name){if(!/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(name))throw new TypeError("OAuth storage table name must be a plain SQL identifier");return name}function stringColumn(row,column){let value=row?.[column];return typeof value=="string"?value:void 0}export{OAuthProxyDurableObject,cloudflareStorage,firestoreStorage,memoryStorage,postgresStorage,redisStorage,upstashStorage};
|
package/dist/oauth/supabase.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createJwtVerifier,invalidToken,normalizedProviderUrl,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,recordValue,requiredString,stringValue}from"../chunk-
|
|
1
|
+
import{createJwtVerifier,invalidToken,normalizedProviderUrl,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,recordValue,requiredString,stringValue}from"../chunk-4ICJVJOI.js";import{isRecord}from"../chunk-JX52OYMQ.js";function oauthSupabaseProvider(options={}){let projectId=options.projectId??oauthEnvironmentValue("MCP_USE_OAUTH_SUPABASE_PROJECT_ID"),configuredSupabaseUrl=options.supabaseUrl??oauthEnvironmentValue("MCP_USE_OAUTH_SUPABASE_URL"),jwtSecret=options.jwtSecret??oauthEnvironmentValue("MCP_USE_OAUTH_SUPABASE_JWT_SECRET"),resolvedOptions={...options,...projectId!==void 0&&{projectId},...configuredSupabaseUrl!==void 0&&{supabaseUrl:configuredSupabaseUrl},...jwtSecret!==void 0&&{jwtSecret}},supabaseUrl=resolveSupabaseUrl(resolvedOptions),issuer=providerEndpoint(supabaseUrl,"auth/v1").replace(/\/$/,""),secret=resolvedOptions.jwtSecret,audience=resolvedOptions.audience??"authenticated";if(typeof audience!="string"||audience.trim().length===0)throw new TypeError("Supabase audience must be non-empty");if(secret!==void 0&&new TextEncoder().encode(secret).length<32)throw new TypeError("Supabase jwtSecret must be at least 32 bytes");return oauthCustomProvider({...resolvedOptions,createTokenVerifier:resource=>createJwtVerifier({issuer,jwksUrl:new URL(providerEndpoint(supabaseUrl,"auth/v1/.well-known/jwks.json")),...secret!==void 0?{key:new TextEncoder().encode(secret),algorithms:["HS256"]}:{algorithms:["ES256"]},resource,audience}),oauthMetadata:{issuer,authorization_endpoint:providerEndpoint(supabaseUrl,"auth/v1/oauth/authorize"),token_endpoint:providerEndpoint(supabaseUrl,"auth/v1/oauth/token"),registration_endpoint:providerEndpoint(supabaseUrl,"auth/v1/oauth/clients/register"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"]},mapAuthInfo:mapUser})}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub")??requiredString(payload,"user_id");if(id===void 0)throw invalidToken("Missing Supabase subject");let userMetadata=recordValue(payload,"user_metadata")??{},aal=stringValue(payload,"aal");return{user:{id,...optional("email",stringValue(payload,"email")),...optional("name",stringValue(userMetadata,"name")),...optional("fullName",stringValue(userMetadata,"full_name")),...optional("username",stringValue(userMetadata,"username")),...optional("avatarUrl",stringValue(userMetadata,"avatar_url")),...optional("role",stringValue(payload,"role")),...optional("aal",aal),amr:supabaseAmr(payload.amr),...optional("sessionId",stringValue(payload,"session_id"))},payload,permissions:aal===void 0?[]:[`aal:${aal}`]}}function optional(key,value){return value===void 0?{}:{[key]:value}}function resolveSupabaseUrl(options){if(options.supabaseUrl!==void 0)return normalizedProviderUrl(options.supabaseUrl,"supabaseUrl");if(options.projectId===void 0||!/^[a-z0-9-]+$/i.test(options.projectId))throw new TypeError("Supabase requires projectId or supabaseUrl");return new URL(`https://${options.projectId}.supabase.co`)}function supabaseAmr(value){return Array.isArray(value)?value.flatMap(item=>{if(!isRecord(item))return[];let method=item.method,timestamp=item.timestamp;return typeof method!="string"||method.length===0?[]:timestamp!==void 0&&(typeof timestamp!="number"||!Number.isFinite(timestamp))?[]:[timestamp===void 0?{method}:{method,timestamp}]}):[]}export{oauthSupabaseProvider};
|
package/dist/oauth/workos.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-
|
|
1
|
+
import{booleanValue,createJwtVerifier,invalidToken,normalizedProviderUrl,normalizedStrings,oauthCustomProvider,oauthEnvironmentValue,payloadFromAuthInfo,providerEndpoint,requiredString,stringValue}from"../chunk-4ICJVJOI.js";import"../chunk-JX52OYMQ.js";function oauthWorkOSProvider(options={}){let subdomain=options.subdomain??oauthEnvironmentValue("MCP_USE_OAUTH_WORKOS_SUBDOMAIN");if(subdomain===void 0)throw new Error("WorkOS subdomain is required.");let issuer=workosIssuer(subdomain);return oauthCustomProvider({...options,createTokenVerifier:resource=>createJwtVerifier({issuer,jwksUrl:new URL(providerEndpoint(issuer,"oauth2/jwks")),resource}),oauthMetadata:{issuer,authorization_endpoint:providerEndpoint(issuer,"oauth2/authorize"),token_endpoint:providerEndpoint(issuer,"oauth2/token"),registration_endpoint:providerEndpoint(issuer,"oauth2/register"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"]},mapAuthInfo:mapUser})}function mapUser(authInfo){let payload=payloadFromAuthInfo(authInfo),id=requiredString(payload,"sub");if(id===void 0)throw invalidToken("Missing WorkOS subject");return{user:{id,...optional("email",stringValue(payload,"email")),...optional("emailVerified",booleanValue(payload,"email_verified")),...optional("name",stringValue(payload,"name")),...optional("preferredUsername",stringValue(payload,"preferred_username")),...optional("firstName",stringValue(payload,"first_name")),...optional("lastName",stringValue(payload,"last_name")),...optional("picture",stringValue(payload,"picture")),roles:normalizedStrings(payload.roles),...optional("organizationId",stringValue(payload,"org_id")),...optional("sessionId",stringValue(payload,"sid"))},payload,permissions:normalizedStrings(payload.permissions)}}function optional(key,value){return value===void 0?{}:{[key]:value}}function workosIssuer(value){if(typeof value!="string"||value.trim().length===0)throw new TypeError("WorkOS subdomain is required");let url=normalizedProviderUrl(value,"WorkOS subdomain");if(url.pathname!=="/")throw new TypeError("WorkOS subdomain must be a hostname or HTTPS origin");return url.href.replace(/\/$/,"")}export{oauthWorkOSProvider};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-use",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.10.0
|
|
4
|
+
"version": "2.10.0",
|
|
5
5
|
"description": "MCP framework and CLI built on the official v2 SDK",
|
|
6
6
|
"author": "mcp-use, Inc.",
|
|
7
7
|
"license": "MIT",
|
|
@@ -137,11 +137,11 @@
|
|
|
137
137
|
"hono": "^4.13.7",
|
|
138
138
|
"jose": "^6.1.3",
|
|
139
139
|
"oauth4webapi": "^3.8.8",
|
|
140
|
-
"@mcp-use/
|
|
141
|
-
"@mcp-use/
|
|
140
|
+
"@mcp-use/cli": "4.4.0",
|
|
141
|
+
"@mcp-use/inspector": "20.3.20"
|
|
142
142
|
},
|
|
143
143
|
"peerDependencies": {
|
|
144
|
-
"@mcp-use/client": "^2.0.1 || ^2.1.0 || ^2.1.1 || ^2.1.2 || ^2.1.3 || ^2.1.4 || ^2.1.5 || ^2.2.0 || ^2.2.1 || ^2.2.2 || ^2.2.3 || ^2.2.4 || ^2.2.5 || ^2.3.0 || ^2.3.1 || ^2.3.2 || ^2.3.3 || ^2.3.4 || ^2.3.5 || ^2.4.0 || ^2.4.1 || ^2.4.2",
|
|
144
|
+
"@mcp-use/client": "^2.0.1 || ^2.1.0 || ^2.1.1 || ^2.1.2 || ^2.1.3 || ^2.1.4 || ^2.1.5 || ^2.2.0 || ^2.2.1 || ^2.2.2 || ^2.2.3 || ^2.2.4 || ^2.2.5 || ^2.3.0 || ^2.3.1 || ^2.3.2 || ^2.3.3 || ^2.3.4 || ^2.3.5 || ^2.4.0 || ^2.4.1 || ^2.4.2 || ^2.4.3",
|
|
145
145
|
"react": "^19.0.0",
|
|
146
146
|
"react-dom": "^19.0.0",
|
|
147
147
|
"vite": "^8.0.0"
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
"vitest": "^4.1.11",
|
|
175
175
|
"zod": "^4.4.3",
|
|
176
176
|
"vite": "8.0.16",
|
|
177
|
-
"@mcp-use/client": "2.4.
|
|
177
|
+
"@mcp-use/client": "2.4.3"
|
|
178
178
|
},
|
|
179
179
|
"publishConfig": {
|
|
180
180
|
"access": "public"
|
package/dist/chunk-4VRUHDIY.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
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`)}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")}export{isRecord,isLocalhost,parseAbsoluteUrl,assertSecureHttpUrl,assertOAuthMetadata};
|