Skip to content
Merged
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
21 changes: 21 additions & 0 deletions mcpcontract/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,27 @@ func TestContextHasExplicitLocalAndFleetProfiles(t *testing.T) {
if _, ok := localProperties["skills"]; !ok {
t.Fatal("local context is missing skills")
}
commonSkills, ok := localProperties["common_skills"].(map[string]any)
if !ok {
t.Fatal("local context is missing common_skills")
}
commonProperties := commonSkills["properties"].(map[string]any)
for _, name := range []string{"root", "total", "truncated", "items"} {
if _, ok := commonProperties[name]; !ok {
t.Fatalf("common_skills is missing %s", name)
}
}
for _, required := range local["required"].([]string) {
if required == "common_skills" {
t.Fatal("common_skills must remain optional for rolling compatibility with older AgentDock nodes")
}
}
nodes := fleet["properties"].(map[string]any)["nodes"].(map[string]any)
node := nodes["items"].(map[string]any)
nodeContext := node["properties"].(map[string]any)["context"].(map[string]any)
if _, ok := nodeContext["properties"].(map[string]any)["common_skills"]; !ok {
t.Fatal("fleet node context is missing common_skills")
}
runtimeSchema, ok := localProperties["runtime"].(map[string]any)
if !ok {
t.Fatal("local context is missing runtime")
Expand Down
18 changes: 16 additions & 2 deletions mcpcontract/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,19 @@ func localContextProperties(includeShared bool) map[string]any {
"file": stringProperty("skill:// URI for the active SKILL.md."), "bundled": booleanProperty("Whether the Skill is bundled by AgentDock."),
}, "required": []string{"name", "description", "file"}, "additionalProperties": false,
}
commonSkill := map[string]any{
"type": "object", "properties": map[string]any{
"name": stringProperty("Common Skill name."), "description": stringProperty("Short capability description."),
"file": stringProperty("Host path to the common SKILL.md."),
}, "required": []string{"name", "description", "file"}, "additionalProperties": false,
}
commonSkills := strictObject(map[string]any{
"root": stringProperty("Common Agent Skills root path."),
"total": integerProperty("Total valid common Skills discovered before truncation."),
"truncated": booleanProperty("Whether the common Skill index was truncated."),
"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)
indexItem := contextItemSchema(false)
warning := map[string]any{
Expand All @@ -168,8 +181,9 @@ func localContextProperties(includeShared bool) map[string]any {
}, "required": []string{"source", "message"}, "additionalProperties": false,
}
props := map[string]any{
"skills": map[string]any{"type": "array", "description": "Installed document Skill capability index.", "items": skill},
"dynamic_mcp": map[string]any{"type": "array", "description": "Enabled dynamic MCP server capability index.", "items": dynamicItem},
"skills": map[string]any{"type": "array", "description": "Installed document Skill capability index.", "items": skill},
"common_skills": commonSkills,
"dynamic_mcp": map[string]any{"type": "array", "description": "Enabled dynamic MCP server capability index.", "items": dynamicItem},
"acp": strictObject(map[string]any{
"enabled": booleanProperty("Whether ACP is enabled."), "agent": stringProperty("Configured ACP agent name."), "description": stringProperty("Short ACP usage orientation."),
}, "enabled", "agent", "description"),
Expand Down
Loading