Skip to content

Commit a39f72c

Browse files
feat: support proposed spec frontmatter in skill discovery
Parse both frontmatter formats for skill tool declarations: - Proposed: metadata.io.modelcontextprotocol/tools (space-separated) - Current: allowed-tools (YAML array) Prefers the proposed format when both are present. This enables mcpi-ext to work with servers adopting the skills-as-groups proposal (github/github-mcp-server#2465) while maintaining backward compat with the current allowed-tools format. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a40af58 commit a39f72c

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

src/skills/discover.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export async function discoverSkillsFromServer(
4747
const fm = parsed.frontmatter as Record<string, unknown>;
4848
const name = (fm.name as string | undefined) ?? resource.name;
4949
const description = (fm.description as string | undefined) ?? "";
50-
const allowedTools = parseAllowedTools(fm["allowed-tools"]);
50+
const allowedTools = parseAllowedTools(fm);
5151

5252
if (!name) {
5353
log(`[skills] Skill at ${resource.uri} has no name, skipping`);
@@ -73,9 +73,28 @@ export async function discoverSkillsFromServer(
7373
return skills;
7474
}
7575

76-
function parseAllowedTools(value: unknown): string[] {
77-
if (Array.isArray(value)) {
78-
return value.filter((v): v is string => typeof v === "string");
76+
/**
77+
* Parse tool names from frontmatter, supporting both formats:
78+
* - Current: `allowed-tools: [tool_a, tool_b]` (YAML array)
79+
* - Proposed spec: `metadata.io.modelcontextprotocol/tools: "tool_a tool_b"` (space-separated)
80+
*
81+
* Prefers the proposed spec format when both are present.
82+
*/
83+
function parseAllowedTools(fm: Record<string, unknown>): string[] {
84+
// Proposed spec format: metadata.io.modelcontextprotocol/tools (space-separated string)
85+
const metadata = fm.metadata as Record<string, unknown> | undefined;
86+
if (metadata) {
87+
const specTools = metadata["io.modelcontextprotocol/tools"];
88+
if (typeof specTools === "string" && specTools.trim().length > 0) {
89+
return specTools.trim().split(/\s+/);
90+
}
7991
}
92+
93+
// Current format: allowed-tools (YAML array)
94+
const legacy = fm["allowed-tools"];
95+
if (Array.isArray(legacy)) {
96+
return legacy.filter((v): v is string => typeof v === "string");
97+
}
98+
8099
return [];
81100
}

0 commit comments

Comments
 (0)