@wener/mcps 1.0.1

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.
Files changed (141) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.mjs +15 -0
  3. package/dist/mcps-cli.mjs +174727 -0
  4. package/lib/chat/agent.js +187 -0
  5. package/lib/chat/agent.js.map +1 -0
  6. package/lib/chat/audit.js +238 -0
  7. package/lib/chat/audit.js.map +1 -0
  8. package/lib/chat/converters.js +467 -0
  9. package/lib/chat/converters.js.map +1 -0
  10. package/lib/chat/handler.js +1068 -0
  11. package/lib/chat/handler.js.map +1 -0
  12. package/lib/chat/index.js +12 -0
  13. package/lib/chat/index.js.map +1 -0
  14. package/lib/chat/types.js +35 -0
  15. package/lib/chat/types.js.map +1 -0
  16. package/lib/contracts/AuditContract.js +85 -0
  17. package/lib/contracts/AuditContract.js.map +1 -0
  18. package/lib/contracts/McpsContract.js +113 -0
  19. package/lib/contracts/McpsContract.js.map +1 -0
  20. package/lib/contracts/index.js +3 -0
  21. package/lib/contracts/index.js.map +1 -0
  22. package/lib/dev.server.js +7 -0
  23. package/lib/dev.server.js.map +1 -0
  24. package/lib/entities/ChatRequestEntity.js +318 -0
  25. package/lib/entities/ChatRequestEntity.js.map +1 -0
  26. package/lib/entities/McpRequestEntity.js +271 -0
  27. package/lib/entities/McpRequestEntity.js.map +1 -0
  28. package/lib/entities/RequestLogEntity.js +177 -0
  29. package/lib/entities/RequestLogEntity.js.map +1 -0
  30. package/lib/entities/ResponseEntity.js +150 -0
  31. package/lib/entities/ResponseEntity.js.map +1 -0
  32. package/lib/entities/index.js +11 -0
  33. package/lib/entities/index.js.map +1 -0
  34. package/lib/entities/types.js +11 -0
  35. package/lib/entities/types.js.map +1 -0
  36. package/lib/index.js +3 -0
  37. package/lib/index.js.map +1 -0
  38. package/lib/mcps-cli.js +44 -0
  39. package/lib/mcps-cli.js.map +1 -0
  40. package/lib/providers/McpServerHandlerDef.js +40 -0
  41. package/lib/providers/McpServerHandlerDef.js.map +1 -0
  42. package/lib/providers/findMcpServerDef.js +26 -0
  43. package/lib/providers/findMcpServerDef.js.map +1 -0
  44. package/lib/providers/prometheus/def.js +24 -0
  45. package/lib/providers/prometheus/def.js.map +1 -0
  46. package/lib/providers/prometheus/index.js +2 -0
  47. package/lib/providers/prometheus/index.js.map +1 -0
  48. package/lib/providers/relay/def.js +32 -0
  49. package/lib/providers/relay/def.js.map +1 -0
  50. package/lib/providers/relay/index.js +2 -0
  51. package/lib/providers/relay/index.js.map +1 -0
  52. package/lib/providers/sql/def.js +31 -0
  53. package/lib/providers/sql/def.js.map +1 -0
  54. package/lib/providers/sql/index.js +2 -0
  55. package/lib/providers/sql/index.js.map +1 -0
  56. package/lib/providers/tencent-cls/def.js +44 -0
  57. package/lib/providers/tencent-cls/def.js.map +1 -0
  58. package/lib/providers/tencent-cls/index.js +2 -0
  59. package/lib/providers/tencent-cls/index.js.map +1 -0
  60. package/lib/scripts/bundle.js +90 -0
  61. package/lib/scripts/bundle.js.map +1 -0
  62. package/lib/server/api-routes.js +96 -0
  63. package/lib/server/api-routes.js.map +1 -0
  64. package/lib/server/audit.js +274 -0
  65. package/lib/server/audit.js.map +1 -0
  66. package/lib/server/chat-routes.js +82 -0
  67. package/lib/server/chat-routes.js.map +1 -0
  68. package/lib/server/config.js +223 -0
  69. package/lib/server/config.js.map +1 -0
  70. package/lib/server/db.js +97 -0
  71. package/lib/server/db.js.map +1 -0
  72. package/lib/server/index.js +2 -0
  73. package/lib/server/index.js.map +1 -0
  74. package/lib/server/mcp-handler.js +167 -0
  75. package/lib/server/mcp-handler.js.map +1 -0
  76. package/lib/server/mcp-routes.js +112 -0
  77. package/lib/server/mcp-routes.js.map +1 -0
  78. package/lib/server/mcps-router.js +119 -0
  79. package/lib/server/mcps-router.js.map +1 -0
  80. package/lib/server/schema.js +129 -0
  81. package/lib/server/schema.js.map +1 -0
  82. package/lib/server/server.js +166 -0
  83. package/lib/server/server.js.map +1 -0
  84. package/lib/web/ChatPage.js +827 -0
  85. package/lib/web/ChatPage.js.map +1 -0
  86. package/lib/web/McpInspectorPage.js +214 -0
  87. package/lib/web/McpInspectorPage.js.map +1 -0
  88. package/lib/web/ServersPage.js +93 -0
  89. package/lib/web/ServersPage.js.map +1 -0
  90. package/lib/web/main.js +541 -0
  91. package/lib/web/main.js.map +1 -0
  92. package/package.json +83 -0
  93. package/src/chat/agent.ts +240 -0
  94. package/src/chat/audit.ts +377 -0
  95. package/src/chat/converters.test.ts +325 -0
  96. package/src/chat/converters.ts +459 -0
  97. package/src/chat/handler.test.ts +137 -0
  98. package/src/chat/handler.ts +1233 -0
  99. package/src/chat/index.ts +16 -0
  100. package/src/chat/types.ts +72 -0
  101. package/src/contracts/AuditContract.ts +93 -0
  102. package/src/contracts/McpsContract.ts +141 -0
  103. package/src/contracts/index.ts +18 -0
  104. package/src/dev.server.ts +7 -0
  105. package/src/entities/ChatRequestEntity.ts +157 -0
  106. package/src/entities/McpRequestEntity.ts +149 -0
  107. package/src/entities/RequestLogEntity.ts +78 -0
  108. package/src/entities/ResponseEntity.ts +75 -0
  109. package/src/entities/index.ts +12 -0
  110. package/src/entities/types.ts +188 -0
  111. package/src/index.ts +1 -0
  112. package/src/mcps-cli.ts +59 -0
  113. package/src/providers/McpServerHandlerDef.ts +105 -0
  114. package/src/providers/findMcpServerDef.ts +31 -0
  115. package/src/providers/prometheus/def.ts +21 -0
  116. package/src/providers/prometheus/index.ts +1 -0
  117. package/src/providers/relay/def.ts +31 -0
  118. package/src/providers/relay/index.ts +1 -0
  119. package/src/providers/relay/relay.test.ts +47 -0
  120. package/src/providers/sql/def.ts +33 -0
  121. package/src/providers/sql/index.ts +1 -0
  122. package/src/providers/tencent-cls/def.ts +38 -0
  123. package/src/providers/tencent-cls/index.ts +1 -0
  124. package/src/scripts/bundle.ts +82 -0
  125. package/src/server/api-routes.ts +98 -0
  126. package/src/server/audit.ts +310 -0
  127. package/src/server/chat-routes.ts +95 -0
  128. package/src/server/config.test.ts +162 -0
  129. package/src/server/config.ts +198 -0
  130. package/src/server/db.ts +115 -0
  131. package/src/server/index.ts +1 -0
  132. package/src/server/mcp-handler.ts +209 -0
  133. package/src/server/mcp-routes.ts +133 -0
  134. package/src/server/mcps-router.ts +133 -0
  135. package/src/server/schema.ts +175 -0
  136. package/src/server/server.ts +163 -0
  137. package/src/web/ChatPage.tsx +1005 -0
  138. package/src/web/McpInspectorPage.tsx +254 -0
  139. package/src/web/ServersPage.tsx +139 -0
  140. package/src/web/main.tsx +600 -0
  141. package/src/web/styles.css +15 -0
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Chat API Module
3
+ * Provides unified AI model gateway with protocol conversion
4
+ */
5
+
6
+ // Types
7
+ export * from './types';
8
+
9
+ // Converters
10
+ export * from './converters';
11
+
12
+ // Audit
13
+ export * from './audit';
14
+
15
+ // Handler
16
+ export { createChatHandler, type ChatHandlerOptions } from './handler';
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Common types for chat API
3
+ */
4
+ import { z } from 'zod';
5
+
6
+ // ============================================================================
7
+ // Provider Configuration (wener-mcps specific)
8
+ // ============================================================================
9
+
10
+ /**
11
+ * Protocol type for model providers
12
+ */
13
+ export type ProtocolType = 'openai' | 'anthropic' | 'gemini';
14
+
15
+ /**
16
+ * Provider endpoint configuration
17
+ */
18
+ export const ProviderEndpointSchema = z.object({
19
+ baseUrl: z.string(),
20
+ headers: z.record(z.string(), z.string()).optional(),
21
+ processors: z.array(z.string()).optional(),
22
+ });
23
+ export type ProviderEndpoint = z.infer<typeof ProviderEndpointSchema>;
24
+
25
+ /**
26
+ * Model configuration
27
+ */
28
+ export const ModelConfigSchema = z.object({
29
+ /** Base URL for the API */
30
+ baseUrl: z.string().optional(),
31
+ /** API key (uses Authorization: Bearer header) */
32
+ apiKey: z.string().optional(),
33
+ /** Additional headers */
34
+ headers: z.record(z.string(), z.string()).optional(),
35
+ /** Default adapter for protocol conversion */
36
+ adapter: z.enum(['openai', 'anthropic', 'gemini']).optional(),
37
+ /** Adapter-specific endpoints */
38
+ adapters: z
39
+ .object({
40
+ openai: ProviderEndpointSchema.optional(),
41
+ anthropic: ProviderEndpointSchema.optional(),
42
+ gemini: ProviderEndpointSchema.optional(),
43
+ })
44
+ .optional(),
45
+ /** Processor chain */
46
+ processors: z.array(z.string()).optional(),
47
+ });
48
+ export type ModelConfig = z.infer<typeof ModelConfigSchema>;
49
+
50
+ /**
51
+ * Chat configuration with models
52
+ */
53
+ export const ChatConfigSchema = z.object({
54
+ models: z.record(z.string(), ModelConfigSchema).optional(),
55
+ });
56
+ export type ChatConfig = z.infer<typeof ChatConfigSchema>;
57
+
58
+ // ============================================================================
59
+ // Stream Event Types
60
+ // ============================================================================
61
+
62
+ /**
63
+ * Stream event types for SSE
64
+ */
65
+ export type StreamEventType =
66
+ | 'message_start'
67
+ | 'content_block_start'
68
+ | 'content_block_delta'
69
+ | 'content_block_stop'
70
+ | 'message_delta'
71
+ | 'message_stop'
72
+ | 'error';
@@ -0,0 +1,93 @@
1
+ import { oc } from '@orpc/contract';
2
+ import { z } from 'zod';
3
+
4
+ // Audit event schema
5
+ export const AuditEventSchema = z.object({
6
+ id: z.string(),
7
+ timestamp: z.string(),
8
+ method: z.string(),
9
+ path: z.string(),
10
+ serverName: z.string().nullish(),
11
+ serverType: z.string().nullish(),
12
+ status: z.number().nullish(),
13
+ durationMs: z.number().nullish(),
14
+ requestHeaders: z.record(z.string(), z.string()).nullish(),
15
+ responseHeaders: z.record(z.string(), z.string()).nullish(),
16
+ requestBody: z.unknown().nullish(),
17
+ responseBody: z.unknown().nullish(),
18
+ error: z.string().nullish(),
19
+ toolName: z.string().nullish(),
20
+ toolArgs: z.unknown().nullish(),
21
+ });
22
+ export type AuditEvent = z.infer<typeof AuditEventSchema>;
23
+
24
+ // Query params
25
+ export const AuditQuerySchema = z.object({
26
+ limit: z.coerce.number().default(50),
27
+ offset: z.coerce.number().default(0),
28
+ serverName: z.string().nullish(),
29
+ serverType: z.string().nullish(),
30
+ method: z.string().nullish(),
31
+ from: z.string().nullish(),
32
+ to: z.string().nullish(),
33
+ });
34
+
35
+ // Audit stats
36
+ export const AuditStatsSchema = z.object({
37
+ totalRequests: z.number(),
38
+ totalErrors: z.number(),
39
+ avgDurationMs: z.number(),
40
+ byServer: z.array(
41
+ z.object({
42
+ name: z.string(),
43
+ count: z.number(),
44
+ }),
45
+ ),
46
+ byMethod: z.array(
47
+ z.object({
48
+ method: z.string(),
49
+ count: z.number(),
50
+ }),
51
+ ),
52
+ });
53
+
54
+ // Contract definition
55
+ export const AuditContract = oc.prefix('/audit').router({
56
+ // List audit events
57
+ list: oc
58
+ .input(AuditQuerySchema)
59
+ .output(
60
+ z.object({
61
+ events: z.array(AuditEventSchema),
62
+ total: z.number(),
63
+ }),
64
+ )
65
+ .route({ method: 'GET', path: '/', summary: 'List audit events' }),
66
+
67
+ // Get single event
68
+ get: oc
69
+ .input(z.object({ id: z.string() }))
70
+ .output(AuditEventSchema.nullable())
71
+ .route({ method: 'GET', path: '/{id}', summary: 'Get audit event by ID' }),
72
+
73
+ // Get stats
74
+ stats: oc
75
+ .input(
76
+ z.object({
77
+ from: z.string().nullish(),
78
+ to: z.string().nullish(),
79
+ }),
80
+ )
81
+ .output(AuditStatsSchema)
82
+ .route({ method: 'GET', path: '/stats', summary: 'Get audit statistics' }),
83
+
84
+ // Clear old events
85
+ clear: oc
86
+ .input(
87
+ z.object({
88
+ before: z.string().describe('Clear events before this timestamp'),
89
+ }),
90
+ )
91
+ .output(z.object({ deleted: z.number() }))
92
+ .route({ method: 'DELETE', path: '/', summary: 'Clear audit events' }),
93
+ });
@@ -0,0 +1,141 @@
1
+ import { oc } from '@orpc/contract';
2
+ import { z } from 'zod';
3
+
4
+ // Server info schema
5
+ export const ServerInfoSchema = z.object({
6
+ name: z.string(),
7
+ type: z.string(),
8
+ disabled: z.boolean().optional(),
9
+ });
10
+ export type ServerInfo = z.infer<typeof ServerInfoSchema>;
11
+
12
+ // Server type info schema
13
+ export const ServerTypeInfoSchema = z.object({
14
+ type: z.string(),
15
+ description: z.string(),
16
+ dynamicEndpoint: z.string(),
17
+ });
18
+ export type ServerTypeInfo = z.infer<typeof ServerTypeInfoSchema>;
19
+
20
+ // Model info schema
21
+ export const ModelInfoSchema = z.object({
22
+ name: z.string(),
23
+ adapter: z.string().nullish(),
24
+ baseUrl: z.string().nullish(),
25
+ contextWindow: z.number().nullish(),
26
+ maxInputTokens: z.number().nullish(),
27
+ maxOutputTokens: z.number().nullish(),
28
+ });
29
+ export type ModelInfo = z.infer<typeof ModelInfoSchema>;
30
+
31
+ // Service overview schema
32
+ export const ServiceOverviewSchema = z.object({
33
+ name: z.string(),
34
+ version: z.string(),
35
+ servers: z.array(ServerInfoSchema),
36
+ serverTypes: z.array(ServerTypeInfoSchema),
37
+ models: z.array(ModelInfoSchema),
38
+ endpoints: z.array(z.string()),
39
+ });
40
+ export type ServiceOverview = z.infer<typeof ServiceOverviewSchema>;
41
+
42
+ // Request stats schema
43
+ export const RequestStatsSchema = z.object({
44
+ totalRequests: z.number(),
45
+ totalErrors: z.number(),
46
+ avgDurationMs: z.number(),
47
+ byServer: z.array(
48
+ z.object({
49
+ name: z.string(),
50
+ count: z.number(),
51
+ }),
52
+ ),
53
+ byMethod: z.array(
54
+ z.object({
55
+ method: z.string(),
56
+ count: z.number(),
57
+ }),
58
+ ),
59
+ byEndpoint: z.array(
60
+ z.object({
61
+ endpoint: z.string(),
62
+ count: z.number(),
63
+ }),
64
+ ),
65
+ });
66
+ export type RequestStats = z.infer<typeof RequestStatsSchema>;
67
+
68
+ // Tool parameter schema
69
+ export const ToolParameterSchema = z.object({
70
+ name: z.string(),
71
+ type: z.string(),
72
+ description: z.string().nullish(),
73
+ required: z.boolean(),
74
+ });
75
+ export type ToolParameter = z.infer<typeof ToolParameterSchema>;
76
+
77
+ // Tool info schema for display
78
+ export const ToolInfoSchema = z.object({
79
+ name: z.string(),
80
+ description: z.string().nullish(),
81
+ serverName: z.string(),
82
+ serverType: z.string(),
83
+ parameters: z.array(ToolParameterSchema),
84
+ inputSchemaCompact: z.string().nullish(), // Compact TS-like schema representation
85
+ });
86
+ export type ToolInfo = z.infer<typeof ToolInfoSchema>;
87
+
88
+ // MCPS Contract
89
+ export const McpsContract = oc.prefix('/mcps').router({
90
+ // Get service overview
91
+ overview: oc
92
+ .input(z.object({}))
93
+ .output(ServiceOverviewSchema)
94
+ .route({ method: 'GET', path: '/overview', summary: 'Get service overview' }),
95
+
96
+ // Get request statistics
97
+ stats: oc
98
+ .input(
99
+ z.object({
100
+ from: z.string().nullish(),
101
+ to: z.string().nullish(),
102
+ }),
103
+ )
104
+ .output(RequestStatsSchema)
105
+ .route({ method: 'GET', path: '/stats', summary: 'Get request statistics' }),
106
+
107
+ // List configured servers
108
+ servers: oc
109
+ .input(z.object({}))
110
+ .output(
111
+ z.object({
112
+ servers: z.array(ServerInfoSchema),
113
+ }),
114
+ )
115
+ .route({ method: 'GET', path: '/servers', summary: 'List configured servers' }),
116
+
117
+ // List configured models
118
+ models: oc
119
+ .input(z.object({}))
120
+ .output(
121
+ z.object({
122
+ models: z.array(ModelInfoSchema),
123
+ }),
124
+ )
125
+ .route({ method: 'GET', path: '/models', summary: 'List configured models' }),
126
+
127
+ // List tools from all servers
128
+ tools: oc
129
+ .input(
130
+ z.object({
131
+ server: z.string().nullish(), // Filter by server name
132
+ filter: z.string().nullish(), // Glob pattern filter (like X-MCP-Include)
133
+ }),
134
+ )
135
+ .output(
136
+ z.object({
137
+ tools: z.array(ToolInfoSchema),
138
+ }),
139
+ )
140
+ .route({ method: 'GET', path: '/tools', summary: 'List tools from MCP servers' }),
141
+ });
@@ -0,0 +1,18 @@
1
+ export { AuditContract, AuditEventSchema, AuditQuerySchema, AuditStatsSchema, type AuditEvent } from './AuditContract';
2
+ export {
3
+ McpsContract,
4
+ ServiceOverviewSchema,
5
+ ServerInfoSchema,
6
+ ServerTypeInfoSchema,
7
+ ModelInfoSchema,
8
+ RequestStatsSchema,
9
+ ToolInfoSchema,
10
+ ToolParameterSchema,
11
+ type ServiceOverview,
12
+ type ServerInfo,
13
+ type ServerTypeInfo,
14
+ type ModelInfo,
15
+ type RequestStats,
16
+ type ToolInfo,
17
+ type ToolParameter,
18
+ } from './McpsContract';
@@ -0,0 +1,7 @@
1
+ import { createServer } from '#/server/server';
2
+
3
+ const { app } = createServer({});
4
+
5
+ export default {
6
+ fetch: app.fetch,
7
+ };
@@ -0,0 +1,157 @@
1
+ import { Entity, Enum, PrimaryKey, Property } from '@mikro-orm/decorators/es';
2
+
3
+ /**
4
+ * Chat protocol type
5
+ */
6
+ export const ChatProtocolType = Object.freeze({
7
+ OpenAI: 'openai',
8
+ Anthropic: 'anthropic',
9
+ Gemini: 'gemini',
10
+ } as const);
11
+ export type ChatProtocolType = (typeof ChatProtocolType)[keyof typeof ChatProtocolType];
12
+
13
+ /**
14
+ * Request status
15
+ */
16
+ export const RequestStatus = Object.freeze({
17
+ Pending: 'pending',
18
+ Success: 'success',
19
+ Error: 'error',
20
+ Timeout: 'timeout',
21
+ } as const);
22
+ export type RequestStatus = (typeof RequestStatus)[keyof typeof RequestStatus];
23
+
24
+ /**
25
+ * Chat Request Entity for auditing and metering
26
+ */
27
+ @Entity({ tableName: 'chat_request' })
28
+ export class ChatRequestEntity {
29
+ @PrimaryKey({ type: 'integer' })
30
+ id!: number;
31
+
32
+ /** Unique request ID for tracing */
33
+ @Property({ type: 'string', unique: true })
34
+ requestId!: string;
35
+
36
+ /** Request timestamp */
37
+ @Property({ type: 'datetime' })
38
+ requestedAt: Date = new Date();
39
+
40
+ /** Response timestamp */
41
+ @Property({ type: 'datetime', nullable: true })
42
+ completedAt?: Date;
43
+
44
+ /** Request status */
45
+ @Enum(() => RequestStatus)
46
+ status: RequestStatus = RequestStatus.Pending;
47
+
48
+ /** HTTP method */
49
+ @Property({ type: 'string' })
50
+ method!: string;
51
+
52
+ /** Request path/endpoint */
53
+ @Property({ type: 'string' })
54
+ endpoint!: string;
55
+
56
+ /** Input protocol (client-facing) */
57
+ @Enum(() => ChatProtocolType)
58
+ inputProtocol!: ChatProtocolType;
59
+
60
+ /** Output protocol (upstream provider) */
61
+ @Enum(() => ChatProtocolType)
62
+ outputProtocol!: ChatProtocolType;
63
+
64
+ /** Model name requested */
65
+ @Property({ type: 'string' })
66
+ model!: string;
67
+
68
+ /** Resolved model name */
69
+ @Property({ type: 'string', nullable: true })
70
+ resolvedModel?: string;
71
+
72
+ /** Provider name */
73
+ @Property({ type: 'string', nullable: true })
74
+ provider?: string;
75
+
76
+ /** Upstream base URL */
77
+ @Property({ type: 'string', nullable: true })
78
+ upstreamUrl?: string;
79
+
80
+ /** Whether request was streaming */
81
+ @Property({ type: 'boolean', default: false })
82
+ streaming: boolean = false;
83
+
84
+ /** Input token count */
85
+ @Property({ type: 'integer', nullable: true })
86
+ inputTokens?: number;
87
+
88
+ /** Output token count */
89
+ @Property({ type: 'integer', nullable: true })
90
+ outputTokens?: number;
91
+
92
+ /** Total token count */
93
+ @Property({ type: 'integer', nullable: true })
94
+ totalTokens?: number;
95
+
96
+ /** Request duration in ms */
97
+ @Property({ type: 'integer', nullable: true })
98
+ durationMs?: number;
99
+
100
+ /** Time to first token in ms */
101
+ @Property({ type: 'integer', nullable: true })
102
+ ttftMs?: number;
103
+
104
+ /** HTTP status code */
105
+ @Property({ type: 'integer', nullable: true })
106
+ httpStatus?: number;
107
+
108
+ /** Error message */
109
+ @Property({ type: 'text', nullable: true })
110
+ errorMessage?: string;
111
+
112
+ /** Error code */
113
+ @Property({ type: 'string', nullable: true })
114
+ errorCode?: string;
115
+
116
+ /** Client IP */
117
+ @Property({ type: 'string', nullable: true })
118
+ clientIp?: string;
119
+
120
+ /** User agent */
121
+ @Property({ type: 'string', nullable: true })
122
+ userAgent?: string;
123
+
124
+ /** User ID */
125
+ @Property({ type: 'string', nullable: true })
126
+ userId?: string;
127
+
128
+ /** Organization ID */
129
+ @Property({ type: 'string', nullable: true })
130
+ orgId?: string;
131
+
132
+ /** API key ID (not the actual key) */
133
+ @Property({ type: 'string', nullable: true })
134
+ apiKeyId?: string;
135
+
136
+ /** Request metadata (JSON) */
137
+ @Property({ type: 'json', nullable: true })
138
+ requestMeta?: Record<string, unknown>;
139
+
140
+ /** Response metadata (JSON) */
141
+ @Property({ type: 'json', nullable: true })
142
+ responseMeta?: Record<string, unknown>;
143
+
144
+ /** Cost in credits (decimal string) */
145
+ @Property({ type: 'string', nullable: true })
146
+ cost?: string;
147
+
148
+ /** Currency */
149
+ @Property({ type: 'string', nullable: true })
150
+ currency?: string;
151
+
152
+ @Property({ type: 'datetime' })
153
+ createdAt: Date = new Date();
154
+
155
+ @Property({ type: 'datetime', onUpdate: () => new Date() })
156
+ updatedAt: Date = new Date();
157
+ }
@@ -0,0 +1,149 @@
1
+ import { Entity, Enum, PrimaryKey, Property } from '@mikro-orm/decorators/es';
2
+
3
+ /**
4
+ * MCP server type
5
+ */
6
+ export const McpServerType = Object.freeze({
7
+ TencentCls: 'tencent-cls',
8
+ Sql: 'sql',
9
+ Prometheus: 'prometheus',
10
+ Relay: 'relay',
11
+ Custom: 'custom',
12
+ } as const);
13
+ export type McpServerType = (typeof McpServerType)[keyof typeof McpServerType];
14
+
15
+ /**
16
+ * MCP request type (JSON-RPC method)
17
+ */
18
+ export const McpRequestType = Object.freeze({
19
+ Initialize: 'initialize',
20
+ ToolsList: 'tools/list',
21
+ ToolsCall: 'tools/call',
22
+ ResourcesList: 'resources/list',
23
+ ResourcesRead: 'resources/read',
24
+ PromptsList: 'prompts/list',
25
+ PromptsGet: 'prompts/get',
26
+ CompletionComplete: 'completion/complete',
27
+ LoggingSetLevel: 'logging/setLevel',
28
+ Ping: 'ping',
29
+ Other: 'other',
30
+ } as const);
31
+ export type McpRequestType = (typeof McpRequestType)[keyof typeof McpRequestType];
32
+
33
+ /**
34
+ * Request status
35
+ */
36
+ export const RequestStatus = Object.freeze({
37
+ Pending: 'pending',
38
+ Success: 'success',
39
+ Error: 'error',
40
+ Timeout: 'timeout',
41
+ } as const);
42
+ export type RequestStatus = (typeof RequestStatus)[keyof typeof RequestStatus];
43
+
44
+ /**
45
+ * MCP Request Entity for auditing
46
+ */
47
+ @Entity({ tableName: 'mcp_request' })
48
+ export class McpRequestEntity {
49
+ @PrimaryKey({ type: 'integer' })
50
+ id!: number;
51
+
52
+ /** Unique request ID */
53
+ @Property({ type: 'string' })
54
+ requestId!: string;
55
+
56
+ /** MCP session ID */
57
+ @Property({ type: 'string', nullable: true })
58
+ sessionId?: string;
59
+
60
+ /** Request timestamp */
61
+ @Property({ type: 'datetime' })
62
+ requestedAt: Date = new Date();
63
+
64
+ /** Response timestamp */
65
+ @Property({ type: 'datetime', nullable: true })
66
+ completedAt?: Date;
67
+
68
+ /** Request status */
69
+ @Enum(() => RequestStatus)
70
+ status: RequestStatus = RequestStatus.Pending;
71
+
72
+ /** HTTP method */
73
+ @Property({ type: 'string' })
74
+ method!: string;
75
+
76
+ /** Request path */
77
+ @Property({ type: 'string' })
78
+ path!: string;
79
+
80
+ /** MCP server name */
81
+ @Property({ type: 'string' })
82
+ serverName!: string;
83
+
84
+ /** MCP server type */
85
+ @Enum(() => McpServerType)
86
+ serverType: McpServerType = McpServerType.Custom;
87
+
88
+ /** MCP request type (JSON-RPC method) */
89
+ @Enum(() => McpRequestType)
90
+ mcpMethod: McpRequestType = McpRequestType.Other;
91
+
92
+ /** Tool name (for tools/call) */
93
+ @Property({ type: 'string', nullable: true })
94
+ toolName?: string;
95
+
96
+ /** Resource URI (for resources/read) */
97
+ @Property({ type: 'string', nullable: true })
98
+ resourceUri?: string;
99
+
100
+ /** Prompt name (for prompts/get) */
101
+ @Property({ type: 'string', nullable: true })
102
+ promptName?: string;
103
+
104
+ /** Request duration in ms */
105
+ @Property({ type: 'integer', nullable: true })
106
+ durationMs?: number;
107
+
108
+ /** HTTP status code */
109
+ @Property({ type: 'integer', nullable: true })
110
+ httpStatus?: number;
111
+
112
+ /** Error message */
113
+ @Property({ type: 'text', nullable: true })
114
+ errorMessage?: string;
115
+
116
+ /** Error code */
117
+ @Property({ type: 'string', nullable: true })
118
+ errorCode?: string;
119
+
120
+ /** Client IP */
121
+ @Property({ type: 'string', nullable: true })
122
+ clientIp?: string;
123
+
124
+ /** User agent */
125
+ @Property({ type: 'string', nullable: true })
126
+ userAgent?: string;
127
+
128
+ /** User ID */
129
+ @Property({ type: 'string', nullable: true })
130
+ userId?: string;
131
+
132
+ /** Request headers (JSON) */
133
+ @Property({ type: 'json', nullable: true })
134
+ requestHeaders?: Record<string, string>;
135
+
136
+ /** Request body (JSON) */
137
+ @Property({ type: 'json', nullable: true })
138
+ requestBody?: Record<string, unknown>;
139
+
140
+ /** Response metadata (JSON) */
141
+ @Property({ type: 'json', nullable: true })
142
+ responseMeta?: Record<string, unknown>;
143
+
144
+ @Property({ type: 'datetime' })
145
+ createdAt: Date = new Date();
146
+
147
+ @Property({ type: 'datetime', onUpdate: () => new Date() })
148
+ updatedAt: Date = new Date();
149
+ }