( plugin: LoadedPlugin, errors: PluginError[] = [], )
| 129 | * including manifest entries, .mcp.json files, and .mcpb files |
| 130 | */ |
| 131 | export async function loadPluginMcpServers( |
| 132 | plugin: LoadedPlugin, |
| 133 | errors: PluginError[] = [], |
| 134 | ): Promise<Record<string, McpServerConfig> | undefined> { |
| 135 | let servers: Record<string, McpServerConfig> = {} |
| 136 | |
| 137 | // Check for .mcp.json in plugin directory first (lowest priority) |
| 138 | const defaultMcpServers = await loadMcpServersFromFile( |
| 139 | plugin.path, |
| 140 | '.mcp.json', |
| 141 | ) |
| 142 | if (defaultMcpServers) { |
| 143 | servers = { ...servers, ...defaultMcpServers } |
| 144 | } |
| 145 | |
| 146 | // Handle manifest mcpServers if present (higher priority) |
| 147 | if (plugin.manifest.mcpServers) { |
| 148 | const mcpServersSpec = plugin.manifest.mcpServers |
| 149 | |
| 150 | // Handle different mcpServers formats |
| 151 | if (typeof mcpServersSpec === 'string') { |
| 152 | // Check if it's an MCPB file |
| 153 | if (isMcpbSource(mcpServersSpec)) { |
| 154 | const mcpbServers = await loadMcpServersFromMcpb( |
| 155 | plugin, |
| 156 | mcpServersSpec, |
| 157 | errors, |
| 158 | ) |
| 159 | if (mcpbServers) { |
| 160 | servers = { ...servers, ...mcpbServers } |
| 161 | } |
| 162 | } else { |
| 163 | // Path to JSON file |
| 164 | const mcpServers = await loadMcpServersFromFile( |
| 165 | plugin.path, |
| 166 | mcpServersSpec, |
| 167 | ) |
| 168 | if (mcpServers) { |
| 169 | servers = { ...servers, ...mcpServers } |
| 170 | } |
| 171 | } |
| 172 | } else if (Array.isArray(mcpServersSpec)) { |
| 173 | // Array of paths or inline configs. |
| 174 | // Load all specs in parallel, then merge in original order so |
| 175 | // last-wins collision semantics are preserved. |
| 176 | const results = await Promise.all( |
| 177 | mcpServersSpec.map(async spec => { |
| 178 | try { |
| 179 | if (typeof spec === 'string') { |
| 180 | // Check if it's an MCPB file |
| 181 | if (isMcpbSource(spec)) { |
| 182 | return await loadMcpServersFromMcpb(plugin, spec, errors) |
| 183 | } |
| 184 | // Path to JSON file |
| 185 | return await loadMcpServersFromFile(plugin.path, spec) |
| 186 | } |
| 187 | // Inline MCP server configs (sync) |
| 188 | return spec |
no test coverage detected