opalserve 0.1.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -115
- package/assets/logo.svg +51 -0
- package/dist/auth/api-keys.d.ts +7 -0
- package/dist/auth/api-keys.d.ts.map +1 -0
- package/dist/auth/api-keys.js +12 -0
- package/dist/auth/api-keys.js.map +1 -0
- package/dist/auth/index.d.ts +4 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +4 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +11 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +46 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/passwords.d.ts +3 -0
- package/dist/auth/passwords.d.ts.map +1 -0
- package/dist/auth/passwords.js +33 -0
- package/dist/auth/passwords.js.map +1 -0
- package/dist/cli/commands/admin.d.ts +13 -0
- package/dist/cli/commands/admin.d.ts.map +1 -0
- package/dist/cli/commands/admin.js +261 -0
- package/dist/cli/commands/admin.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +4 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +77 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/context.d.ts +5 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +190 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/health.d.ts +4 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +36 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +81 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/server.d.ts +10 -0
- package/dist/cli/commands/server.d.ts.map +1 -0
- package/dist/cli/commands/server.js +108 -0
- package/dist/cli/commands/server.js.map +1 -0
- package/dist/cli/commands/start.d.ts +6 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +63 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +21 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +2 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +58 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/tools.d.ts +8 -0
- package/dist/cli/commands/tools.d.ts.map +1 -0
- package/dist/cli/commands/tools.js +28 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +156 -30
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ui/banner.d.ts +8 -0
- package/dist/cli/ui/banner.d.ts.map +1 -0
- package/dist/cli/ui/banner.js +54 -0
- package/dist/cli/ui/banner.js.map +1 -0
- package/dist/cli/ui/prompts.d.ts +11 -0
- package/dist/cli/ui/prompts.d.ts.map +1 -0
- package/dist/cli/ui/prompts.js +74 -0
- package/dist/cli/ui/prompts.js.map +1 -0
- package/dist/cli/ui/table.d.ts +5 -0
- package/dist/cli/ui/table.d.ts.map +1 -0
- package/dist/cli/ui/table.js +103 -0
- package/dist/cli/ui/table.js.map +1 -0
- package/dist/config/credentials.d.ts +10 -0
- package/dist/config/credentials.d.ts.map +1 -0
- package/dist/config/credentials.js +33 -0
- package/dist/config/credentials.js.map +1 -0
- package/dist/config/defaults.d.ts +5 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +20 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/loader.d.ts +4 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +57 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +2 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +2 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +5 -0
- package/dist/constants.js.map +1 -0
- package/dist/context/chunker.d.ts +2 -0
- package/dist/context/chunker.d.ts.map +1 -0
- package/dist/context/chunker.js +81 -0
- package/dist/context/chunker.js.map +1 -0
- package/dist/context/index.d.ts +26 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +97 -0
- package/dist/context/index.js.map +1 -0
- package/dist/core/discovery.d.ts +17 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +31 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/proxy.d.ts +14 -0
- package/dist/core/proxy.d.ts.map +1 -0
- package/dist/core/proxy.js +36 -0
- package/dist/core/proxy.js.map +1 -0
- package/dist/core/registry.d.ts +30 -31
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +92 -234
- package/dist/core/registry.js.map +1 -1
- package/dist/core/secrets.d.ts +4 -0
- package/dist/core/secrets.d.ts.map +1 -0
- package/dist/core/secrets.js +40 -0
- package/dist/core/secrets.js.map +1 -0
- package/dist/core/server-manager.d.ts +18 -0
- package/dist/core/server-manager.d.ts.map +1 -0
- package/dist/core/server-manager.js +120 -0
- package/dist/core/server-manager.js.map +1 -0
- package/dist/dashboard/assets/index-BNOtcUPs.js +257 -0
- package/dist/dashboard/assets/index-Duwp34GW.css +1 -0
- package/dist/dashboard/index.html +14 -0
- package/dist/index.d.ts +22 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -9
- package/dist/index.js.map +1 -1
- package/dist/integrations/github.d.ts +5 -0
- package/dist/integrations/github.d.ts.map +1 -0
- package/dist/integrations/github.js +63 -0
- package/dist/integrations/github.js.map +1 -0
- package/dist/integrations/slack.d.ts +21 -0
- package/dist/integrations/slack.d.ts.map +1 -0
- package/dist/integrations/slack.js +61 -0
- package/dist/integrations/slack.js.map +1 -0
- package/dist/monitoring/tracker.d.ts +31 -0
- package/dist/monitoring/tracker.d.ts.map +1 -0
- package/dist/monitoring/tracker.js +86 -0
- package/dist/monitoring/tracker.js.map +1 -0
- package/dist/server/app.d.ts +8 -0
- package/dist/server/app.d.ts.map +1 -0
- package/dist/server/app.js +81 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/mcp-gateway.d.ts +12 -0
- package/dist/server/mcp-gateway.d.ts.map +1 -0
- package/dist/server/mcp-gateway.js +91 -0
- package/dist/server/mcp-gateway.js.map +1 -0
- package/dist/server/routes/auth.d.ts +4 -0
- package/dist/server/routes/auth.d.ts.map +1 -0
- package/dist/server/routes/auth.js +117 -0
- package/dist/server/routes/auth.js.map +1 -0
- package/dist/server/routes/context.d.ts +4 -0
- package/dist/server/routes/context.d.ts.map +1 -0
- package/dist/server/routes/context.js +107 -0
- package/dist/server/routes/context.js.map +1 -0
- package/dist/server/routes/health.d.ts +4 -0
- package/dist/server/routes/health.d.ts.map +1 -0
- package/dist/server/routes/health.js +22 -0
- package/dist/server/routes/health.js.map +1 -0
- package/dist/server/routes/servers.d.ts +4 -0
- package/dist/server/routes/servers.d.ts.map +1 -0
- package/dist/server/routes/servers.js +47 -0
- package/dist/server/routes/servers.js.map +1 -0
- package/dist/server/routes/stats.d.ts +4 -0
- package/dist/server/routes/stats.d.ts.map +1 -0
- package/dist/server/routes/stats.js +97 -0
- package/dist/server/routes/stats.js.map +1 -0
- package/dist/server/routes/team-servers.d.ts +4 -0
- package/dist/server/routes/team-servers.d.ts.map +1 -0
- package/dist/server/routes/team-servers.js +108 -0
- package/dist/server/routes/team-servers.js.map +1 -0
- package/dist/server/routes/tools.d.ts +4 -0
- package/dist/server/routes/tools.d.ts.map +1 -0
- package/dist/server/routes/tools.js +44 -0
- package/dist/server/routes/tools.js.map +1 -0
- package/dist/server/routes/webhooks.d.ts +4 -0
- package/dist/server/routes/webhooks.d.ts.map +1 -0
- package/dist/server/routes/webhooks.js +77 -0
- package/dist/server/routes/webhooks.js.map +1 -0
- package/dist/storage/database.d.ts +48 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +336 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/repositories/server-repo.d.ts +2 -0
- package/dist/storage/repositories/server-repo.d.ts.map +1 -0
- package/dist/storage/repositories/server-repo.js +3 -0
- package/dist/storage/repositories/server-repo.js.map +1 -0
- package/dist/storage/repositories/tool-repo.d.ts +2 -0
- package/dist/storage/repositories/tool-repo.d.ts.map +1 -0
- package/dist/storage/repositories/tool-repo.js +3 -0
- package/dist/storage/repositories/tool-repo.js.map +1 -0
- package/dist/types/index.d.ts +482 -587
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +52 -69
- package/dist/types/index.js.map +1 -1
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +23 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +67 -56
- package/.env.example +0 -19
- package/config/servers.example.yaml +0 -67
- package/config/servers.yaml +0 -2
- package/dist/cli/discover.d.ts +0 -3
- package/dist/cli/discover.d.ts.map +0 -1
- package/dist/cli/discover.js +0 -160
- package/dist/cli/discover.js.map +0 -1
- package/dist/connectors/base.d.ts +0 -49
- package/dist/connectors/base.d.ts.map +0 -1
- package/dist/connectors/base.js +0 -45
- package/dist/connectors/base.js.map +0 -1
- package/dist/connectors/custom.d.ts +0 -19
- package/dist/connectors/custom.d.ts.map +0 -1
- package/dist/connectors/custom.js +0 -129
- package/dist/connectors/custom.js.map +0 -1
- package/dist/connectors/github.d.ts +0 -18
- package/dist/connectors/github.d.ts.map +0 -1
- package/dist/connectors/github.js +0 -188
- package/dist/connectors/github.js.map +0 -1
- package/dist/connectors/google-drive.d.ts +0 -18
- package/dist/connectors/google-drive.d.ts.map +0 -1
- package/dist/connectors/google-drive.js +0 -209
- package/dist/connectors/google-drive.js.map +0 -1
- package/dist/connectors/index.d.ts +0 -11
- package/dist/connectors/index.d.ts.map +0 -1
- package/dist/connectors/index.js +0 -76
- package/dist/connectors/index.js.map +0 -1
- package/dist/connectors/postgres.d.ts +0 -18
- package/dist/connectors/postgres.d.ts.map +0 -1
- package/dist/connectors/postgres.js +0 -140
- package/dist/connectors/postgres.js.map +0 -1
- package/dist/connectors/slack.d.ts +0 -18
- package/dist/connectors/slack.d.ts.map +0 -1
- package/dist/connectors/slack.js +0 -181
- package/dist/connectors/slack.js.map +0 -1
- package/dist/core/auth.d.ts +0 -26
- package/dist/core/auth.d.ts.map +0 -1
- package/dist/core/auth.js +0 -81
- package/dist/core/auth.js.map +0 -1
- package/dist/core/tokenizer.d.ts +0 -16
- package/dist/core/tokenizer.d.ts.map +0 -1
- package/dist/core/tokenizer.js +0 -29
- package/dist/core/tokenizer.js.map +0 -1
- package/dist/governance/audit.d.ts +0 -27
- package/dist/governance/audit.d.ts.map +0 -1
- package/dist/governance/audit.js +0 -149
- package/dist/governance/audit.js.map +0 -1
- package/dist/governance/index.d.ts +0 -5
- package/dist/governance/index.d.ts.map +0 -1
- package/dist/governance/index.js +0 -5
- package/dist/governance/index.js.map +0 -1
- package/dist/governance/policy.d.ts +0 -20
- package/dist/governance/policy.d.ts.map +0 -1
- package/dist/governance/policy.js +0 -162
- package/dist/governance/policy.js.map +0 -1
- package/dist/governance/rate-limiter.d.ts +0 -20
- package/dist/governance/rate-limiter.d.ts.map +0 -1
- package/dist/governance/rate-limiter.js +0 -73
- package/dist/governance/rate-limiter.js.map +0 -1
- package/dist/governance/types.d.ts +0 -246
- package/dist/governance/types.d.ts.map +0 -1
- package/dist/governance/types.js +0 -72
- package/dist/governance/types.js.map +0 -1
- package/dist/identity/access-control.d.ts +0 -15
- package/dist/identity/access-control.d.ts.map +0 -1
- package/dist/identity/access-control.js +0 -81
- package/dist/identity/access-control.js.map +0 -1
- package/dist/identity/index.d.ts +0 -4
- package/dist/identity/index.d.ts.map +0 -1
- package/dist/identity/index.js +0 -4
- package/dist/identity/index.js.map +0 -1
- package/dist/identity/manager.d.ts +0 -29
- package/dist/identity/manager.d.ts.map +0 -1
- package/dist/identity/manager.js +0 -167
- package/dist/identity/manager.js.map +0 -1
- package/dist/identity/types.d.ts +0 -237
- package/dist/identity/types.d.ts.map +0 -1
- package/dist/identity/types.js +0 -80
- package/dist/identity/types.js.map +0 -1
- package/dist/registry/server.d.ts +0 -14
- package/dist/registry/server.d.ts.map +0 -1
- package/dist/registry/server.js +0 -177
- package/dist/registry/server.js.map +0 -1
- package/dist/utils/config.d.ts +0 -29
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js +0 -47
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -44
- package/dist/utils/index.js.map +0 -1
- package/dist/workflow/engine.d.ts +0 -18
- package/dist/workflow/engine.d.ts.map +0 -1
- package/dist/workflow/engine.js +0 -155
- package/dist/workflow/engine.js.map +0 -1
- package/dist/workflow/index.d.ts +0 -4
- package/dist/workflow/index.d.ts.map +0 -1
- package/dist/workflow/index.js +0 -4
- package/dist/workflow/index.js.map +0 -1
- package/dist/workflow/templates.d.ts +0 -4
- package/dist/workflow/templates.d.ts.map +0 -1
- package/dist/workflow/templates.js +0 -218
- package/dist/workflow/templates.js.map +0 -1
- package/dist/workflow/types.d.ts +0 -255
- package/dist/workflow/types.d.ts.map +0 -1
- package/dist/workflow/types.js +0 -48
- package/dist/workflow/types.js.map +0 -1
- package/eslint.config.js +0 -25
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { createLogger } from '../utils/logger.js';
|
|
5
|
+
const log = createLogger('mcp-gateway');
|
|
6
|
+
export class McpGateway {
|
|
7
|
+
registry;
|
|
8
|
+
mcpServer;
|
|
9
|
+
constructor(registry) {
|
|
10
|
+
this.registry = registry;
|
|
11
|
+
this.mcpServer = new McpServer({ name: 'opalserve', version: '3.0.0' }, { capabilities: { tools: {} } });
|
|
12
|
+
this.registerMetaTools();
|
|
13
|
+
this.registerProxyTools();
|
|
14
|
+
}
|
|
15
|
+
registerMetaTools() {
|
|
16
|
+
// Meta-tool: search across all servers
|
|
17
|
+
this.mcpServer.tool('opalserve_search', 'Search for tools across all registered MCP servers', { query: z.string().describe('Search query for finding tools') }, async ({ query }) => {
|
|
18
|
+
const results = this.registry.searchTools(query, { limit: 10 });
|
|
19
|
+
const formatted = results.map(r => `${r.tool.id} — ${r.tool.description || r.tool.name}`).join('\n');
|
|
20
|
+
return {
|
|
21
|
+
content: [{
|
|
22
|
+
type: 'text',
|
|
23
|
+
text: results.length > 0
|
|
24
|
+
? `Found ${results.length} tools:\n\n${formatted}`
|
|
25
|
+
: `No tools found matching "${query}"`,
|
|
26
|
+
}],
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
// Meta-tool: list all servers and their status
|
|
30
|
+
this.mcpServer.tool('opalserve_servers', 'List all registered MCP servers and their connection status', {}, async () => {
|
|
31
|
+
const servers = this.registry.listServers();
|
|
32
|
+
const formatted = servers.map(s => `${s.name} [${s.status}] — ${s.toolCount} tools (${s.transport})`).join('\n');
|
|
33
|
+
return {
|
|
34
|
+
content: [{
|
|
35
|
+
type: 'text',
|
|
36
|
+
text: servers.length > 0
|
|
37
|
+
? `${servers.length} servers:\n\n${formatted}`
|
|
38
|
+
: 'No servers registered',
|
|
39
|
+
}],
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
registerProxyTools() {
|
|
44
|
+
// Register all discovered tools as proxy-through tools
|
|
45
|
+
const tools = this.registry.listTools();
|
|
46
|
+
for (const tool of tools) {
|
|
47
|
+
const toolId = tool.id;
|
|
48
|
+
const inputSchema = (tool.inputSchema && typeof tool.inputSchema === 'object')
|
|
49
|
+
? tool.inputSchema
|
|
50
|
+
: {};
|
|
51
|
+
// Build a Zod schema from the JSON Schema properties
|
|
52
|
+
const properties = (inputSchema.properties || {});
|
|
53
|
+
const required = (inputSchema.required || []);
|
|
54
|
+
const zodShape = {};
|
|
55
|
+
for (const [key, _prop] of Object.entries(properties)) {
|
|
56
|
+
// Use permissive schema — actual validation happens on the backend server
|
|
57
|
+
zodShape[key] = required.includes(key)
|
|
58
|
+
? z.any()
|
|
59
|
+
: z.any().optional();
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
this.mcpServer.tool(`${tool.serverName}__${tool.name}`, tool.description || tool.name, zodShape, async (args) => {
|
|
63
|
+
try {
|
|
64
|
+
const result = await this.registry.callTool(toolId, args);
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
69
|
+
return {
|
|
70
|
+
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
71
|
+
isError: true,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
log.warn({ tool: toolId, error }, 'Failed to register proxy tool');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
log.info({ count: tools.length }, 'Proxy tools registered');
|
|
81
|
+
}
|
|
82
|
+
async connectStdio() {
|
|
83
|
+
const transport = new StdioServerTransport();
|
|
84
|
+
await this.mcpServer.connect(transport);
|
|
85
|
+
log.info('MCP gateway connected via stdio');
|
|
86
|
+
}
|
|
87
|
+
getServer() {
|
|
88
|
+
return this.mcpServer;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=mcp-gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-gateway.js","sourceRoot":"","sources":["../../src/server/mcp-gateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/routes/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAKhE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CA+J1F"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { hashPassword, verifyPassword } from '../../auth/passwords.js';
|
|
3
|
+
import { generateApiKey } from '../../auth/api-keys.js';
|
|
4
|
+
import { createAuthMiddleware } from '../../auth/middleware.js';
|
|
5
|
+
export function registerAuthRoutes(app, registry) {
|
|
6
|
+
const db = registry.getDatabase();
|
|
7
|
+
const requireAuth = createAuthMiddleware(db);
|
|
8
|
+
// --- Register ---
|
|
9
|
+
app.post('/api/v1/auth/register', async (request, reply) => {
|
|
10
|
+
const { email, password, displayName } = request.body;
|
|
11
|
+
if (!email || !password) {
|
|
12
|
+
return reply.status(400).send({ ok: false, error: 'Email and password are required' });
|
|
13
|
+
}
|
|
14
|
+
// Check if user already exists
|
|
15
|
+
const existing = db.get('SELECT id FROM users WHERE email = ?', [email]);
|
|
16
|
+
if (existing) {
|
|
17
|
+
return reply.status(409).send({ ok: false, error: 'User with this email already exists' });
|
|
18
|
+
}
|
|
19
|
+
const now = new Date().toISOString();
|
|
20
|
+
const userId = randomUUID();
|
|
21
|
+
const passwordHash = await hashPassword(password);
|
|
22
|
+
db.run('INSERT INTO users (id, email, password_hash, display_name, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)', [userId, email, passwordHash, displayName ?? null, now, now]);
|
|
23
|
+
// Generate API key
|
|
24
|
+
const { key, keyHash, keyPrefix } = generateApiKey();
|
|
25
|
+
const keyId = randomUUID();
|
|
26
|
+
db.run('INSERT INTO api_keys (id, user_id, key_hash, key_prefix, name, created_at) VALUES (?, ?, ?, ?, ?, ?)', [keyId, userId, keyHash, keyPrefix, 'default', now]);
|
|
27
|
+
return reply.status(201).send({
|
|
28
|
+
ok: true,
|
|
29
|
+
data: {
|
|
30
|
+
user: {
|
|
31
|
+
id: userId,
|
|
32
|
+
email,
|
|
33
|
+
displayName: displayName ?? null,
|
|
34
|
+
createdAt: now,
|
|
35
|
+
updatedAt: now,
|
|
36
|
+
},
|
|
37
|
+
apiKey: key,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
// --- Login ---
|
|
42
|
+
app.post('/api/v1/auth/login', async (request, reply) => {
|
|
43
|
+
const { email, password } = request.body;
|
|
44
|
+
if (!email || !password) {
|
|
45
|
+
return reply.status(400).send({ ok: false, error: 'Email and password are required' });
|
|
46
|
+
}
|
|
47
|
+
const row = db.get('SELECT id, email, password_hash, display_name, created_at, updated_at FROM users WHERE email = ?', [email]);
|
|
48
|
+
if (!row) {
|
|
49
|
+
return reply.status(401).send({ ok: false, error: 'Invalid email or password' });
|
|
50
|
+
}
|
|
51
|
+
const valid = await verifyPassword(password, row.password_hash);
|
|
52
|
+
if (!valid) {
|
|
53
|
+
return reply.status(401).send({ ok: false, error: 'Invalid email or password' });
|
|
54
|
+
}
|
|
55
|
+
// Generate new API key
|
|
56
|
+
const now = new Date().toISOString();
|
|
57
|
+
const { key, keyHash, keyPrefix } = generateApiKey();
|
|
58
|
+
const keyId = randomUUID();
|
|
59
|
+
db.run('INSERT INTO api_keys (id, user_id, key_hash, key_prefix, name, created_at) VALUES (?, ?, ?, ?, ?, ?)', [keyId, row.id, keyHash, keyPrefix, 'login', now]);
|
|
60
|
+
return reply.send({
|
|
61
|
+
ok: true,
|
|
62
|
+
data: {
|
|
63
|
+
user: {
|
|
64
|
+
id: row.id,
|
|
65
|
+
email: row.email,
|
|
66
|
+
displayName: row.display_name,
|
|
67
|
+
createdAt: row.created_at,
|
|
68
|
+
updatedAt: row.updated_at,
|
|
69
|
+
},
|
|
70
|
+
apiKey: key,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
// --- Me ---
|
|
75
|
+
app.get('/api/v1/auth/me', { preHandler: requireAuth }, async (request, reply) => {
|
|
76
|
+
if (!request.user) {
|
|
77
|
+
return reply.status(401).send({ ok: false, error: 'Not authenticated' });
|
|
78
|
+
}
|
|
79
|
+
return reply.send({ ok: true, data: request.user });
|
|
80
|
+
});
|
|
81
|
+
// --- Create API Key ---
|
|
82
|
+
app.post('/api/v1/auth/keys', { preHandler: requireAuth }, async (request, reply) => {
|
|
83
|
+
if (!request.user) {
|
|
84
|
+
return reply.status(401).send({ ok: false, error: 'Not authenticated' });
|
|
85
|
+
}
|
|
86
|
+
const { name } = request.body;
|
|
87
|
+
if (!name) {
|
|
88
|
+
return reply.status(400).send({ ok: false, error: 'Key name is required' });
|
|
89
|
+
}
|
|
90
|
+
const now = new Date().toISOString();
|
|
91
|
+
const { key, keyHash, keyPrefix } = generateApiKey();
|
|
92
|
+
const keyId = randomUUID();
|
|
93
|
+
db.run('INSERT INTO api_keys (id, user_id, key_hash, key_prefix, name, created_at) VALUES (?, ?, ?, ?, ?, ?)', [keyId, request.user.id, keyHash, keyPrefix, name, now]);
|
|
94
|
+
return reply.status(201).send({
|
|
95
|
+
ok: true,
|
|
96
|
+
data: { key, keyPrefix },
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
// --- Delete API Key ---
|
|
100
|
+
app.delete('/api/v1/auth/keys/:id', { preHandler: requireAuth }, async (request, reply) => {
|
|
101
|
+
if (!request.user) {
|
|
102
|
+
return reply.status(401).send({ ok: false, error: 'Not authenticated' });
|
|
103
|
+
}
|
|
104
|
+
const { id } = request.params;
|
|
105
|
+
// Verify the key belongs to the current user
|
|
106
|
+
const existing = db.get('SELECT user_id FROM api_keys WHERE id = ?', [id]);
|
|
107
|
+
if (!existing) {
|
|
108
|
+
return reply.status(404).send({ ok: false, error: 'API key not found' });
|
|
109
|
+
}
|
|
110
|
+
if (existing.user_id !== request.user.id) {
|
|
111
|
+
return reply.status(403).send({ ok: false, error: 'Cannot delete another user\'s API key' });
|
|
112
|
+
}
|
|
113
|
+
db.run('DELETE FROM api_keys WHERE id = ?', [id]);
|
|
114
|
+
return reply.send({ ok: true });
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/routes/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/server/routes/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CA4J7F"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { createAuthMiddleware } from '../../auth/middleware.js';
|
|
3
|
+
export function registerContextRoutes(app, registry) {
|
|
4
|
+
const db = registry.getDatabase();
|
|
5
|
+
const requireAuth = createAuthMiddleware(db);
|
|
6
|
+
// --- Create Document ---
|
|
7
|
+
app.post('/api/v1/context/documents', { preHandler: requireAuth }, async (request, reply) => {
|
|
8
|
+
const { title, content, contentType, source, tags } = request.body;
|
|
9
|
+
if (!title || !content) {
|
|
10
|
+
return reply.status(400).send({ ok: false, error: 'Title and content are required' });
|
|
11
|
+
}
|
|
12
|
+
const now = new Date().toISOString();
|
|
13
|
+
const id = randomUUID();
|
|
14
|
+
const userId = request.user?.id ?? null;
|
|
15
|
+
// Resolve team_id from user membership
|
|
16
|
+
let teamId = null;
|
|
17
|
+
if (userId) {
|
|
18
|
+
const membership = db.get('SELECT team_id FROM team_members WHERE user_id = ?', [userId]);
|
|
19
|
+
teamId = membership?.team_id ?? null;
|
|
20
|
+
}
|
|
21
|
+
db.run(`INSERT INTO context_documents (id, team_id, title, content, content_type, source, tags, uploaded_by, created_at, updated_at)
|
|
22
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [id, teamId, title, content, contentType ?? 'text/markdown', source ?? null, JSON.stringify(tags ?? []), userId, now, now]);
|
|
23
|
+
const doc = {
|
|
24
|
+
id,
|
|
25
|
+
teamId,
|
|
26
|
+
title,
|
|
27
|
+
content,
|
|
28
|
+
contentType: contentType ?? 'text/markdown',
|
|
29
|
+
source: source ?? null,
|
|
30
|
+
tags: tags ?? [],
|
|
31
|
+
uploadedBy: userId,
|
|
32
|
+
createdAt: now,
|
|
33
|
+
updatedAt: now,
|
|
34
|
+
};
|
|
35
|
+
return reply.status(201).send({ ok: true, data: doc });
|
|
36
|
+
});
|
|
37
|
+
// --- List Documents ---
|
|
38
|
+
app.get('/api/v1/context/documents', { preHandler: requireAuth }, async (_request, reply) => {
|
|
39
|
+
const rows = db.all('SELECT * FROM context_documents ORDER BY created_at DESC');
|
|
40
|
+
const data = rows.map(r => ({
|
|
41
|
+
id: r.id,
|
|
42
|
+
teamId: r.team_id,
|
|
43
|
+
title: r.title,
|
|
44
|
+
content: r.content,
|
|
45
|
+
contentType: r.content_type,
|
|
46
|
+
source: r.source,
|
|
47
|
+
tags: JSON.parse(r.tags || '[]'),
|
|
48
|
+
uploadedBy: r.uploaded_by,
|
|
49
|
+
createdAt: r.created_at,
|
|
50
|
+
updatedAt: r.updated_at,
|
|
51
|
+
}));
|
|
52
|
+
return reply.send({ ok: true, data });
|
|
53
|
+
});
|
|
54
|
+
// --- Search Documents ---
|
|
55
|
+
app.get('/api/v1/context/search', { preHandler: requireAuth }, async (request, reply) => {
|
|
56
|
+
const { q } = request.query;
|
|
57
|
+
if (!q || !q.trim()) {
|
|
58
|
+
return reply.status(400).send({ ok: false, error: 'Query parameter "q" is required' });
|
|
59
|
+
}
|
|
60
|
+
const terms = q.toLowerCase().split(/\s+/);
|
|
61
|
+
const rows = db.all('SELECT * FROM context_documents ORDER BY created_at DESC');
|
|
62
|
+
const results = rows
|
|
63
|
+
.map(r => {
|
|
64
|
+
let score = 0;
|
|
65
|
+
const titleL = r.title.toLowerCase();
|
|
66
|
+
const contentL = r.content.toLowerCase();
|
|
67
|
+
const tagsL = (r.tags || '[]').toLowerCase();
|
|
68
|
+
for (const term of terms) {
|
|
69
|
+
if (titleL.includes(term))
|
|
70
|
+
score += 5;
|
|
71
|
+
if (contentL.includes(term))
|
|
72
|
+
score += 3;
|
|
73
|
+
if (tagsL.includes(term))
|
|
74
|
+
score += 2;
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
doc: {
|
|
78
|
+
id: r.id,
|
|
79
|
+
teamId: r.team_id,
|
|
80
|
+
title: r.title,
|
|
81
|
+
content: r.content,
|
|
82
|
+
contentType: r.content_type,
|
|
83
|
+
source: r.source,
|
|
84
|
+
tags: JSON.parse(r.tags || '[]'),
|
|
85
|
+
uploadedBy: r.uploaded_by,
|
|
86
|
+
createdAt: r.created_at,
|
|
87
|
+
updatedAt: r.updated_at,
|
|
88
|
+
},
|
|
89
|
+
score,
|
|
90
|
+
};
|
|
91
|
+
})
|
|
92
|
+
.filter(r => r.score > 0)
|
|
93
|
+
.sort((a, b) => b.score - a.score);
|
|
94
|
+
return reply.send({ ok: true, data: results });
|
|
95
|
+
});
|
|
96
|
+
// --- Delete Document ---
|
|
97
|
+
app.delete('/api/v1/context/documents/:id', { preHandler: requireAuth }, async (request, reply) => {
|
|
98
|
+
const { id } = request.params;
|
|
99
|
+
const existing = db.get('SELECT id FROM context_documents WHERE id = ?', [id]);
|
|
100
|
+
if (!existing) {
|
|
101
|
+
return reply.status(404).send({ ok: false, error: 'Document not found' });
|
|
102
|
+
}
|
|
103
|
+
db.run('DELETE FROM context_documents WHERE id = ?', [id]);
|
|
104
|
+
return reply.send({ ok: true });
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/server/routes/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/server/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAqB5F"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function registerHealthRoutes(app, registry) {
|
|
2
|
+
app.get('/api/v1/health', async (_request, reply) => {
|
|
3
|
+
const servers = registry.listServers();
|
|
4
|
+
const tools = registry.listTools();
|
|
5
|
+
return reply.send({
|
|
6
|
+
ok: true,
|
|
7
|
+
data: {
|
|
8
|
+
status: 'running',
|
|
9
|
+
version: '3.0.0',
|
|
10
|
+
uptime: process.uptime(),
|
|
11
|
+
servers: {
|
|
12
|
+
total: servers.length,
|
|
13
|
+
connected: servers.filter(s => s.status === 'connected').length,
|
|
14
|
+
},
|
|
15
|
+
tools: {
|
|
16
|
+
total: tools.length,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/server/routes/health.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,oBAAoB,CAAC,GAAoB,EAAE,QAA2B;IACpF,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;QAEnC,OAAO,KAAK,CAAC,IAAI,CAAC;YAChB,EAAE,EAAE,IAAI;YACR,IAAI,EAAE;gBACJ,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,OAAO;gBAChB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;gBACxB,OAAO,EAAE;oBACP,KAAK,EAAE,OAAO,CAAC,MAAM;oBACrB,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM;iBAChE;gBACD,KAAK,EAAE;oBACL,KAAK,EAAE,KAAK,CAAC,MAAM;iBACpB;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../../src/server/routes/servers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAiD5F"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { McpServerConfigSchema } from '../../types/index.js';
|
|
2
|
+
export function registerServerRoutes(app, registry) {
|
|
3
|
+
app.get('/api/v1/servers', async (_request, reply) => {
|
|
4
|
+
const servers = registry.listServers();
|
|
5
|
+
return reply.send({ ok: true, data: servers });
|
|
6
|
+
});
|
|
7
|
+
app.post('/api/v1/servers', async (request, reply) => {
|
|
8
|
+
const parsed = McpServerConfigSchema.safeParse(request.body);
|
|
9
|
+
if (!parsed.success) {
|
|
10
|
+
return reply.status(400).send({
|
|
11
|
+
ok: false,
|
|
12
|
+
error: 'Invalid server configuration',
|
|
13
|
+
details: parsed.error.flatten(),
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
await registry.addServer(parsed.data);
|
|
18
|
+
const servers = registry.listServers();
|
|
19
|
+
const added = servers.find(s => s.name === parsed.data.name);
|
|
20
|
+
return reply.status(201).send({ ok: true, data: added });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
24
|
+
return reply.status(500).send({ ok: false, error: message });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
app.delete('/api/v1/servers/:name', async (request, reply) => {
|
|
28
|
+
const { name } = request.params;
|
|
29
|
+
try {
|
|
30
|
+
await registry.removeServer(name);
|
|
31
|
+
return reply.send({ ok: true });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
return reply.status(404).send({ ok: false, error: message });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
app.get('/api/v1/servers/:name/health', async (request, reply) => {
|
|
39
|
+
const { name } = request.params;
|
|
40
|
+
const results = await registry.healthCheck(name);
|
|
41
|
+
if (results.length === 0) {
|
|
42
|
+
return reply.status(404).send({ ok: false, error: `Server "${name}" not found` });
|
|
43
|
+
}
|
|
44
|
+
return reply.send({ ok: true, data: results[0] });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=servers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.js","sourceRoot":"","sources":["../../../src/server/routes/servers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/server/routes/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAmBhE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAqI3F"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createAuthMiddleware } from '../../auth/middleware.js';
|
|
2
|
+
function parsePeriod(period) {
|
|
3
|
+
const match = period.match(/^(\d+)(h|d|w|m)$/);
|
|
4
|
+
if (!match)
|
|
5
|
+
return "datetime('now', '-24 hours')";
|
|
6
|
+
const [, value, unit] = match;
|
|
7
|
+
const num = parseInt(value, 10);
|
|
8
|
+
switch (unit) {
|
|
9
|
+
case 'h': return `datetime('now', '-${num} hours')`;
|
|
10
|
+
case 'd': return `datetime('now', '-${num} days')`;
|
|
11
|
+
case 'w': return `datetime('now', '-${num * 7} days')`;
|
|
12
|
+
case 'm': return `datetime('now', '-${num * 30} days')`;
|
|
13
|
+
default: return "datetime('now', '-24 hours')";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function registerStatsRoutes(app, registry) {
|
|
17
|
+
const db = registry.getDatabase();
|
|
18
|
+
const requireAuth = createAuthMiddleware(db);
|
|
19
|
+
// --- Overview Stats ---
|
|
20
|
+
app.get('/api/v1/stats/overview', { preHandler: requireAuth }, async (request, reply) => {
|
|
21
|
+
const { period } = request.query;
|
|
22
|
+
const since = parsePeriod(period ?? '24h');
|
|
23
|
+
const totalRow = db.get(`SELECT COUNT(*) as count FROM usage_events WHERE created_at >= ${since}`);
|
|
24
|
+
const totalCalls = totalRow?.count ?? 0;
|
|
25
|
+
const activeUsersRow = db.get(`SELECT COUNT(DISTINCT user_id) as count FROM usage_events WHERE created_at >= ${since} AND user_id IS NOT NULL`);
|
|
26
|
+
const activeUsers = activeUsersRow?.count ?? 0;
|
|
27
|
+
const topTools = db.all(`SELECT tool_name as name, COUNT(*) as count FROM usage_events
|
|
28
|
+
WHERE created_at >= ${since} AND tool_name IS NOT NULL
|
|
29
|
+
GROUP BY tool_name ORDER BY count DESC LIMIT 10`);
|
|
30
|
+
const errorRow = db.get(`SELECT COUNT(*) as count FROM usage_events WHERE created_at >= ${since} AND success = 0`);
|
|
31
|
+
const errorCount = errorRow?.count ?? 0;
|
|
32
|
+
const errorRate = totalCalls > 0 ? errorCount / totalCalls : 0;
|
|
33
|
+
return reply.send({
|
|
34
|
+
ok: true,
|
|
35
|
+
data: {
|
|
36
|
+
totalCalls,
|
|
37
|
+
activeUsers,
|
|
38
|
+
topTools,
|
|
39
|
+
errorRate: Math.round(errorRate * 10000) / 10000,
|
|
40
|
+
period: period ?? '24h',
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
// --- Per-User Stats ---
|
|
45
|
+
app.get('/api/v1/stats/users/:id', { preHandler: requireAuth }, async (request, reply) => {
|
|
46
|
+
const { id } = request.params;
|
|
47
|
+
const { period } = request.query;
|
|
48
|
+
const since = parsePeriod(period ?? '7d');
|
|
49
|
+
const user = db.get('SELECT id, email, display_name FROM users WHERE id = ?', [id]);
|
|
50
|
+
if (!user) {
|
|
51
|
+
return reply.status(404).send({ ok: false, error: 'User not found' });
|
|
52
|
+
}
|
|
53
|
+
const totalRow = db.get(`SELECT COUNT(*) as count FROM usage_events WHERE user_id = ? AND created_at >= ${since}`, [id]);
|
|
54
|
+
const topTools = db.all(`SELECT tool_name as name, COUNT(*) as count FROM usage_events
|
|
55
|
+
WHERE user_id = ? AND created_at >= ${since} AND tool_name IS NOT NULL
|
|
56
|
+
GROUP BY tool_name ORDER BY count DESC LIMIT 10`, [id]);
|
|
57
|
+
const errorRow = db.get(`SELECT COUNT(*) as count FROM usage_events WHERE user_id = ? AND created_at >= ${since} AND success = 0`, [id]);
|
|
58
|
+
const totalCalls = totalRow?.count ?? 0;
|
|
59
|
+
const errorCount = errorRow?.count ?? 0;
|
|
60
|
+
return reply.send({
|
|
61
|
+
ok: true,
|
|
62
|
+
data: {
|
|
63
|
+
user: { id: user.id, email: user.email, displayName: user.display_name },
|
|
64
|
+
totalCalls,
|
|
65
|
+
topTools,
|
|
66
|
+
errorRate: totalCalls > 0 ? Math.round((errorCount / totalCalls) * 10000) / 10000 : 0,
|
|
67
|
+
period: period ?? '7d',
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
// --- Per-Server Stats ---
|
|
72
|
+
app.get('/api/v1/stats/servers/:name', { preHandler: requireAuth }, async (request, reply) => {
|
|
73
|
+
const { name } = request.params;
|
|
74
|
+
const { period } = request.query;
|
|
75
|
+
const since = parsePeriod(period ?? '7d');
|
|
76
|
+
const totalRow = db.get(`SELECT COUNT(*) as count FROM usage_events WHERE server_name = ? AND created_at >= ${since}`, [name]);
|
|
77
|
+
const topTools = db.all(`SELECT tool_name as name, COUNT(*) as count FROM usage_events
|
|
78
|
+
WHERE server_name = ? AND created_at >= ${since} AND tool_name IS NOT NULL
|
|
79
|
+
GROUP BY tool_name ORDER BY count DESC LIMIT 10`, [name]);
|
|
80
|
+
const errorRow = db.get(`SELECT COUNT(*) as count FROM usage_events WHERE server_name = ? AND created_at >= ${since} AND success = 0`, [name]);
|
|
81
|
+
const avgLatencyRow = db.get(`SELECT AVG(latency_ms) as avg_latency FROM usage_events WHERE server_name = ? AND created_at >= ${since} AND latency_ms IS NOT NULL`, [name]);
|
|
82
|
+
const totalCalls = totalRow?.count ?? 0;
|
|
83
|
+
const errorCount = errorRow?.count ?? 0;
|
|
84
|
+
return reply.send({
|
|
85
|
+
ok: true,
|
|
86
|
+
data: {
|
|
87
|
+
serverName: name,
|
|
88
|
+
totalCalls,
|
|
89
|
+
topTools,
|
|
90
|
+
errorRate: totalCalls > 0 ? Math.round((errorCount / totalCalls) * 10000) / 10000 : 0,
|
|
91
|
+
avgLatencyMs: avgLatencyRow?.avg_latency ? Math.round(avgLatencyRow.avg_latency) : null,
|
|
92
|
+
period: period ?? '7d',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/server/routes/stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-servers.d.ts","sourceRoot":"","sources":["../../../src/server/routes/team-servers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAyJhG"}
|