UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

1 lines • 4.94 kB
import{createLogger,logError}from"#internal/logging.js";import{McpServer,createMcpHandler}from"#compiled/@modelcontextprotocol/server/index.js";const log=createLogger(`mcp.server`),MCP_PROTOCOL_VERSION=`2026-07-28`,MCP_LEGACY_PROTOCOL_VERSION=`2025-11-25`,MCP_REQUEST_BODY_MAX_BYTES=1048576;var McpToolOperationError=class extends Error{code;constructor(e,t){super(t),this.name=`McpToolOperationError`,this.code=e}};const RETRYABLE_CODES=new Set([`conflict`]);function defineMcpTool(e){return{name:e.definition.name,register(t,n){t.registerTool(e.definition.name,{...e.definition.annotations===void 0?{}:{annotations:e.definition.annotations},...e.definition.description===void 0?{}:{description:e.definition.description},inputSchema:e.definition.inputSchema,...e.definition.outputSchema===void 0?{}:{outputSchema:e.definition.outputSchema}},async(t,r)=>await callTool(e.call,t,r.mcpReq.signal,n))}}}function createMcpStreamableHttpServer(e){let t=new Map(e.tools.map(e=>[e.name,e]));if(t.size!==e.tools.length)throw Error(`MCP tool names must be unique.`);return async n=>{let r=await e.authenticate(n);if(r instanceof Response)return r;let i=createMcpHandler(()=>createServer(e,t,r),{legacy:`stateless`});if(n.method.toUpperCase()!==`POST`)return await i.fetch(n);let a=await inspectRequestBody(n);if(a.tooLarge)return requestBodyTooLargeResponse();if(a.invalidJson)return invalidJsonResponse();let o=a.value;if(o===void 0)return await i.fetch(n);let s=await preflightModernRequest(n,o);return s===void 0?await i.fetch(n,{parsedBody:o}):s}}async function preflightModernRequest(e,t){return e.headers.has(`mcp-protocol-version`)||!claimsCurrentProtocolVersion(t)?void 0:await probeEarlierValidationFailure(e,t)??headerMismatchResponse(t)}async function inspectRequestBody(e){let t=e.body;if(t===null)return{tooLarge:!1};let n=Number(e.headers.get(`content-length`));if(Number.isFinite(n)&&n>1048576)return await t.cancel().catch(()=>{}),{tooLarge:!0};let r=t.getReader(),i=[],a=0;try{for(;;){let e=await r.read();if(e.done)break;if(a+=e.value.byteLength,a>1048576)return await r.cancel(),{tooLarge:!0};i.push(e.value)}let e=new Uint8Array(a),t=0;for(let n of i)e.set(n,t),t+=n.byteLength;return{tooLarge:!1,value:JSON.parse(new TextDecoder().decode(e))}}catch{return{invalidJson:!0,tooLarge:!1}}}function invalidJsonResponse(){return Response.json({error:{code:-32700,message:`Parse error`},id:null,jsonrpc:`2.0`},{status:400})}function requestBodyTooLargeResponse(){return Response.json({error:{code:-32e3,message:`Request body too large`},id:null,jsonrpc:`2.0`},{status:413,statusText:`Request Entity Too Large`})}function claimsCurrentProtocolVersion(e){return isPlainRecord(e)&&isPlainRecord(e.params)&&isPlainRecord(e.params._meta)&&e.params._meta[`io.modelcontextprotocol/protocolVersion`]===`2026-07-28`}function isPlainRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function probeEarlierValidationFailure(e,t){let n=new Headers(e.headers);n.set(`mcp-protocol-version`,MCP_PROTOCOL_VERSION);let r=new Request(e.url,{body:JSON.stringify(t),headers:n,method:e.method}),i=createMcpHandler(()=>new McpServer({name:`eve-mcp-preflight`,version:`0`}),{legacy:`reject`});try{let e=await i.fetch(r,{parsedBody:t});if(e.status===406||e.status===415)return e;if(e.status===400){let t=await e.clone().json().catch(()=>void 0);if(t?.error?.code===-32700||t?.error?.code===-32600||t?.error?.code===-32602||t?.error?.code===-32022)return e}await e.body?.cancel();return}finally{await i.close().catch(()=>{})}}function headerMismatchResponse(e){let t=`the body carries a modern MCP envelope but the required MCP-Protocol-Version header is absent`;return Response.json({error:{code:-32020,data:{mismatch:{body:t,header:`(missing)`}},message:`Bad Request: the request headers and body disagree: ${t}`},id:readJsonRpcRequestId(e),jsonrpc:`2.0`},{status:400})}function readJsonRpcRequestId(e){if(typeof e!=`object`||!e||Array.isArray(e))return null;let t=Reflect.get(e,`id`);return typeof t==`string`||typeof t==`number`?t:null}function createServer(e,t,n){let r={capabilities:{tools:{listChanged:!1}}};e.instructions!==void 0&&(r.instructions=e.instructions);let i=new McpServer({name:e.name,version:e.version},r);for(let e of t.values())e.register(i,n);return i}async function callTool(e,t,n,r){try{return await e(t,{auth:r,signal:n})}catch(e){return e instanceof McpToolOperationError?toolError({code:e.code,message:e.message,retryable:RETRYABLE_CODES.has(e.code)}):toolError({code:`internal`,errorId:logError(log,`MCP tool call failed`,e),message:`The server could not complete this tool call.`,retryable:!1})}}function toolError(e){return{content:[{type:`text`,text:e.errorId===void 0?e.message:`${e.message} (errorId: ${e.errorId})`}],isError:!0,structuredContent:{error:e}}}export{MCP_LEGACY_PROTOCOL_VERSION,MCP_PROTOCOL_VERSION,MCP_REQUEST_BODY_MAX_BYTES,McpToolOperationError,createMcpStreamableHttpServer,defineMcpTool};