( execMsg: ExecServerMessage, mcpTools: McpToolDefinition[], sendFrame: (data: Uint8Array) => void, onMcpExec: (exec: PendingExec) => void, )
| 935 | } |
| 936 | |
| 937 | function handleExecMessage( |
| 938 | execMsg: ExecServerMessage, |
| 939 | mcpTools: McpToolDefinition[], |
| 940 | sendFrame: (data: Uint8Array) => void, |
| 941 | onMcpExec: (exec: PendingExec) => void, |
| 942 | ): void { |
| 943 | const execCase = execMsg.message.case; |
| 944 | |
| 945 | if (execCase === "requestContextArgs") { |
| 946 | const requestContext = create(RequestContextSchema, { |
| 947 | rules: [], |
| 948 | repositoryInfo: [], |
| 949 | tools: mcpTools, |
| 950 | gitRepos: [], |
| 951 | projectLayouts: [], |
| 952 | mcpInstructions: [], |
| 953 | fileContents: {}, |
| 954 | customSubagents: [], |
| 955 | }); |
| 956 | const result = create(RequestContextResultSchema, { |
| 957 | result: { |
| 958 | case: "success", |
| 959 | value: create(RequestContextSuccessSchema, { requestContext }), |
| 960 | }, |
| 961 | }); |
| 962 | sendExecResult(execMsg, "requestContextResult", result, sendFrame); |
| 963 | return; |
| 964 | } |
| 965 | |
| 966 | if (execCase === "mcpArgs") { |
| 967 | const mcpArgs = execMsg.message.value; |
| 968 | const decoded = decodeMcpArgsMap(mcpArgs.args ?? {}); |
| 969 | onMcpExec({ |
| 970 | execId: execMsg.execId, |
| 971 | execMsgId: execMsg.id, |
| 972 | toolCallId: mcpArgs.toolCallId || crypto.randomUUID(), |
| 973 | toolName: mcpArgs.toolName || mcpArgs.name, |
| 974 | decodedArgs: JSON.stringify(decoded), |
| 975 | }); |
| 976 | return; |
| 977 | } |
| 978 | |
| 979 | // --- Reject native Cursor tools --- |
| 980 | // The model tries these first. We must respond with rejection/error |
| 981 | // so it falls back to our MCP tools (registered via RequestContext). |
| 982 | const REJECT_REASON = "Tool not available in this environment. Use the MCP tools provided instead."; |
| 983 | |
| 984 | if (execCase === "readArgs") { |
| 985 | const args = execMsg.message.value; |
| 986 | const result = create(ReadResultSchema, { |
| 987 | result: { case: "rejected", value: create(ReadRejectedSchema, { path: args.path, reason: REJECT_REASON }) }, |
| 988 | }); |
| 989 | sendExecResult(execMsg, "readResult", result, sendFrame); |
| 990 | return; |
| 991 | } |
| 992 | if (execCase === "lsArgs") { |
| 993 | const args = execMsg.message.value; |
| 994 | const result = create(LsResultSchema, { |
no test coverage detected