99 "net/url"
1010 "os"
1111 "path/filepath"
12- "reflect"
1312 "strings"
1413 "sync"
1514
@@ -65,7 +64,7 @@ func lookupInterceptStage(requestID string) string {
6564func main () {
6665 server := mcp .NewServer (& mcp.Implementation {
6766 Name : "iwdp-mcp" ,
68- Version : "0.5.2 " ,
67+ Version : "0.5.3 " ,
6968 }, nil )
7069
7170 registerTools (server )
@@ -76,23 +75,67 @@ func main() {
7675}
7776
7877func addTool [In , Out any ](s * mcp.Server , t * mcp.Tool , h mcp.ToolHandlerFor [In , Out ]) {
79- if t .InputSchema == nil && isEmptyStructType (reflect .TypeFor [In ]()) {
80- copy := * t
81- copy .InputSchema = emptyObjectInputSchema ()
82- t = & copy
78+ copy := * t
79+ if copy .InputSchema == nil {
80+ schema , err := jsonschema.For [In ](nil )
81+ if err != nil {
82+ panic (fmt .Sprintf ("AddTool: tool %q: input schema: %v" , copy .Name , err ))
83+ }
84+ copy .InputSchema = codexCompatibleInputSchema (copy .Name , schema )
85+ } else {
86+ copy .InputSchema = codexCompatibleInputSchema (copy .Name , copy .InputSchema )
87+ }
88+ mcp .AddTool (s , & copy , h )
89+ }
90+
91+ func codexCompatibleInputSchema (toolName string , schema any ) map [string ]any {
92+ data , err := json .Marshal (schema )
93+ if err != nil {
94+ panic (fmt .Sprintf ("AddTool: tool %q: marshal input schema: %v" , toolName , err ))
8395 }
84- mcp .AddTool (s , t , h )
96+ var out map [string ]any
97+ if err := json .Unmarshal (data , & out ); err != nil {
98+ panic (fmt .Sprintf ("AddTool: tool %q: unmarshal input schema: %v" , toolName , err ))
99+ }
100+ normalizeSchema (out )
101+ return out
85102}
86103
87- func isEmptyStructType (t reflect.Type ) bool {
88- return t .Kind () == reflect .Struct && t .NumField () == 0
104+ func normalizeSchema (schema any ) {
105+ switch s := schema .(type ) {
106+ case map [string ]any :
107+ for _ , value := range s {
108+ normalizeSchema (value )
109+ }
110+ if schemaTypeIncludes (s ["type" ], "object" ) {
111+ if _ , ok := s ["properties" ].(map [string ]any ); ! ok {
112+ s ["properties" ] = map [string ]any {}
113+ }
114+ }
115+ if schemaTypeIncludes (s ["type" ], "array" ) {
116+ if _ , ok := s ["items" ].(map [string ]any ); ! ok {
117+ s ["items" ] = map [string ]any {}
118+ }
119+ }
120+ case []any :
121+ for _ , value := range s {
122+ normalizeSchema (value )
123+ }
124+ }
89125}
90126
91- func emptyObjectInputSchema () * jsonschema.Schema {
92- return & jsonschema.Schema {
93- Type : "object" ,
94- Properties : map [string ]* jsonschema.Schema {},
127+ func schemaTypeIncludes (value any , typ string ) bool {
128+ switch v := value .(type ) {
129+ case string :
130+ return v == typ
131+ case []any :
132+ for _ , item := range v {
133+ if item == typ {
134+ return true
135+ }
136+ }
95137 }
138+ return false
96139}
97140
98141// --- Input/Output types for MCP tools ---
0 commit comments