@@ -33,7 +33,8 @@ import (
33
33
34
34
type MCP struct {
35
35
server * server.MCPServer
36
- app * Application
36
+ apps map [string ]* Application
37
+ appArgs map [string ][]string
37
38
projectDir string
38
39
}
39
40
@@ -61,6 +62,7 @@ var excludedOptions = map[string]bool{
61
62
func NewServer (projectDir string ) (* MCP , error ) {
62
63
mcp := & MCP {
63
64
projectDir : projectDir ,
65
+ apps : map [string ]* Application {},
64
66
}
65
67
66
68
mcp .server = server .NewMCPServer (
@@ -70,21 +72,36 @@ func NewServer(projectDir string) (*MCP, error) {
70
72
server .WithResourceCapabilities (true , true ),
71
73
)
72
74
73
- var err error
74
- mcp .app , err = NewApp (projectDir )
75
- if err != nil {
76
- return nil , err
75
+ mcp .appArgs = map [string ][]string {
76
+ "symfony" : {"php" , "bin/console" },
77
+ // "cloud": {"run", "upsun"},
77
78
}
78
- for _ , command := range mcp .app .Commands {
79
- if _ , ok := excludedCommands [command .Name ]; ok {
80
- continue
81
- }
82
- if command .Hidden {
83
- continue
84
- }
85
- if err := mcp .addTool (command ); err != nil {
79
+
80
+ e := & php.Executor {
81
+ Dir : projectDir ,
82
+ BinName : "php" ,
83
+ }
84
+ if composerPath , err := e .FindComposer ("" ); err == nil {
85
+ mcp .appArgs ["composer" ] = []string {"php" , composerPath }
86
+ }
87
+
88
+ for name , args := range mcp .appArgs {
89
+ var err error
90
+ mcp .apps [name ], err = NewApp (projectDir , args )
91
+ if err != nil {
86
92
return nil , err
87
93
}
94
+ for _ , command := range mcp .apps [name ].Commands {
95
+ if _ , ok := excludedCommands [command .Name ]; ok {
96
+ continue
97
+ }
98
+ if command .Hidden {
99
+ continue
100
+ }
101
+ if err := mcp .addTool (name , command ); err != nil {
102
+ return nil , err
103
+ }
104
+ }
88
105
}
89
106
90
107
return mcp , nil
@@ -94,7 +111,7 @@ func (p *MCP) Start() error {
94
111
return server .ServeStdio (p .server )
95
112
}
96
113
97
- func (p * MCP ) addTool (cmd command ) error {
114
+ func (p * MCP ) addTool (appName string , cmd command ) error {
98
115
toolOptions := []mcp.ToolOption {}
99
116
toolOptions = append (toolOptions , mcp .WithDescription (cmd .Description + "\n \n " + cmd .Help ))
100
117
for name , arg := range cmd .Definition .Arguments {
@@ -120,7 +137,7 @@ func (p *MCP) addTool(cmd command) error {
120
137
}
121
138
}
122
139
123
- toolName := strings .ReplaceAll (cmd .Name , ":" , "-" )
140
+ toolName := appName + "--" + strings .ReplaceAll (cmd .Name , ":" , "-" )
124
141
regexp := regexp .MustCompile (`^[a-zA-Z0-9_-]{1,64}$` )
125
142
if ! regexp .MatchString (toolName ) {
126
143
return fmt .Errorf ("invalid command name: %s" , cmd .Name )
@@ -159,14 +176,14 @@ func (p *MCP) addTool(cmd command) error {
159
176
}
160
177
executorArgs = append (executorArgs , "--no-ansi" )
161
178
executorArgs = append (executorArgs , "--no-interaction" )
162
- e , err := php .SymfonyConsoleExecutor (p .projectDir , executorArgs )
163
- if err != nil {
164
- return nil , err
165
- }
166
- e .Dir = p .projectDir
167
179
var buf bytes.Buffer
168
- e .Stdout = & buf
169
- e .Stderr = & buf
180
+ e := & php.Executor {
181
+ BinName : "php" ,
182
+ Dir : p .projectDir ,
183
+ Args : append (p .appArgs [appName ], executorArgs ... ),
184
+ Stdout : & buf ,
185
+ Stderr : & buf ,
186
+ }
170
187
if ret := e .Execute (false ); ret != 0 {
171
188
return mcp .NewToolResultError (fmt .Sprintf ("Error running %s (exit code: %d)\n %s" , strings .Join (executorArgs , " " ), ret , buf .String ())), nil
172
189
}
0 commit comments