Files
erp_naurua/public/api/erp-lager-mcp.php
T

89 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../../modules/shared/db.php';
require_once __DIR__ . '/../../modules/erp/lager/mcp.php';
final class ErpLagerMcpJsonRpcException extends RuntimeException
{
public function __construct(private int $rpcCode, string $message, ?Throwable $previous = null)
{
parent::__construct($message, 0, $previous);
}
public function rpcCode(): int
{
return $this->rpcCode;
}
}
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
$env = expand_env_values(parse_env_file(__DIR__ . '/../../.env'));
$request = [];
try {
erp_lager_mcp_authorize($env);
$pdo = connect_database($env);
$body = file_get_contents('php://input');
$request = json_decode($body === false ? '' : $body, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($request) || ($request['jsonrpc'] ?? '') !== '2.0') {
throw new InvalidArgumentException('Ungültige JSON-RPC-Anfrage.');
}
if (array_key_exists('params', $request) && !is_array($request['params'])) {
throw new ErpLagerMcpJsonRpcException(-32602, 'Parameter müssen als Objekt oder Array übergeben werden.');
}
$id = $request['id'] ?? null;
$method = (string) ($request['method'] ?? '');
$params = is_array($request['params'] ?? null) ? $request['params'] : [];
if ($method === 'initialize') {
$result = [
'protocolVersion' => (string) ($params['protocolVersion'] ?? '2025-03-26'),
'capabilities' => ['tools' => ['listChanged' => false]],
'serverInfo' => ['name' => 'naurua-erp-lager', 'version' => '1.0.0'],
];
} elseif ($method === 'notifications/initialized') {
http_response_code(202);
exit;
} elseif ($method === 'tools/list') {
$result = ['tools' => erp_lager_mcp_tools()];
} elseif ($method === 'tools/call') {
$tool = (string) ($params['name'] ?? '');
$arguments = is_array($params['arguments'] ?? null) ? $params['arguments'] : [];
if (array_key_exists('arguments', $params) && !is_array($params['arguments'])) {
throw new ErpLagerMcpJsonRpcException(-32602, 'Tool-Argumente müssen als Objekt übergeben werden.');
}
try {
$result = [
'content' => [[
'type' => 'text',
'text' => json_encode(erp_lager_mcp_call($pdo, $tool, $arguments), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR),
]],
'isError' => false,
];
} catch (InvalidArgumentException $e) {
throw new ErpLagerMcpJsonRpcException(-32602, $e->getMessage(), $e);
}
} else {
throw new ErpLagerMcpJsonRpcException(-32601, 'Unbekannte JSON-RPC-Methode: ' . $method);
}
echo json_encode(['jsonrpc' => '2.0', 'id' => $id, 'result' => $result], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
} catch (Throwable $e) {
$isAuthError = $e instanceof RuntimeException && str_contains($e->getMessage(), 'Token');
$isJsonRpcError = $e instanceof ErpLagerMcpJsonRpcException;
http_response_code($isJsonRpcError ? 200 : ($isAuthError ? 401 : 400));
echo json_encode([
'jsonrpc' => '2.0',
'id' => $request['id'] ?? null,
'error' => [
'code' => $isJsonRpcError ? $e->rpcCode() : -32600,
'message' => $e->getMessage(),
],
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}