Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.18% covered (success)
91.18%
31 / 34
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
RemoteMcpController
91.18% covered (success)
91.18%
31 / 34
50.00% covered (danger)
50.00%
1 / 2
3.01
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __invoke
90.91% covered (success)
90.91%
30 / 33
0.00% covered (danger)
0.00%
0 / 1
2.00
1<?php
2namespace Apie\McpServer\Controllers;
3
4use Apie\Core\ApieLib;
5use Apie\McpServer\Tool\ToolFactory;
6use Apie\McpServer\Tool\ToolRunner;
7use Mcp\Server\HttpServerRunner;
8use Mcp\Server\Server;
9use Mcp\Server\Transport\Http\HttpMessage;
10use Mcp\Server\Transport\Http\SessionStoreInterface;
11use Nyholm\Psr7\Response;
12use Nyholm\Psr7\Stream;
13use Psr\Http\Message\ServerRequestInterface;
14use Psr\Log\LoggerInterface;
15
16class RemoteMcpController
17{
18    public function __construct(
19        private readonly ToolFactory $toolFactory,
20        private readonly ToolRunner $toolRunner,
21        private readonly LoggerInterface $logger,
22        private readonly ?SessionStoreInterface $sessionStore = null
23    ) {
24    }
25    public function __invoke(ServerRequestInterface $request): Response
26    {
27        $server = new Server('apie-server');
28        $server->registerHandler('tools/list', function ($params) {
29            return $this->toolFactory->createList();
30        });
31        $server->registerHandler('tools/call', function ($params) use ($request) {
32            $name = $params->name;
33            $tool = $this->toolFactory->findByName($name);
34            return $this->toolRunner->run($tool, $params, $request);
35        });
36        // TODO: configurable options?
37        $httpOptions = [
38            'session_timeout' => 1800,
39            'max_queue_size' => 500,
40            'enable_sse' => false,
41            'shared_hosting' => true,
42            'server_header' => 'Apie-MCP-Server/' . ApieLib::VERSION,
43        ];
44        
45        $runner = new HttpServerRunner(
46            $server,
47            $server->createInitializationOptions(),
48            $httpOptions,
49            $this->logger,
50            $this->sessionStore
51        );
52        $message = new HttpMessage($request->getBody()->getContents());
53        $message->setMethod($request->getMethod());
54        foreach ($request->getHeaders() as $name => $values) {
55            $message->setHeader($name, implode(', ', $values));
56        }
57        $result = $runner->handleRequest($message);
58
59        return new Response(
60            $result->getStatusCode(),
61            $result->getHeaders(),
62            Stream::create($result->getBody())
63        );
64    }
65}