返回 CodeWhale
mcp.ts
根目录 / crates / tui / extension-host / src / dsh / mcp.ts
1 /** Raw DSH MCP rows submit definitions to the existing Rust MCP owner. */
2 import type { Context } from '@deepseek-ai/cordis'
3 import { normalizeMcp, type McpDefinition } from '../shims/mcp.ts'
4 export interface ReviewedMcpContext extends Context { mcp:{registerServer(definition:McpDefinition):()=>void} }
5 export function reviewedMcpModule() {
6 return { name:'codewhale-reviewed-mcp',inject:['mcp'],
7 apply(ctx:ReviewedMcpContext,config:Record<string,unknown>) {
8 if(!config||Array.isArray(config)||Object.keys(config).some(k=>!['transport','serverName','command','args','env','cwd','url','headers','toolCallTimeoutMs','failOnStartupError'].includes(k)))throw new Error('MCP row uses unsupported configuration; Core owns reconnect and instruction bounds')
9 if(typeof config.serverName!=='string')throw new Error('MCP serverName must be literal')
10 const options:Record<string,unknown>={}
11 if(config.toolCallTimeoutMs!==undefined) { const timeout=config.toolCallTimeoutMs;if(typeof timeout!=='number'||!Number.isInteger(timeout)||timeout<1000||timeout>86_400_000||timeout%1000!==0)throw new Error('MCP timeout must be whole seconds within Core bounds');options.execute_timeout=timeout/1000 }
12 // Core connects lazily and reports connection failures through /mcp.
13 // Loader activation cannot stand in for an MCP handshake receipt.
14 if(config.failOnStartupError===true)throw new Error('failOnStartupError requires explicit Core MCP connection qualification before activation')
15 if(config.failOnStartupError!==undefined&&config.failOnStartupError!==false)throw new Error('MCP startup gate must be a boolean')
16 let server:Record<string,unknown>
17 if(config.transport==='stdio') {
18 const cwd=config.cwd??''
19 if(typeof cwd!=='string'||(cwd!==''&&cwd!=='.'&&(!cwd||/[\\:\u0000-\u001f]/u.test(cwd)||cwd.split('/').some(p=>!p||p==='.'||p==='..'))))throw new Error('MCP cwd must be a reviewed bundle-relative directory')
20 server={type:'stdio',command:config.command,args:config.args??[],env:config.env??{},cwd:cwd===''||cwd==='.'?'source':`source/${cwd}`}
21 }else if(config.transport==='streamable-http'||config.transport==='sse')server={type:config.transport,url:config.url,headers:config.headers??{}}
22 else throw new Error('MCP transport must be stdio, streamable-http or sse')
23 if(Object.keys(options).length)server.extensions={'net.codewhale':options}
24 ctx.mcp.registerServer(normalizeMcp({serverName:config.serverName,server}))
25 },
26 }
27 }
28
28 lines TYPESCRIPT