11import OAuthProvider from '@cloudflare/workers-oauth-provider'
22import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
3+ import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'
4+ import type { ZodRawShape } from 'zod'
35import workerVersion from './version'
46import { McpAgent } from 'agents/mcp'
57import { createAuthApp , createTokenExchangeCallback } from './auth'
@@ -9,7 +11,7 @@ import { WorkerApiClient } from './apiClient'
911import { registerAllToolsWithServer } from '../../src/mcp/tools/index'
1012
1113// Import types
12- import { DevCycleMCPServerInstance } from '../../src/mcp/server'
14+ import type { DevCycleMCPServerInstance } from '../../src/mcp/server'
1315import { handleToolError } from '../../src/mcp/utils/errorHandling'
1416
1517import { registerProjectSelectionTools } from './projectSelectionTools'
@@ -48,12 +50,14 @@ export class DevCycleMCP extends McpAgent<Env, DevCycleMCPState, UserProps> {
4850 * Initialize the MCP server with tools and handlers
4951 */
5052 async init ( ) {
53+ // Initialize MCP headers with version once at startup
54+ WorkerApiClient . initializeMCPHeaders ( this . version )
55+
5156 // Initialize the Worker-specific API client with OAuth tokens and state management
5257 this . apiClient = new WorkerApiClient (
5358 this . props ,
5459 this . env ,
5560 this , // Pass the McpAgent instance for state management
56- this . version ,
5761 )
5862
5963 console . log ( 'Initializing DevCycle MCP Worker' , {
@@ -62,26 +66,50 @@ export class DevCycleMCP extends McpAgent<Env, DevCycleMCPState, UserProps> {
6266 hasProject : await this . apiClient . hasProjectKey ( ) ,
6367 } )
6468
69+ // Check environment variable for output schema support
70+ const enableOutputSchemas =
71+ ( this . env . ENABLE_OUTPUT_SCHEMAS as string ) === 'true'
72+ if ( enableOutputSchemas ) {
73+ console . log ( 'DevCycle MCP Worker - Output Schemas: ENABLED' )
74+ }
75+
6576 // Create an adapter to make the worker's McpServer compatible with the CLI registration pattern
6677 const serverAdapter : DevCycleMCPServerInstance = {
6778 registerToolWithErrorHandling : (
6879 name : string ,
6980 config : {
7081 description : string
71- annotations ?: any
72- inputSchema ?: any
73- outputSchema ?: any
82+ annotations ?: ToolAnnotations
83+ inputSchema ?: ZodRawShape
84+ outputSchema ?: ZodRawShape
7485 } ,
75- handler : ( args : any ) => Promise < any > ,
86+ handler : ( args : unknown ) => Promise < unknown > ,
7687 ) => {
88+ // Conditionally include output schema based on environment variable
89+ const toolConfig : {
90+ description : string
91+ annotations ?: ToolAnnotations
92+ inputSchema ?: ZodRawShape
93+ outputSchema ?: ZodRawShape
94+ } = {
95+ description : config . description ,
96+ annotations : config . annotations ,
97+ inputSchema : config . inputSchema ,
98+ }
99+
100+ if ( enableOutputSchemas && config . outputSchema ) {
101+ toolConfig . outputSchema = config . outputSchema
102+ }
103+
77104 this . server . registerTool (
78105 name ,
79- {
80- description : config . description ,
81- annotations : config . annotations ,
82- inputSchema : config . inputSchema || { } ,
83- } ,
84- async ( args : any ) => {
106+ // TypeScript workaround: The MCP SDK's registerTool has complex generic constraints
107+ // that cause "Type instantiation is excessively deep" errors when used with our
108+ // adapter pattern. The types are correct at runtime, but TS can't verify them.
109+ toolConfig as Parameters <
110+ typeof this . server . registerTool
111+ > [ 1 ] ,
112+ async ( args : unknown ) => {
85113 try {
86114 const result = await handler ( args )
87115 return {
0 commit comments