Unify MCP tool handlers around one result type

This commit is contained in:
Ian Gulliver
2026-10-23 17:38:34 -07:00
parent 6c51457a06
commit 758aa7f893
7 changed files with 28 additions and 48 deletions
+5 -5
View File
@@ -35,9 +35,9 @@ func (m *Manager) clientShellTools() []mcp.Tool {
"The most recently active one is listed first. " +
"The human's iPhone is listed too, when byre's app is open on it; it takes only show_page, show_file and drive_page, and the other client tools fail there.",
InputSchema: json.RawMessage(`{"type": "object", "properties": {}}`),
Handler: func(ctx context.Context, raw json.RawMessage) (string, error) {
Handler: mcp.Typed(func(ctx context.Context, args struct{}) (string, error) {
return m.listClients(), nil
},
}),
},
{
Name: "client_bash",
@@ -134,7 +134,7 @@ func (m *Manager) clientTools(l *live) []mcp.Tool {
},
"required": ["client", "op"]
}`),
Rich: mcp.TypedRich(func(ctx context.Context, args drivePageArgs) mcp.Result {
Handler: mcp.TypedResult(func(ctx context.Context, args drivePageArgs) mcp.Result {
return m.drivePage(ctx, l, args)
}),
},
@@ -186,7 +186,7 @@ func (m *Manager) clientTools(l *live) []mcp.Tool {
},
"required": ["client", "path"]
}`),
Rich: mcp.TypedRich(m.clientRead),
Handler: mcp.TypedResult(m.clientRead),
},
{
Name: "client_write",
@@ -264,7 +264,7 @@ func (m *Manager) clientTools(l *live) []mcp.Tool {
},
"required": ["client", "tool"]
}`),
Rich: mcp.TypedRich(m.clientHands),
Handler: mcp.TypedResult(m.clientHands),
},
}...)
}
+1 -1
View File
@@ -27,7 +27,7 @@ func (m *Manager) renderDiagramTool() mcp.Tool {
},
"required": ["source"]
}`),
Rich: mcp.TypedRich(func(ctx context.Context, args struct {
Handler: mcp.TypedResult(func(ctx context.Context, args struct {
Source string `json:"source"`
}) mcp.Result {
png, err := renderDiagram(ctx, args.Source)
+1 -1
View File
@@ -38,7 +38,7 @@ func (m *Manager) fileTools(l *live) []mcp.Tool {
},
"required": ["path"]
}`),
Rich: mcp.TypedRich(func(ctx context.Context, args readArgs) mcp.Result {
Handler: mcp.TypedResult(func(ctx context.Context, args readArgs) mcp.Result {
return m.read(l, args)
}),
},
+1 -1
View File
@@ -32,7 +32,7 @@ func (m *Manager) randomChoiceTool() mcp.Tool {
},
"required": ["choices"]
}`),
Rich: mcp.TypedRich(func(ctx context.Context, args struct {
Handler: mcp.TypedResult(func(ctx context.Context, args struct {
Choices []struct {
Choice string `json:"choice"`
Weight float64 `json:"weight"`
+2 -2
View File
@@ -121,7 +121,7 @@ func (m *Manager) cancelReadyTool(l *live) mcp.Tool {
Description: "Withdraw your standing ready_for_merge or suggest_discard, when it no longer holds: for example the human raised a problem, or you found more work. " +
"The human then no longer sees the task as ready to merge or as suggested for discard; call ready_for_merge or suggest_discard again once it holds.",
InputSchema: json.RawMessage(`{"type": "object", "properties": {}}`),
Handler: func(ctx context.Context, raw json.RawMessage) (string, error) {
Handler: mcp.Typed(func(ctx context.Context, args struct{}) (string, error) {
err := m.store.ClearReady(ctx, l.taskID, agentActor, "")
if errors.Is(err, store.ErrNotFound) {
return "", fmt.Errorf("%w: this task has no standing ready_for_merge or suggest_discard", ErrConflict)
@@ -130,7 +130,7 @@ func (m *Manager) cancelReadyTool(l *live) mcp.Tool {
return "", err
}
return "Withdrawn: the human no longer sees this task as ready to merge or suggested for discard.", nil
},
}),
}
}
+2 -2
View File
@@ -264,13 +264,13 @@ func (m *Manager) takeSnapshotTool(l *live) mcp.Tool {
Name: "take_snapshot",
Description: takeSnapshotDescription + " It snapshots your own task's worktree.",
InputSchema: json.RawMessage(`{"type": "object", "properties": {}}`),
Handler: func(ctx context.Context, args json.RawMessage) (string, error) {
Handler: mcp.Typed(func(ctx context.Context, args struct{}) (string, error) {
err := m.RequestSnapshot(ctx, l.taskID)
if err != nil {
return "", err
}
return "Worktree committed to the task's branch, and snapshot requested. If the project has a review workflow, its reviewers check it against the default branch (a subtask's against its parent's branch); their findings come to you together once the workflow finishes.", nil
},
}),
}
}