-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMcpServerFactory.php
More file actions
128 lines (107 loc) · 4.12 KB
/
McpServerFactory.php
File metadata and controls
128 lines (107 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
declare(strict_types=1);
namespace Piwik\Plugins\McpServer;
use Matomo\Dependencies\McpServer\Mcp\Schema\ServerCapabilities;
use Matomo\Dependencies\McpServer\Mcp\Server;
use Matomo\Dependencies\McpServer\Mcp\Server\Handler\Request\CallToolHandler;
use Matomo\Dependencies\McpServer\Mcp\Capability\Registry;
use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\ReferenceHandler;
use Matomo\Dependencies\McpServer\Mcp\Server\Session\SessionStoreInterface;
use Piwik\Config;
use Piwik\Plugin\Manager;
use Piwik\Log\LoggerInterface;
use Piwik\Plugins\McpServer\Server\Handler\Request\ObservedCallToolHandler;
use Piwik\Plugins\McpServer\Support\Logging\ToolCallParameterFormatter;
use Psr\Container\ContainerInterface;
use Psr\Log\NullLogger;
final class McpServerFactory
{
private const DEFAULT_TOOL_CALL_LOG_LEVEL = 'DEBUG';
public function __construct(
private LoggerInterface $logger,
private SessionStoreInterface $sessionStore,
private ContainerInterface $container,
private ToolCallParameterFormatter $toolCallParameterFormatter
) {
}
public function createServer(): Server
{
$version = (string) Manager::getInstance()->getVersion('McpServer');
$registry = new Registry(logger: new NullLogger());
$builder = Server::builder()
->setServerInfo('Matomo MCP Server', $version)
->setLogger(new NullLogger())
->setRegistry($registry)
->setSession($this->sessionStore)
->setContainer($this->container)
->setDiscovery(__DIR__, ['McpTools'])
->setCapabilities(new ServerCapabilities(
tools: true,
// Use null to avoid advertising listChanged capabilities we don't implement.
toolsListChanged: null,
resources: false,
resourcesSubscribe: null,
resourcesListChanged: null,
prompts: false,
promptsListChanged: null,
logging: false,
completions: false,
));
if ($this->isToolCallLoggingEnabled()) {
$referenceHandler = new ReferenceHandler($this->container);
$callToolHandler = new CallToolHandler($registry, $referenceHandler, new NullLogger());
$builder->addRequestHandler(new ObservedCallToolHandler(
$callToolHandler,
$this->logger,
$this->toolCallParameterFormatter,
$this->isFullParameterLoggingEnabled(),
$this->resolveToolCallLogLevel()
));
}
return $builder->build();
}
private function isToolCallLoggingEnabled(): bool
{
$config = $this->getMcpServerConfig();
if (!array_key_exists('log_tool_calls', $config)) {
return false;
}
return $config['log_tool_calls'] == 1;
}
private function isFullParameterLoggingEnabled(): bool
{
$config = $this->getMcpServerConfig();
if (!array_key_exists('log_tool_call_parameters_full', $config)) {
return false;
}
return $config['log_tool_call_parameters_full'] == 1;
}
private function resolveToolCallLogLevel(): string
{
$config = $this->getMcpServerConfig();
$configuredLevel = $config['log_tool_call_level'] ?? null;
if (!is_scalar($configuredLevel)) {
return self::DEFAULT_TOOL_CALL_LOG_LEVEL;
}
$normalizedLevel = strtoupper(trim((string) $configuredLevel));
$validLevels = ['ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'VERBOSE'];
if (!in_array($normalizedLevel, $validLevels, true)) {
return self::DEFAULT_TOOL_CALL_LOG_LEVEL;
}
return $normalizedLevel;
}
/**
* @return array<string, mixed>
*/
private function getMcpServerConfig(): array
{
$config = Config::getInstance()->McpServer ?? [];
return is_array($config) ? $config : [];
}
}