Skip to content

Commit 9ea73c6

Browse files
authored
Add Serena as built-in MCP tool for listing and inspection (#7055)
1 parent 26f1ee1 commit 9ea73c6

5 files changed

Lines changed: 66 additions & 29 deletions

File tree

.github/workflows/agent-performance-analyzer.lock.yml

Lines changed: 3 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/campaign-manager.lock.yml

Lines changed: 3 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/workflow-health-manager.lock.yml

Lines changed: 3 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cli/mcp_list_tools.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ The command will:
206206
}
207207

208208
// commonMCPServerNames contains commonly used MCP server names for shell completion
209-
var commonMCPServerNames = []string{"github", "playwright", "tavily", "safe-outputs"}
209+
var commonMCPServerNames = []string{"github", "playwright", "serena", "tavily", "safe-outputs"}
210210

211211
// completeMCPListToolsArgs provides completion for mcp list-tools command arguments
212212
func completeMCPListToolsArgs(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

pkg/parser/mcp.go

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
199199
if hasTools {
200200
if tools, ok := toolsSection.(map[string]any); ok {
201201
for toolName, toolValue := range tools {
202-
// Only handle built-in MCP tools (github and playwright)
203-
if toolName == "github" || toolName == "playwright" {
202+
// Only handle built-in MCP tools (github, playwright, and serena)
203+
if toolName == "github" || toolName == "playwright" || toolName == "serena" {
204204
config, err := processBuiltinMCPTool(toolName, toolValue, serverFilter)
205205
if err != nil {
206206
return nil, err
@@ -227,8 +227,8 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
227227
if hasTools {
228228
if tools, ok := toolsSection.(map[string]any); ok {
229229
for toolName, toolValue := range tools {
230-
// Only handle built-in MCP tools (github and playwright)
231-
if toolName == "github" || toolName == "playwright" {
230+
// Only handle built-in MCP tools (github, playwright, and serena)
231+
if toolName == "github" || toolName == "playwright" || toolName == "serena" {
232232
config, err := processBuiltinMCPTool(toolName, toolValue, serverFilter)
233233
if err != nil {
234234
return nil, err
@@ -268,7 +268,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
268268
return configs, nil
269269
}
270270

271-
// processBuiltinMCPTool handles built-in MCP tools (github and playwright)
271+
// processBuiltinMCPTool handles built-in MCP tools (github, playwright, and serena)
272272
func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string) (*MCPServerConfig, error) {
273273
// Apply server filter if specified
274274
if serverFilter != "" && !strings.Contains(strings.ToLower(toolName), strings.ToLower(serverFilter)) {
@@ -478,6 +478,57 @@ func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string)
478478
config.Env["PLAYWRIGHT_BLOCK_ALL_DOMAINS"] = "true"
479479
}
480480

481+
return &config, nil
482+
} else if toolName == "serena" {
483+
// Handle Serena MCP server - uses uvx to install and run from GitHub
484+
config := MCPServerConfig{
485+
Name: "serena",
486+
Type: "stdio",
487+
Command: "uvx",
488+
Args: []string{
489+
"--from", "git+https://github.com/oraios/serena",
490+
"serena", "start-mcp-server",
491+
"--context", "codex",
492+
"--project", "${GITHUB_WORKSPACE}",
493+
},
494+
Env: make(map[string]string),
495+
}
496+
497+
// Check for custom Serena configuration
498+
if toolConfig, ok := toolValue.(map[string]any); ok {
499+
// Handle custom args - these would be appended to the default args
500+
if argsValue, exists := toolConfig["args"]; exists {
501+
// Handle []any format
502+
if argsSlice, ok := argsValue.([]any); ok {
503+
for _, arg := range argsSlice {
504+
if argStr, ok := arg.(string); ok {
505+
config.Args = append(config.Args, argStr)
506+
}
507+
}
508+
}
509+
// Handle []string format
510+
if argsSlice, ok := argsValue.([]string); ok {
511+
config.Args = append(config.Args, argsSlice...)
512+
}
513+
}
514+
515+
// Handle allowed tools configuration
516+
if allowed, hasAllowed := toolConfig["allowed"]; hasAllowed {
517+
if allowedSlice, ok := allowed.([]any); ok {
518+
for _, item := range allowedSlice {
519+
if str, ok := item.(string); ok {
520+
config.Allowed = append(config.Allowed, str)
521+
}
522+
}
523+
}
524+
}
525+
}
526+
527+
// If no specific allowed tools are configured, allow all tools (*)
528+
if len(config.Allowed) == 0 {
529+
config.Allowed = []string{"*"}
530+
}
531+
481532
return &config, nil
482533
}
483534

0 commit comments

Comments
 (0)