Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions mcpcontract/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ func TestContextHasExplicitLocalAndFleetProfiles(t *testing.T) {
if _, ok := fleet["properties"].(map[string]any)["nodes"]; !ok {
t.Fatal("fleet context is missing nodes")
}
dynamicMCP := localProperties["dynamic_mcp"].(map[string]any)
dynamicItem := dynamicMCP["items"].(map[string]any)
dynamicProperties := dynamicItem["properties"].(map[string]any)
for _, name := range []string{"name", "description", "status", "tool_count", "last_error_code"} {
if _, ok := dynamicProperties[name]; !ok {
t.Fatalf("dynamic MCP context item is missing %s", name)
}
}
if dynamicItem["additionalProperties"] != false {
t.Fatalf("dynamic MCP context item must remain strict: %#v", dynamicItem)
}
if reflect.DeepEqual(local, fleet) {
t.Fatal("local and fleet context profiles unexpectedly match")
}
Expand Down
14 changes: 13 additions & 1 deletion mcpcontract/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func localContextProperties(includeShared bool) map[string]any {
"items": map[string]any{"type": "array", "items": commonSkill},
}, "root", "total", "truncated", "items")
commonSkills["description"] = "Lower-priority common Agent Skill capability index; installed AgentDock Skills take precedence on conflicts."
dynamicItem := contextItemSchema(true)
dynamicItem := dynamicMCPItemSchema()
indexItem := contextItemSchema(false)
warning := map[string]any{
"type": "object", "properties": map[string]any{
Expand Down Expand Up @@ -227,3 +227,15 @@ func contextItemSchema(requireDescription bool) map[string]any {
"additionalProperties": false,
}
}

func dynamicMCPItemSchema() map[string]any {
schema := contextItemSchema(true)
properties := schema["properties"].(map[string]any)
properties["status"] = map[string]any{
"type": "string", "description": "Runtime health state: idle, ready, or error.",
"enum": []string{"idle", "ready", "error"},
}
properties["tool_count"] = integerProperty("Discovered tool count from the latest successful refresh.")
properties["last_error_code"] = stringProperty("Safe machine-readable code for the latest refresh error.")
return schema
}