* Build claude's project-scoped MCP config from the `{ kind: 'mcp' }` skills, * resolving every header value (SecretRef / bearer / string). Returns * `undefined` when there are no MCP skills so the caller can skip the write.
( skills: Array<WorkspaceSkill>, resolveSecret: (ref: SecretRef) => string, )
| 80 | * `undefined` when there are no MCP skills so the caller can skip the write. |
| 81 | */ |
| 82 | function buildMcpConfig( |
| 83 | skills: Array<WorkspaceSkill>, |
| 84 | resolveSecret: (ref: SecretRef) => string, |
| 85 | ): { mcpServers: Record<string, ClaudeMcpServer> } | undefined { |
| 86 | const mcpServers: Record<string, ClaudeMcpServer> = {} |
| 87 | let count = 0 |
| 88 | for (const skill of skills) { |
| 89 | if (skill.kind !== 'mcp') continue |
| 90 | count += 1 |
| 91 | const headers: Record<string, string> = {} |
| 92 | const rawHeaders = skill.config.headers ?? {} |
| 93 | for (const [name, value] of Object.entries(rawHeaders)) { |
| 94 | headers[name] = resolveHeaderValue(value, resolveSecret) |
| 95 | } |
| 96 | const rawUrl = skill.config['url'] |
| 97 | const url = typeof rawUrl === 'string' ? rawUrl : '' |
| 98 | mcpServers[skill.name] = { type: 'http', url, headers } |
| 99 | } |
| 100 | return count > 0 ? { mcpServers } : undefined |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * Write the project-scoped `.mcp.json`, re-resolving every secret. This runs on |
no test coverage detected