Skip to content

Commit cd23489

Browse files
claude[bot]kargnas
andcommitted
feat: add simple info page for GET /mcp requests with override capability
- Default GET requests now return a simple info page (HTML or JSON based on Accept header) - Added 'get_handler' config option to allow custom handler override - Info page shows minimal server information for security - Maintains backward compatibility while providing better user experience Co-authored-by: Sangrak Choi <kargnas@users.noreply.github.com>
1 parent bff4ba9 commit cd23489

File tree

2 files changed

+122
-9
lines changed

2 files changed

+122
-9
lines changed

config/mcp-server.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,44 @@
202202
*/
203203
'domain' => null,
204204

205+
/*
206+
|--------------------------------------------------------------------------
207+
| GET Request Handler Override
208+
|--------------------------------------------------------------------------
209+
|
210+
| Customize the response when making a GET request to the MCP endpoint.
211+
| By default, a simple info page is returned showing server details.
212+
|
213+
| Options:
214+
| - null: Use the default info page (recommended)
215+
| - string: Fully qualified class name of a custom handler
216+
|
217+
| Custom Handler Requirements:
218+
| - Must have a public 'handle(Request $request)' method
219+
| - Should return a valid Laravel response
220+
|
221+
| Example:
222+
| 'get_handler' => null, // Default info page
223+
| 'get_handler' => App\Http\Handlers\CustomMcpInfoHandler::class, // Custom handler
224+
|
225+
| Example Custom Handler:
226+
| ```php
227+
| namespace App\Http\Handlers;
228+
|
229+
| use Illuminate\Http\Request;
230+
|
231+
| class CustomMcpInfoHandler
232+
| {
233+
| public function handle(Request $request)
234+
| {
235+
| return view('mcp.info', ['tools' => $this->getAvailableTools()]);
236+
| }
237+
| }
238+
| ```
239+
|
240+
*/
241+
'get_handler' => null,
242+
205243
/*
206244
|--------------------------------------------------------------------------
207245
| SSE Adapter Configuration (Legacy Provider Only)

src/Http/Controllers/StreamableHttpController.php

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,30 @@ class StreamableHttpController
1313
{
1414
public function getHandle(Request $request)
1515
{
16-
$server = app(MCPServer::class);
17-
set_time_limit(0);
16+
// Check if custom handler is configured
17+
$customHandler = config('mcp-server.get_handler');
18+
if ($customHandler && class_exists($customHandler)) {
19+
$handler = app($customHandler);
20+
if (method_exists($handler, 'handle')) {
21+
return $handler->handle($request);
22+
}
23+
}
1824

19-
$mcpSessionId = $request->headers->get('mcp-session-id');
20-
$lastEventId = $request->headers->get('last-event-id');
25+
// Return default info page
26+
$serverInfo = config('mcp-server.server', ['name' => 'MCP Server', 'version' => '1.0.0']);
27+
$response = [
28+
'mcp_version' => '0.1.0',
29+
'server_info' => $serverInfo,
30+
'protocol' => 'streamable_http',
31+
];
2132

22-
// todo:: SSE connection configuration restricted
33+
// Check Accept header to determine response format
34+
if ($request->accepts('text/html')) {
35+
$html = $this->generateInfoHtml($serverInfo);
36+
return response($html, 200)->header('Content-Type', 'text/html');
37+
}
2338

24-
return response()->json([
25-
'jsonrpc' => '2.0',
26-
'error' => 'Method Not Allowed',
27-
], 405);
39+
return response()->json($response, 200);
2840
}
2941

3042
public function postHandle(Request $request)
@@ -54,4 +66,67 @@ public function postHandle(Request $request)
5466
'error' => 'Bad Request: invalid session ID or method.',
5567
], 400);
5668
}
69+
70+
/**
71+
* Generate simple HTML info page
72+
*/
73+
private function generateInfoHtml(array $serverInfo): string
74+
{
75+
$name = htmlspecialchars($serverInfo['name'] ?? 'MCP Server');
76+
$version = htmlspecialchars($serverInfo['version'] ?? '1.0.0');
77+
78+
return <<<HTML
79+
<!DOCTYPE html>
80+
<html lang="en">
81+
<head>
82+
<meta charset="UTF-8">
83+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
84+
<title>{$name}</title>
85+
<style>
86+
body {
87+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
88+
max-width: 600px;
89+
margin: 50px auto;
90+
padding: 20px;
91+
color: #333;
92+
}
93+
h1 {
94+
color: #2c3e50;
95+
border-bottom: 2px solid #3498db;
96+
padding-bottom: 10px;
97+
}
98+
.info {
99+
background: #f8f9fa;
100+
padding: 15px;
101+
border-radius: 5px;
102+
margin: 20px 0;
103+
}
104+
.info p {
105+
margin: 5px 0;
106+
}
107+
.info strong {
108+
color: #2c3e50;
109+
}
110+
.footer {
111+
margin-top: 40px;
112+
color: #7f8c8d;
113+
font-size: 0.9em;
114+
}
115+
</style>
116+
</head>
117+
<body>
118+
<h1>{$name}</h1>
119+
<div class="info">
120+
<p><strong>Version:</strong> {$version}</p>
121+
<p><strong>Protocol:</strong> Model Context Protocol</p>
122+
<p><strong>Transport:</strong> Streamable HTTP</p>
123+
</div>
124+
<div class="footer">
125+
<p>This is an MCP (Model Context Protocol) server endpoint.</p>
126+
<p>Use an MCP-compatible client to interact with this server.</p>
127+
</div>
128+
</body>
129+
</html>
130+
HTML;
131+
}
57132
}

0 commit comments

Comments
 (0)