2
2
3
3
namespace Kirschbaum \Loop \Commands ;
4
4
5
+ use Exception ;
5
6
use Illuminate \Console \Command ;
6
7
use Illuminate \Support \Facades \Auth ;
7
8
use Kirschbaum \Loop \Enums \ErrorCode ;
@@ -24,75 +25,30 @@ class LoopMcpServerStartCommand extends Command
24
25
25
26
protected $ description = 'Run the Laravel Loop MCP server ' ;
26
27
28
+ protected McpHandler $ mcpHandler ;
29
+
30
+ protected ReadableResourceStream $ stdin ;
31
+
32
+ protected WritableResourceStream $ stdout ;
33
+
27
34
public function handle (McpHandler $ mcpHandler ): int
28
35
{
36
+ $ this ->mcpHandler = $ mcpHandler ;
37
+
29
38
if ($ this ->option ('debug ' )) {
30
39
$ this ->debug ('Starting Laravel Loop MCP server (STDIO transport) ' );
31
40
}
32
41
33
42
if ($ this ->option ('user-id ' )) {
34
- /** @var string|null */
35
- $ authGuard = $ this ->option ('auth-guard ' ) ?? config ('auth.defaults.guard ' );
36
- $ userModel = $ this ->option ('user-model ' ) ?? 'App \\Models \\User ' ;
37
- $ user = $ userModel ::find ($ this ->option ('user-id ' ));
38
-
39
- if (! $ user ) {
40
- $ this ->error (sprintf ('User with ID %s not found. Model used: %s ' , $ this ->option ('user-id ' ), $ userModel ));
41
-
42
- return Command::FAILURE ;
43
- }
44
-
45
- Auth::guard ($ authGuard )->login ($ user );
46
-
47
- if ($ this ->option ('debug ' )) {
48
- $ this ->debug (sprintf ('Authenticated with user ID %s ' , $ this ->option ('user-id ' )));
49
- }
43
+ $ this ->authenticateUser ();
50
44
}
51
45
52
46
$ loop = Loop::get ();
53
- $ stdin = new ReadableResourceStream (STDIN , $ loop );
54
- $ stdout = new WritableResourceStream (STDOUT , $ loop );
55
-
56
- $ stdin ->on ('data ' , function ($ data ) use ($ stdout , $ mcpHandler ) {
57
- if ($ this ->option ('debug ' )) {
58
- $ this ->debug ('Received data: ' .$ data );
59
- }
60
-
61
- foreach (explode ("\n" , trim ($ data )) as $ line ) {
62
- if (! json_validate ($ line )) {
63
- if ($ this ->option ('debug ' )) {
64
- $ this ->debug ('Invalid line: ' .$ line );
65
- }
66
-
67
- continue ;
68
- }
69
-
70
- try {
71
- $ message = (array ) json_decode ($ line , true );
72
- $ response = $ mcpHandler ->handle ($ message );
73
-
74
- if ($ this ->option ('debug ' )) {
75
- $ this ->debug ('Response: ' .json_encode ($ response ));
76
- }
77
-
78
- if (isset ($ message ['id ' ])) {
79
- $ stdout ->write (json_encode ($ response ).PHP_EOL );
80
- }
81
- } catch (\Throwable $ e ) {
82
- $ this ->debug ('Error processing message: ' .$ e ->getMessage ());
83
-
84
- $ response = $ mcpHandler ->formatErrorResponse (
85
- $ message ['id ' ] ?? '' ,
86
- ErrorCode::INTERNAL_ERROR ,
87
- $ e ->getMessage ()
88
- );
89
-
90
- $ stdout ->write (json_encode ($ response ).PHP_EOL );
91
-
92
- report ($ e );
93
- }
94
- }
47
+ $ this ->stdin = new ReadableResourceStream (STDIN , $ loop );
48
+ $ this ->stdout = new WritableResourceStream (STDOUT , $ loop );
95
49
50
+ $ this ->stdin ->on ('data ' , function ($ data ) {
51
+ $ this ->processData ($ data );
96
52
});
97
53
98
54
if ($ this ->option ('debug ' )) {
@@ -135,6 +91,66 @@ public function handle(McpHandler $mcpHandler): int
135
91
return Command::SUCCESS ;
136
92
}
137
93
94
+ protected function processData (string $ data ): void
95
+ {
96
+ if ($ this ->option ('debug ' )) {
97
+ $ this ->debug ('Received data: ' .$ data );
98
+ }
99
+
100
+ foreach (explode ("\n" , trim ($ data )) as $ line ) {
101
+ if (! json_validate ($ line )) {
102
+ if ($ this ->option ('debug ' )) {
103
+ $ this ->debug ('Invalid line: ' .$ line );
104
+ }
105
+
106
+ continue ;
107
+ }
108
+
109
+ try {
110
+ $ message = (array ) json_decode ($ line , true );
111
+ $ response = $ this ->mcpHandler ->handle ($ message );
112
+
113
+ if ($ this ->option ('debug ' )) {
114
+ $ this ->debug ('Response: ' .json_encode ($ response ));
115
+ }
116
+
117
+ if (isset ($ message ['id ' ])) {
118
+ $ this ->stdout ->write (json_encode ($ response ).PHP_EOL );
119
+ }
120
+ } catch (\Throwable $ e ) {
121
+ $ this ->debug ('Error processing message: ' .$ e ->getMessage ());
122
+
123
+ $ response = $ this ->mcpHandler ->formatErrorResponse (
124
+ $ message ['id ' ] ?? '' ,
125
+ ErrorCode::INTERNAL_ERROR ,
126
+ $ e ->getMessage ()
127
+ );
128
+
129
+ $ this ->stdout ->write (json_encode ($ response ).PHP_EOL );
130
+
131
+ report ($ e );
132
+ }
133
+ }
134
+ }
135
+
136
+ protected function authenticateUser (): void
137
+ {
138
+ /** @var string|null */
139
+ $ authGuard = $ this ->option ('auth-guard ' ) ?? config ('auth.defaults.guard ' );
140
+ $ userModel = $ this ->option ('user-model ' ) ?? 'App \\Models \\User ' ;
141
+ $ user = $ userModel ::find ($ this ->option ('user-id ' ));
142
+
143
+ if (! $ user ) {
144
+ throw new Exception (sprintf ('User with ID %s not found. Model used: %s ' , $ this ->option ('user-id ' ), $ userModel ));
145
+ }
146
+
147
+ Auth::guard ($ authGuard )->login ($ user );
148
+
149
+ if ($ this ->option ('debug ' )) {
150
+ $ this ->debug (sprintf ('Authenticated with user ID %s ' , $ this ->option ('user-id ' )));
151
+ }
152
+ }
153
+
138
154
protected function debug (string $ message ): void
139
155
{
140
156
0 commit comments