-
Notifications
You must be signed in to change notification settings - Fork 75
Support per-plugin MCP environment variable configuration #14381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3ea8f8c
4e772ae
8e8e902
b9d79d6
ee0f392
fc4eb64
5168aa4
fb637b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -169,7 +169,7 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var toolsBuilder strings.Builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var mcpServersBuilder strings.Builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var markdownBuilder strings.Builder // Only used for imports WITH inputs (compile-time substitution) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var importPaths []string // NEW: Track import paths for runtime-import macro generation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var importPaths []string // NEW: Track import paths for runtime-import macro generation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var stepsBuilder strings.Builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var copilotSetupStepsBuilder strings.Builder // Track copilot-setup-steps.yml separately | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var runtimesBuilder strings.Builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -317,7 +317,7 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Has inputs - must inline for compile-time substitution | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("Agent file has inputs - will be inlined instead of runtime-imported") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // For agent files, extract markdown content (only when inputs are present) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| markdownContent, err := processIncludedFileWithVisited(item.fullPath, item.sectionName, false, visited) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -489,7 +489,7 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Has inputs - must inline for compile-time substitution | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.Printf("Import %s has inputs - will be inlined for compile-time substitution", importRelPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Extract markdown content from imported file (only for imports with inputs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| markdownContent, err := processIncludedFileWithVisited(item.fullPath, item.sectionName, false, visited) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -584,15 +584,29 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Extract plugins from imported file (merge into set to avoid duplicates) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // This now handles both simple string format and object format with MCP configs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pluginsContent, err := extractPluginsFromContent(string(content)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err == nil && pluginsContent != "" && pluginsContent != "[]" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Parse plugins JSON array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var importedPlugins []string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if jsonErr := json.Unmarshal([]byte(pluginsContent), &importedPlugins); jsonErr == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, plugin := range importedPlugins { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !pluginsSet[plugin] { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pluginsSet[plugin] = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| plugins = append(plugins, plugin) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Parse plugins - can be array of strings or objects | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var pluginsRaw []any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if jsonErr := json.Unmarshal([]byte(pluginsContent), &pluginsRaw); jsonErr == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, item := range pluginsRaw { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Handle string format: "org/repo" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if pluginStr, ok := item.(string); ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !pluginsSet[pluginStr] { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pluginsSet[pluginStr] = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| plugins = append(plugins, pluginStr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if pluginObj, ok := item.(map[string]any); ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Handle object format: { "id": "org/repo", "mcp": {...} } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if idVal, hasID := pluginObj["id"]; hasID { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if pluginID, ok := idVal.(string); ok && !pluginsSet[pluginID] { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pluginsSet[pluginID] = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| plugins = append(plugins, pluginID) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Note: MCP configs from imports are currently not merged | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // They would need to be handled at a higher level in compiler_orchestrator_tools.go | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+590
to
+607
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Parse plugins - can be array of strings or objects | |
| var pluginsRaw []any | |
| if jsonErr := json.Unmarshal([]byte(pluginsContent), &pluginsRaw); jsonErr == nil { | |
| for _, item := range pluginsRaw { | |
| // Handle string format: "org/repo" | |
| if pluginStr, ok := item.(string); ok { | |
| if !pluginsSet[pluginStr] { | |
| pluginsSet[pluginStr] = true | |
| plugins = append(plugins, pluginStr) | |
| } | |
| } else if pluginObj, ok := item.(map[string]any); ok { | |
| // Handle object format: { "id": "org/repo", "mcp": {...} } | |
| if idVal, hasID := pluginObj["id"]; hasID { | |
| if pluginID, ok := idVal.(string); ok && !pluginsSet[pluginID] { | |
| pluginsSet[pluginID] = true | |
| plugins = append(plugins, pluginID) | |
| // Note: MCP configs from imports are currently not merged | |
| // They would need to be handled at a higher level in compiler_orchestrator_tools.go | |
| // Parse plugins - can be array of strings/objects or an object with repos | |
| var pluginsRaw any | |
| if jsonErr := json.Unmarshal([]byte(pluginsContent), &pluginsRaw); jsonErr == nil { | |
| switch v := pluginsRaw.(type) { | |
| case []any: | |
| for _, item := range v { | |
| // Handle string format: "org/repo" | |
| if pluginStr, ok := item.(string); ok { | |
| if !pluginsSet[pluginStr] { | |
| pluginsSet[pluginStr] = true | |
| plugins = append(plugins, pluginStr) | |
| } | |
| } else if pluginObj, ok := item.(map[string]any); ok { | |
| // Handle object format: { "id": "org/repo", "mcp": {...} } | |
| if idVal, hasID := pluginObj["id"]; hasID { | |
| if pluginID, ok := idVal.(string); ok && !pluginsSet[pluginID] { | |
| pluginsSet[pluginID] = true | |
| plugins = append(plugins, pluginID) | |
| // Note: MCP configs from imports are currently not merged | |
| // They would need to be handled at a higher level in compiler_orchestrator_tools.go | |
| } | |
| } | |
| } | |
| } | |
| case map[string]any: | |
| // Handle object format: { "repos": [...], "github-token": "..." } | |
| if reposVal, hasRepos := v["repos"]; hasRepos { | |
| if reposSlice, ok := reposVal.([]any); ok { | |
| for _, repoItem := range reposSlice { | |
| if pluginStr, ok := repoItem.(string); ok { | |
| if !pluginsSet[pluginStr] { | |
| pluginsSet[pluginStr] = true | |
| plugins = append(plugins, pluginStr) | |
| } | |
| } |
Copilot
AI
Feb 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imported plugin objects can include MCP env config, but import processing currently drops those configs (only the plugin ID is merged). This means MCP env vars for imported plugins won't be available when starting the gateway. Consider extending ImportsResult to carry merged plugin MCP configs and merging them into WorkflowData.PluginInfo.MCPConfigs, or emitting a validation warning/error when an imported plugin specifies mcp.env that can't be honored.
| // They would need to be handled at a higher level in compiler_orchestrator_tools.go | |
| // They would need to be handled at a higher level in compiler_orchestrator_tools.go | |
| // Emit a warning if an imported plugin defines MCP env config that cannot be honored here. | |
| if mcpCfg, hasMCP := pluginObj["mcp"]; hasMCP && mcpCfg != nil { | |
| if mcpMap, ok := mcpCfg.(map[string]any); ok { | |
| if _, hasEnv := mcpMap["env"]; hasEnv { | |
| importLog.Warnf("imported plugin %s defines mcp.env, which is currently not merged into workflow MCP configs", pluginID) | |
| } | |
| } | |
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2483,9 +2483,20 @@ | |||||
| ] | ||||||
| }, | ||||||
| "plugins": { | ||||||
| "description": "Plugin configuration for installing plugins before workflow execution. Supports both array format (list of repos) and object format (repos + custom token).", | ||||||
| "description": "Plugin configuration for installing plugins before workflow execution. Supports array format (list of repos/plugin configs) and object format (repos + custom token).", | ||||||
| "examples": [ | ||||||
| ["github/copilot-plugin", "acme/custom-tools"], | ||||||
| [ | ||||||
| "github/simple-plugin", | ||||||
| { | ||||||
| "id": "github/mcp-plugin", | ||||||
| "mcp": { | ||||||
| "env": { | ||||||
| "API_KEY": "${{ secrets.API_KEY }}" | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| ], | ||||||
| { | ||||||
| "repos": ["github/copilot-plugin", "acme/custom-tools"], | ||||||
| "github-token": "${{ secrets.CUSTOM_PLUGIN_TOKEN }}" | ||||||
|
|
@@ -2494,25 +2505,93 @@ | |||||
| "oneOf": [ | ||||||
| { | ||||||
| "type": "array", | ||||||
| "description": "List of plugin repository slugs to install. Each plugin is installed using the engine's plugin installation command with default token resolution.", | ||||||
| "description": "List of plugins to install. Each item can be either a repository slug string (e.g., 'org/repo') or an object with id and optional MCP configuration.", | ||||||
| "items": { | ||||||
| "type": "string", | ||||||
| "pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$", | ||||||
| "description": "Plugin repository slug in the format 'org/repo' (e.g., 'github/example-plugin')" | ||||||
| "oneOf": [ | ||||||
| { | ||||||
| "type": "string", | ||||||
| "pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$", | ||||||
| "description": "Plugin repository slug in the format 'org/repo' (e.g., 'github/example-plugin')" | ||||||
| }, | ||||||
| { | ||||||
| "type": "object", | ||||||
| "description": "Plugin configuration with ID and optional MCP settings for environment variables", | ||||||
| "required": ["id"], | ||||||
| "properties": { | ||||||
| "id": { | ||||||
| "type": "string", | ||||||
| "pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$", | ||||||
| "description": "Plugin repository slug in the format 'org/repo' (e.g., 'github/example-plugin')" | ||||||
| }, | ||||||
| "mcp": { | ||||||
| "type": "object", | ||||||
| "description": "MCP server configuration for this plugin. When defined, the compiler scans the plugin's MCP JSON and mounts it in the gateway with the specified environment variables.", | ||||||
| "properties": { | ||||||
| "env": { | ||||||
| "type": "object", | ||||||
| "description": "Environment variables to pass when instantiating the MCP server. These variables are made available to the MCP server at runtime and can reference secrets using ${{ secrets.SECRET_NAME }} syntax.", | ||||||
| "additionalProperties": { | ||||||
| "type": "string" | ||||||
| }, | ||||||
| "examples": [ | ||||||
| { | ||||||
| "API_KEY": "${{ secrets.API_KEY }}", | ||||||
| "API_URL": "https://api.example.com" | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| }, | ||||||
| "additionalProperties": false | ||||||
| } | ||||||
| }, | ||||||
| "additionalProperties": false | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| }, | ||||||
| { | ||||||
| "type": "object", | ||||||
| "description": "Plugin configuration with custom GitHub token. The custom token overrides the default token resolution chain.", | ||||||
| "description": "Plugin configuration with custom GitHub token. Repos can be either strings or objects with MCP configuration.", | ||||||
| "required": ["repos"], | ||||||
| "properties": { | ||||||
| "repos": { | ||||||
| "type": "array", | ||||||
| "description": "List of plugin repository slugs to install", | ||||||
| "description": "List of plugins to install. Each item can be either a repository slug string or an object with id and optional MCP configuration.", | ||||||
| "items": { | ||||||
| "type": "string", | ||||||
| "pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$", | ||||||
| "description": "Plugin repository slug in the format 'org/repo' (e.g., 'github/example-plugin')" | ||||||
| "oneOf": [ | ||||||
| { | ||||||
| "type": "string", | ||||||
| "pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$", | ||||||
| "description": "Plugin repository slug in the format 'org/repo' (e.g., 'github/example-plugin')" | ||||||
| }, | ||||||
| { | ||||||
| "type": "object", | ||||||
| "description": "Plugin configuration with ID and optional MCP settings", | ||||||
| "required": ["id"], | ||||||
| "properties": { | ||||||
| "id": { | ||||||
| "type": "string", | ||||||
| "pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$", | ||||||
| "description": "Plugin repository slug in the format 'org/repo' (e.g., 'github/example-plugin')" | ||||||
| }, | ||||||
| "mcp": { | ||||||
| "type": "object", | ||||||
| "description": "MCP server configuration for this plugin", | ||||||
| "properties": { | ||||||
| "env": { | ||||||
| "type": "object", | ||||||
| "description": "Environment variables for the MCP server", | ||||||
| "additionalProperties": { | ||||||
| "type": "string" | ||||||
| } | ||||||
| } | ||||||
| }, | ||||||
| "additionalProperties": false | ||||||
| } | ||||||
| }, | ||||||
| "additionalProperties": false | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| }, | ||||||
| "github-token": { | ||||||
|
|
@@ -3537,7 +3616,7 @@ | |||||
| }, | ||||||
| "description": "Toolsets to enable" | ||||||
| }, | ||||||
| "url": { | ||||||
| "id": { | ||||||
|
||||||
| "id": { | |
| "url": { |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,8 +17,7 @@ var orchestratorToolsLog = logger.New("workflow:compiler_orchestrator_tools") | |
| type toolsProcessingResult struct { | ||
| tools map[string]any | ||
| runtimes map[string]any | ||
| plugins []string | ||
| pluginsToken string | ||
| pluginInfo *PluginInfo // Consolidated plugin information | ||
| toolsTimeout int | ||
| toolsStartupTimeout int | ||
| markdownContent string | ||
|
|
@@ -140,13 +139,20 @@ func (c *Compiler) processToolsAndMarkdown(result *parser.FrontmatterResult, cle | |
| } | ||
|
|
||
| // Extract plugins from frontmatter | ||
| plugins, pluginsToken := extractPluginsFromFrontmatter(result.Frontmatter) | ||
| if len(plugins) > 0 { | ||
| orchestratorToolsLog.Printf("Extracted %d plugins from frontmatter (custom_token=%v)", len(plugins), pluginsToken != "") | ||
| pluginInfo := extractPluginsFromFrontmatter(result.Frontmatter) | ||
| if pluginInfo != nil && len(pluginInfo.Plugins) > 0 { | ||
| orchestratorToolsLog.Printf("Extracted %d plugins from frontmatter (custom_token=%v, mcp_configs=%d)", | ||
| len(pluginInfo.Plugins), pluginInfo.CustomToken != "", len(pluginInfo.MCPConfigs)) | ||
| } | ||
|
|
||
| // Merge plugins from imports with top-level plugins | ||
| if len(importsResult.MergedPlugins) > 0 { | ||
| if pluginInfo == nil { | ||
| pluginInfo = &PluginInfo{ | ||
| MCPConfigs: make(map[string]*PluginMCPConfig), | ||
| } | ||
|
Comment on lines
149
to
+153
|
||
| } | ||
|
|
||
| orchestratorToolsLog.Printf("Merging %d plugins from imports", len(importsResult.MergedPlugins)) | ||
| // Create a set to track unique plugins | ||
| pluginsSet := make(map[string]bool) | ||
|
|
@@ -157,7 +163,7 @@ func (c *Compiler) processToolsAndMarkdown(result *parser.FrontmatterResult, cle | |
| } | ||
|
|
||
| // Add top-level plugins (these override/supplement imports) | ||
| for _, plugin := range plugins { | ||
| for _, plugin := range pluginInfo.Plugins { | ||
| pluginsSet[plugin] = true | ||
| } | ||
|
|
||
|
|
@@ -169,9 +175,9 @@ func (c *Compiler) processToolsAndMarkdown(result *parser.FrontmatterResult, cle | |
|
|
||
| // Sort for deterministic output | ||
| sort.Strings(mergedPlugins) | ||
| plugins = mergedPlugins | ||
| pluginInfo.Plugins = mergedPlugins | ||
|
|
||
| orchestratorToolsLog.Printf("Merged plugins: %d total unique plugins", len(plugins)) | ||
| orchestratorToolsLog.Printf("Merged plugins: %d total unique plugins", len(pluginInfo.Plugins)) | ||
| } | ||
|
|
||
| // Add MCP fetch server if needed (when web-fetch is requested but engine doesn't support it) | ||
|
|
@@ -292,8 +298,7 @@ func (c *Compiler) processToolsAndMarkdown(result *parser.FrontmatterResult, cle | |
| return &toolsProcessingResult{ | ||
| tools: tools, | ||
| runtimes: runtimes, | ||
| plugins: plugins, | ||
| pluginsToken: pluginsToken, | ||
| pluginInfo: pluginInfo, | ||
| toolsTimeout: toolsTimeout, | ||
| toolsStartupTimeout: toolsStartupTimeout, | ||
| markdownContent: markdownContent, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plugin section docs still refer to plugin objects having
url, but the implementation/schema useid. Also the docs currently say "Array items: undefined", which makes the reference unclear. Please update this section to document the actual shape (string item or{ id, mcp: { env } }).See below for a potential fix: