mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(codersdk/toolsdk): fix tool schemata (#17365)
Fixes two issues with the MCP server:
- Ensures we have a non-null schema, as the following schema was making
claude-code unhappy:
```
"inputSchema": { "type": "object", "properties": null },
```
- Skip adding the coder_report_task tool if an agent client is not
available. Otherwise the agent may try to report tasks and get confused.
This commit is contained in:
@@ -402,7 +402,9 @@ func mcpServerHandler(inv *serpent.Invocation, client *codersdk.Client, instruct
|
||||
// Create a new context for the tools with all relevant information.
|
||||
clientCtx := toolsdk.WithClient(ctx, client)
|
||||
// Get the workspace agent token from the environment.
|
||||
var hasAgentClient bool
|
||||
if agentToken, err := getAgentToken(fs); err == nil && agentToken != "" {
|
||||
hasAgentClient = true
|
||||
agentClient := agentsdk.New(client.URL)
|
||||
agentClient.SetSessionToken(agentToken)
|
||||
clientCtx = toolsdk.WithAgentClient(clientCtx, agentClient)
|
||||
@@ -417,6 +419,11 @@ func mcpServerHandler(inv *serpent.Invocation, client *codersdk.Client, instruct
|
||||
|
||||
// Register tools based on the allowlist (if specified)
|
||||
for _, tool := range toolsdk.All {
|
||||
// Skip adding the coder_report_task tool if there is no agent client
|
||||
if !hasAgentClient && tool.Tool.Name == "coder_report_task" {
|
||||
cliui.Warnf(inv.Stderr, "Task reporting not available")
|
||||
continue
|
||||
}
|
||||
if len(allowedTools) == 0 || slices.ContainsFunc(allowedTools, func(t string) bool {
|
||||
return t == tool.Tool.Name
|
||||
}) {
|
||||
@@ -689,6 +696,11 @@ func getAgentToken(fs afero.Fs) (string, error) {
|
||||
// mcpFromSDK adapts a toolsdk.Tool to go-mcp's server.ServerTool.
|
||||
// It assumes that the tool responds with a valid JSON object.
|
||||
func mcpFromSDK(sdkTool toolsdk.Tool[any]) server.ServerTool {
|
||||
// NOTE: some clients will silently refuse to use tools if there is an issue
|
||||
// with the tool's schema or configuration.
|
||||
if sdkTool.Schema.Properties == nil {
|
||||
panic("developer error: schema properties cannot be nil")
|
||||
}
|
||||
return server.ServerTool{
|
||||
Tool: mcp.Tool{
|
||||
Name: sdkTool.Tool.Name,
|
||||
|
||||
@@ -259,6 +259,10 @@ is provisioned correctly and the agent can connect to the control plane.
|
||||
Tool: aisdk.Tool{
|
||||
Name: "coder_list_templates",
|
||||
Description: "Lists templates for the authenticated user.",
|
||||
Schema: aisdk.Schema{
|
||||
Properties: map[string]any{},
|
||||
Required: []string{},
|
||||
},
|
||||
},
|
||||
Handler: func(ctx context.Context, _ map[string]any) ([]MinimalTemplate, error) {
|
||||
client, err := clientFromContext(ctx)
|
||||
@@ -318,6 +322,10 @@ is provisioned correctly and the agent can connect to the control plane.
|
||||
Tool: aisdk.Tool{
|
||||
Name: "coder_get_authenticated_user",
|
||||
Description: "Get the currently authenticated user, similar to the `whoami` command.",
|
||||
Schema: aisdk.Schema{
|
||||
Properties: map[string]any{},
|
||||
Required: []string{},
|
||||
},
|
||||
},
|
||||
Handler: func(ctx context.Context, _ map[string]any) (codersdk.User, error) {
|
||||
client, err := clientFromContext(ctx)
|
||||
|
||||
Reference in New Issue
Block a user