feat: add Do Better Norge MCP server — token system, runtime API, interactive setup page
- UserMcpTokens: per-user SHA256-hashed token mint/validate/revoke (Plus/Pro only) - DbnMcpRuntime: 19 MCP tools (search, ask, summarize, timeline, redact, translate, legal_analysis, korrespond, barnevernet_analyze, advocate_brief, deep_research, discrepancy_find, transcribe_audio, corpus_stats, list_documents, get_document, citation_graph, case_workbench_plan, save_to_case) - api/mcp/user/: session/tools/invoke HTTP endpoints with Bearer token auth - api/mcp-tokens.php: token create/revoke/list REST API - mcp.php: interactive setup page with token management, 5-client config tabs, auto-fill on token creation, tool catalog grid, privacy notice - account.php: simplified MCP section with link to mcp.php - nav.php: MCP nav link - .htaccess: Authorization header passthrough, MCP route rewrite, CORS Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../includes/bootstrap.php';
|
||||
require_once __DIR__ . '/../includes/UserMcpTokens.php';
|
||||
|
||||
dbnToolsRequireAuth();
|
||||
|
||||
if (!dbnToolsIsFreeTier()) {
|
||||
dbnToolsError('DBN user MCP tokens are available for Do Better Norge member accounts only.', 403, 'sso_only');
|
||||
}
|
||||
|
||||
$userId = (int)($_SESSION['dbn_tools_sso_uid'] ?? 0);
|
||||
if (!UserMcpTokens::isUserEligible($userId)) {
|
||||
dbnToolsError('MCP access requires a Plus or Pro plan.', 403, 'not_paid');
|
||||
}
|
||||
|
||||
$method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');
|
||||
|
||||
if ($method === 'GET') {
|
||||
dbnToolsRespond([
|
||||
'ok' => true,
|
||||
'tokens' => UserMcpTokens::listForUser($userId),
|
||||
'config' => [
|
||||
'stdio_command' => 'npx',
|
||||
'stdio_args' => ['-y', '@bluenotelogic/mcp', 'dobetternorge-mcp', '--stdio'],
|
||||
'hosted_url' => 'https://mcp.dobetternorge.no/mcp',
|
||||
'env_var' => 'DBN_MCP_TOKEN',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
if ($method !== 'POST') {
|
||||
dbnToolsError('Method not allowed.', 405, 'method_not_allowed');
|
||||
}
|
||||
|
||||
$input = dbnToolsJsonInput(4000);
|
||||
$action = (string)($input['action'] ?? 'create');
|
||||
|
||||
if ($action === 'create') {
|
||||
$created = UserMcpTokens::createForUser($userId, (string)($input['name'] ?? 'DBN MCP'));
|
||||
dbnToolsRespond(['ok' => true, 'token' => $created]);
|
||||
}
|
||||
|
||||
if ($action === 'revoke') {
|
||||
$tokenId = (int)($input['id'] ?? 0);
|
||||
if ($tokenId <= 0) {
|
||||
dbnToolsError('Token id is required.', 422, 'missing_id');
|
||||
}
|
||||
dbnToolsRespond(['ok' => true, 'revoked' => UserMcpTokens::revokeForUser($userId, $tokenId)]);
|
||||
}
|
||||
|
||||
dbnToolsError('Unknown action.', 400, 'bad_action');
|
||||
Reference in New Issue
Block a user