[BUG] MCP clients get no tools from v0.3.0: kubescape_get_vulnerability_details outputSchema is not an object
还没有人认领这个 Issue。
评估
调研方向
从 pkg/kubescape/kubescape.go 和 handleGetVulnerabilityDetails 的输出类型开始,然后阅读 cmd/tools_output_schema_test.go 及其 TestEveryToolHasValidOutputSchema 测试。按描述将 slice 输出包装在一个对象中,并加强测试,要求每个工具的输出 schema 类型都是 object。当 schema 测试通过并能捕获非对象 schema 时,即为完成。
由索引模型根据 Issue 内容生成。
描述
Bug · Severity: Medium · default install · no workaround short of disabling the Kubescape tools
Affects: kagent-tools v0.3.0 (bundled with kagent v0.10.3) · Component: MCP server, tools/list
Introduced by: #66 "Migrate to GO SDK" (merged 2026-09-23)
What breaks
As a user I point an MCP client (MCP Inspector, VS Code, Cursor, Claude Desktop, anything on the TypeScript SDK) at the kagent-tools server. On v0.2.1 the client lists all 124 tools. On v0.3.0, which serves 126, I get none: one tool advertises an invalid outputSchema, and the client rejects the entire tools/list response.
Failed to list tools: [{"code":"invalid_value","values":["object"],
"path":["tools",113,"outputSchema","type"],"message":"Invalid input: expected \"object\""}]
Tool 113 is kubescape_get_vulnerability_details. Its outputSchema is {"type": ["null","array"]}. The MCP spec (2025-06-18) requires a tool's outputSchema to have type: "object", because structured content is always a JSON object.
Reproduce
Docker only, no cluster needed:
docker run -d --name kt --platform linux/amd64 -p 18084:8084 ghcr.io/kagent-dev/kagent/tools:0.3.0 --port 8084
npx @modelcontextprotocol/[email protected] --cli http://localhost:18084/mcp --transport http --method tools/list
The same command against ghcr.io/kagent-dev/kagent/tools:0.2.1 lists all 124 tools and exits 0.
Expected vs actual
- Expected: every tool's
outputSchemais an object schema, andtools/listsucceeds on spec-compliant clients. - Actual:
kubescape_get_vulnerability_detailsadvertises an array schema, and strict clients get no tools at all.
Ask
Wrap that tool's output in an object, and make the existing schema test enforce type: "object" so the next slice-returning handler can't regress it. It's a one-type change. Clients stay broken until a release ships it.
Root cause: the handler's typed output is a slice, so go-sdk infers an array schema
pkg/kubescape/kubescape.go (v0.3.0, unchanged on main):
func (k *KubescapeTool) handleGetVulnerabilityDetails(ctx context.Context, request *sdkmcp.CallToolRequest,
in getVulnerabilityDetailsInput) (*sdkmcp.CallToolResult, []v1beta1.Match, error)
go-sdk (v1.8.0) infers the output schema from the Out type parameter. A nil-able slice becomes {"type":["null","array"]}.
Suggested fix:
type vulnerabilityDetailsOutput struct {
Matches []v1beta1.Match `json:"matches"`
}
cmd/tools_output_schema_test.go (TestEveryToolHasValidOutputSchema) only checks that each schema is non-nil and JSON-serializable, so this passed CI. Adding require.Equal(t, "object", tool.OutputSchema.(map[string]any)["type"]) (or the equivalent on the typed schema) would catch it.
Scope: exactly one of 126 tools is affected, and the server itself works
Raw JSON-RPC against the v0.3.0 image, with no client-side validation, lists every tool whose schema isn't an object:
H='-H Content-Type:application/json -H Accept:application/json,text/event-stream'
SID=$(curl -s -D - -o /dev/null $H http://localhost:18084/mcp \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
| awk -F': ' 'tolower($1)=="mcp-session-id"{print $2}' | tr -d '\r')
curl -s $H -H "Mcp-Session-Id: $SID" http://localhost:18084/mcp -d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
curl -s $H -H "Mcp-Session-Id: $SID" -H "MCP-Protocol-Version: 2025-06-18" http://localhost:18084/mcp \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | sed -n 's/^data: //p' \
| jq -c '.result.tools|to_entries[]|select(.value.outputSchema.type!="object")|{i:.key,name:.value.name,type:.value.outputSchema.type}'
# {"i":113,"name":"kubescape_get_vulnerability_details","type":["null","array"]}
- Reproduced with image digest
sha256:cb89eb76216195a90cac73846b447525b6e6e33e45154d1ded9621bf11340315, both locally and in a kind cluster running kagentv0.10.3. The0.2.1image, run the same way, passes with 124 tools. - Not a client-version artifact: the image is the only thing that changed between a passing and a failing run (kagent v0.10.2 → v0.10.3, kagent-tools 0.2.1 → 0.3.0). The Inspector version was pinned at 0.21.2 in both.
- Not affected: kagent agents themselves. Their MCP clients don't validate
outputSchema.type, so the RemoteMCPServer staysAcceptedand agents still call tools. Only strict, spec-validating clients break.
- 主要语言
- Go
- 星标
- 36
- 派生
- 29
- 平均合并
- 3 天 23 小时
- 30 天内合并 PR
- 3
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 提供 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 没有贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
kagent-dev/tools 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
kagent-dev/tools#54 ·
-
[FEATURE] Add a limit parameter to k8s_get_resources to bound context growth可能已有人在做 @anjosluc 于 19 天前认领。 未关闭
难度 4/5 3-5 天 新手友好度 45/100
kagent-dev/tools#82 ·
-
难度 3/5 1-2 天 新手友好度 78/100
kagent-dev/tools#80 ·
-
难度 3/5 1-2 天 新手友好度 72/100
kagent-dev/tools#69 · 1 条评论 ·
-
难度 3/5 1-2 天 新手友好度 68/100
kagent-dev/tools#68 · 1 条评论 ·
相似的 Issue
-
难度 1/5 1-3 小时 新手友好度 90/100
FootprintAI/Containarium#2338 ·
维护者通常 1 天内回复
-
[Bug]: core doesn't build standalone on dev since a17068054 (go-mp3 require dropped, go.sum pruned)未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100
SagerNet/sing-openvpn#11 ·
-
priority: P3 type: devops
难度 2/5 1-3 小时 新手友好度 75/100
jiegui2025/hwspec#57 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
columnar-tech/dbc#513 ·
维护者通常 1 天内回复