Skip to content

Commit daf3c88

Browse files
juergen-kcclaude
andcommitted
fix(mcp): address Bugbot findings on PR #19
Medium: insights.html onToolResult race The initialized flag was set to true BEFORE the try-catch in onToolResult. If parseToolResult threw or returned null, the flag was already set and the setTimeout fallback (which uses the more robust load() path) never fired — the UI locked on the loading spinner with no recovery. Now the flag only flips after a successful render. Low: consolidate addToolWithMeta to delegate addToolWithMeta and addToolWithMetaTyped had ~25 lines of identical rate-limiting + audit-logging + tool-filtering wrapper. Any future fix would need to land in both places. Collapsed to a 1-line shim that calls the typed variant with struct{}, so the wrapper exists once. Call sites unchanged (s.addToolWithMeta still works). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f4da3c5 commit daf3c88

2 files changed

Lines changed: 13 additions & 42 deletions

File tree

internal/mcp/apps.go

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -124,47 +124,11 @@ func addToolWithMetaTyped[In any](s *Server, name, description string, meta mcp.
124124
s.toolNames = append(s.toolNames, name)
125125
}
126126

127-
// addToolWithMeta wraps mcp.AddTool with rate limiting, audit logging, and
128-
// tool filtering — same as addTool but also sets Meta on the tool definition.
129-
// This is used for MCP App tools that need _meta.ui.resourceUri.
127+
// addToolWithMeta is the no-args convenience wrapper for addToolWithMetaTyped.
128+
// Kept as a method on *Server for call-site ergonomics (s.addToolWithMeta(...))
129+
// since no-args App tools are the common case.
130130
func (s *Server) addToolWithMeta(name, description string, meta mcp.Meta, handler func(ctx context.Context, req *mcp.CallToolRequest, args struct{}) (*mcp.CallToolResult, any, error)) {
131-
if !s.toolFilter.isAllowed(name) {
132-
return
133-
}
134-
135-
tool := &mcp.Tool{
136-
Name: name,
137-
Description: description,
138-
Meta: meta,
139-
}
140-
141-
wrappedHandler := func(ctx context.Context, req *mcp.CallToolRequest, args struct{}) (*mcp.CallToolResult, any, error) {
142-
if err := s.limiter.allow(); err != nil {
143-
s.auditLog.log(name, req.Params.Arguments, false, err.Error())
144-
return errorResult(err.Error()), nil, nil
145-
}
146-
147-
result, out, err := handler(ctx, req, args)
148-
149-
if err != nil {
150-
s.auditLog.log(name, req.Params.Arguments, false, err.Error())
151-
} else if result != nil && result.IsError {
152-
errMsg := "tool error"
153-
if len(result.Content) > 0 {
154-
if tc, ok := result.Content[0].(*mcp.TextContent); ok {
155-
errMsg = tc.Text
156-
}
157-
}
158-
s.auditLog.log(name, req.Params.Arguments, false, errMsg)
159-
} else {
160-
s.auditLog.log(name, req.Params.Arguments, true, "")
161-
}
162-
163-
return result, out, err
164-
}
165-
166-
mcp.AddTool(s.mcpServer, tool, wrappedHandler)
167-
s.toolNames = append(s.toolNames, name)
131+
addToolWithMetaTyped[struct{}](s, name, description, meta, handler)
168132
}
169133

170134
// --- MCP App registration entry points ---

internal/mcp/apps_html/insights.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,17 @@ <h3>Top users</h3>
404404
var initialized = false;
405405
jcApp.onToolResult(function(params) {
406406
if (initialized) return;
407-
initialized = true;
407+
// Only mark initialized after a successful render; a thrown error or
408+
// null payload leaves initialized=false so the setTimeout fallback
409+
// below takes over and issues a real callTool with proper error
410+
// handling. Previously setting the flag up-front could leave the UI
411+
// stuck on the loading spinner.
408412
try {
409413
var data = jcApp.parseToolResult(params);
410-
if (data) renderAll(data);
414+
if (data) {
415+
initialized = true;
416+
renderAll(data);
417+
}
411418
} catch (e) { /* proactive fetch below will retry */ }
412419
});
413420

0 commit comments

Comments
 (0)