@@ -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 )
272272func 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