deepseek-1.x-dev/src/Controller/McpServerController.php
src/Controller/McpServerController.php
<?php
namespace Drupal\deepseek\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\deepseek\McpPluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* {@inheritDoc}
*/
class McpServerController extends ControllerBase {
/**
* {@inheritDoc}
*/
public function __construct(protected McpPluginManager $pluginManager) {
}
/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('plugin.manager.mcp_tool')
);
}
/**
* Request handler for mcp server and tools.
*/
public function handleRequest(Request $request) {
if ($request->isMethod('GET')) {
return $this->listSse();
}
elseif ($request->isMethod('POST')) {
if (!$this->currentUser()->hasPermission('access mcp server')) {
return new JsonResponse(['error' => 'Access denied'], Response::HTTP_FORBIDDEN);
}
$data = json_decode($request->getContent(), TRUE);
return $this->tool($data);
}
return new JsonResponse(['error' => 'Method not allowed'], Response::HTTP_METHOD_NOT_ALLOWED);
}
/**
* Returns the list of MCP tools.
*/
public function tool(array $params) {
$tool_name = $params['tool_name'] ?? '';
if (empty($tool_name)) {
return new JsonResponse([
'tool_name' => $tool_name,
'status' => 'error',
'error' => [
'code' => 400,
'message' => 'Missing tool_name parameter',
],
], 400);
}
$response = new StreamedResponse();
$response->headers->set('Content-Type', 'text/event-stream');
$response->headers->set('Cache-Control', 'no-cache');
$response->headers->set('Connection', 'keep-alive');
$response->headers->set('X-Accel-Buffering', 'no');
$response->setCallback(function () use ($tool_name, $params) {
try {
$result = $this->pluginManager->executeTool($tool_name, $params['parameters'] ?? []);
$data = [
'type' => 'tool_response',
'tool_name' => $tool_name,
'status' => 'success',
'data' => $result,
];
echo "data: " . json_encode($data) . "\n\n";
}
catch (\Exception $e) {
$error = [
'type' => 'tool_response',
'tool_name' => $tool_name,
'status' => 'error',
'error' => [
'code' => 500,
'message' => $e->getMessage(),
],
];
echo "data: " . json_encode($error) . "\n\n";
}
ob_flush();
flush();
});
return $response;
}
/**
* Streams SSE response with real-time list.
*/
protected function listSse() {
$response = new StreamedResponse();
$response->headers->set('Content-Type', 'text/event-stream');
$response->headers->set('Cache-Control', 'no-cache');
$response->headers->set('Connection', 'keep-alive');
$response->headers->set('X-Accel-Buffering', 'no');
$response->setCallback(function () {
$data = [
'type' => 'plugin_list',
'plugins' => $this->pluginManager->getToolsList(),
'name' => implode(' ', [
$this->config('system.site')->get('name'),
$this->t('Model context protocol server'),
]),
'version' => '1.0.0',
'description' => $this->t("MCP server is deployed on Drupal platform"),
];
echo "data: " . json_encode($data) . "\n\n";
ob_flush();
flush();
});
return $response;
}
}
