fa-mcp-sdk 0.2.125 → 0.2.131

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 (58) hide show
  1. package/bin/fa-mcp.js +43 -12
  2. package/cli-template/config/_local.yaml +29 -11
  3. package/cli-template/config/custom-environment-variables.yaml +0 -6
  4. package/cli-template/config/default.yaml +34 -14
  5. package/cli-template/fa-mcp-sdk-spec.md +396 -189
  6. package/dist/core/_types_/config.d.ts +4 -17
  7. package/dist/core/_types_/config.d.ts.map +1 -1
  8. package/dist/core/_types_/types.d.ts +12 -15
  9. package/dist/core/_types_/types.d.ts.map +1 -1
  10. package/dist/core/auth/middleware.d.ts +9 -37
  11. package/dist/core/auth/middleware.d.ts.map +1 -1
  12. package/dist/core/auth/middleware.js +31 -146
  13. package/dist/core/auth/middleware.js.map +1 -1
  14. package/dist/core/auth/multi-auth.d.ts +10 -14
  15. package/dist/core/auth/multi-auth.d.ts.map +1 -1
  16. package/dist/core/auth/multi-auth.js +133 -220
  17. package/dist/core/auth/multi-auth.js.map +1 -1
  18. package/dist/core/auth/types.d.ts +1 -7
  19. package/dist/core/auth/types.d.ts.map +1 -1
  20. package/dist/core/auth/types.js +1 -10
  21. package/dist/core/auth/types.js.map +1 -1
  22. package/dist/core/bootstrap/init-config.d.ts.map +1 -1
  23. package/dist/core/bootstrap/init-config.js +4 -0
  24. package/dist/core/bootstrap/init-config.js.map +1 -1
  25. package/dist/core/index.d.ts +6 -6
  26. package/dist/core/index.d.ts.map +1 -1
  27. package/dist/core/index.js +5 -4
  28. package/dist/core/index.js.map +1 -1
  29. package/dist/core/utils/utils.d.ts +6 -0
  30. package/dist/core/utils/utils.d.ts.map +1 -1
  31. package/dist/core/utils/utils.js +25 -0
  32. package/dist/core/utils/utils.js.map +1 -1
  33. package/dist/core/web/server-http.d.ts.map +1 -1
  34. package/dist/core/web/server-http.js +32 -18
  35. package/dist/core/web/server-http.js.map +1 -1
  36. package/package.json +1 -1
  37. package/cli-template/src/_examples/custom-basic-auth-example.ts +0 -252
  38. package/cli-template/src/_examples/multi-auth-examples.ts +0 -333
  39. package/cli-template/src/_types_/common.d.ts +0 -27
  40. package/cli-template/src/api/router.ts +0 -35
  41. package/cli-template/src/api/swagger.ts +0 -167
  42. package/cli-template/src/asset/favicon.svg +0 -3
  43. package/cli-template/src/custom-resources.ts +0 -12
  44. package/cli-template/src/prompts/agent-brief.ts +0 -8
  45. package/cli-template/src/prompts/agent-prompt.ts +0 -10
  46. package/cli-template/src/prompts/custom-prompts.ts +0 -12
  47. package/cli-template/src/start.ts +0 -71
  48. package/cli-template/src/tools/handle-tool-call.ts +0 -55
  49. package/cli-template/src/tools/tools.ts +0 -88
  50. package/cli-template/tests/jest-simple-reporter.js +0 -10
  51. package/cli-template/tests/mcp/sse/mcp-sse-client-handling.md +0 -111
  52. package/cli-template/tests/mcp/sse/test-sse-npm-package.js +0 -96
  53. package/cli-template/tests/mcp/test-cases.js +0 -143
  54. package/cli-template/tests/mcp/test-http.js +0 -63
  55. package/cli-template/tests/mcp/test-sse.js +0 -67
  56. package/cli-template/tests/mcp/test-stdio.js +0 -78
  57. package/cli-template/tests/utils.ts +0 -154
  58. package/cli-template/yarn.lock +0 -6375
@@ -1,333 +0,0 @@
1
- /**
2
- * Примеры использования системы мультиаутентификации fa-mcp-sdk
3
- */
4
-
5
- import express from 'express';
6
- // @ts-ignore
7
- import { appConfig, enhancedAuthTokenMW, createConfigurableAuthMiddleware, getMultiAuthError, getAuthInfo, checkMultiAuth, detectAuthConfiguration, logAuthConfiguration } from 'fa-mcp-sdk';
8
-
9
- // ========================================================================
10
- // ПРИМЕР 1: ПРОСТАЯ ЗАМЕНА MIDDLEWARE
11
- // ========================================================================
12
-
13
- const app = express();
14
-
15
- // Вместо старого authTokenMW используем enhancedAuthTokenMW
16
- app.use('/api', enhancedAuthTokenMW);
17
-
18
- app.get('/api/protected', (req, res) => {
19
- const authInfo = (req as any).authInfo;
20
- res.json({
21
- message: 'Access granted',
22
- authType: authInfo?.authType,
23
- username: authInfo?.username,
24
- tokenType: authInfo?.tokenType,
25
- });
26
- });
27
-
28
- // ========================================================================
29
- // ПРИМЕР 2: КОНФИГУРИРУЕМЫЙ MIDDLEWARE
30
- // ========================================================================
31
-
32
- // Middleware с логированием конфигурации при запуске
33
- const authWithLogging = createConfigurableAuthMiddleware({
34
- logConfiguration: true,
35
- forceMultiAuth: false, // Автоматически определяет нужна ли мультиаут
36
- });
37
-
38
- app.use('/api/v2', authWithLogging);
39
-
40
- // ========================================================================
41
- // ПРИМЕР 3: КАСТОМНАЯ ЛОГИКА АУТЕНТИФИКАЦИИ
42
- // ========================================================================
43
-
44
- app.use('/api/custom', async (req, res, next) => {
45
- // Публичные эндпоинты
46
- if (req.path.startsWith('/api/custom/public')) {
47
- return next();
48
- }
49
-
50
- // Для админских эндпоинтов требуем только permanent tokens
51
- if (req.path.startsWith('/api/custom/admin')) {
52
- const token = (req.headers.authorization || '').replace(/^Bearer */, '');
53
- const auth = appConfig.webServer.auth;
54
-
55
- if (auth.permanentServerTokens.includes(token)) {
56
- return next();
57
- } else {
58
- return res.status(403).json({ error: 'Admin access required' });
59
- }
60
- }
61
-
62
- try {
63
- // Для остальных используем полную мультиаутентификацию
64
- const authError = await getMultiAuthError(req);
65
- if (authError) {
66
- res.status(authError.code).send(authError.message);
67
- return;
68
- }
69
- next();
70
- } catch (error) {
71
- res.status(500).send('Authentication error');
72
- return;
73
- }
74
- });
75
-
76
- // ========================================================================
77
- // ПРИМЕР 4: РОУТЕР С РАЗНЫМИ УРОВНЯМИ ДОСТУПА
78
- // ========================================================================
79
-
80
- const apiRouter = express.Router();
81
-
82
- // Публичные роуты - без аутентификации
83
- apiRouter.get('/health', (req, res) => {
84
- res.json({ status: 'ok' });
85
- });
86
-
87
- apiRouter.get('/info', (req, res) => {
88
- const authInfo = getAuthInfo();
89
- res.json({
90
- authEnabled: authInfo.enabled,
91
- configuredTypes: authInfo.configured,
92
- validTypes: authInfo.valid,
93
- usingMultiAuth: authInfo.usingMultiAuth,
94
- });
95
- });
96
-
97
- // Защищенные роуты - с мультиаутентификацией
98
- apiRouter.use('/protected', enhancedAuthTokenMW);
99
-
100
- apiRouter.get('/protected/profile', (req, res) => {
101
- const authInfo = (req as any).authInfo;
102
- res.json({
103
- profile: {
104
- authType: authInfo.authType,
105
- username: authInfo.username || 'anonymous',
106
- permissions: getPermissionsForAuthType(authInfo.authType),
107
- },
108
- });
109
- });
110
-
111
- apiRouter.get('/protected/data', (req, res) => {
112
- const authInfo = (req as any).authInfo;
113
-
114
- // Разные данные в зависимости от типа аутентификации
115
- let data;
116
- switch (authInfo.authType) {
117
- case 'permanentServerTokens':
118
- data = { level: 'server', access: 'full' };
119
- break;
120
- case 'oauth2':
121
- data = { level: 'user', access: 'scoped', scopes: authInfo.payload?.scope };
122
- break;
123
- case 'basic':
124
- data = { level: 'basic', access: 'limited', username: authInfo.username };
125
- break;
126
- case 'pat':
127
- data = { level: 'api', access: 'token-based' };
128
- break;
129
- case 'jwtToken':
130
- data = { level: 'jwt', access: 'custom', payload: authInfo.payload };
131
- break;
132
- default:
133
- data = { level: 'unknown', access: 'none' };
134
- }
135
-
136
- res.json({ data, authInfo: authInfo.authType });
137
- });
138
-
139
- app.use('/api/v3', apiRouter);
140
-
141
- // ========================================================================
142
- // ПРИМЕР 5: ПРОГРАММНОЕ ТЕСТИРОВАНИЕ ТОКЕНОВ
143
- // ========================================================================
144
-
145
- app.post('/api/test-token', async (req, res) => {
146
- const { token } = req.body;
147
-
148
- if (!token) {
149
- return res.status(400).json({ error: 'Token required' });
150
- }
151
-
152
- try {
153
- const authConfig = appConfig.webServer.auth;
154
- const result = await checkMultiAuth(token, authConfig);
155
-
156
- return res.json({
157
- valid: result.success,
158
- authType: result.authType,
159
- tokenType: result.tokenType,
160
- error: result.error,
161
- username: result.username,
162
- hasPayload: !!result.payload,
163
- });
164
- } catch (error) {
165
- return res.status(500).json({ error: 'Authentication test failed' });
166
- }
167
- });
168
-
169
- // ========================================================================
170
- // ПРИМЕР 6: MIDDLEWARE ДЛЯ РАЗНЫХ ТИПОВ API
171
- // ========================================================================
172
-
173
- // REST API - требует любую валидную аутентификацию
174
- app.use('/rest', enhancedAuthTokenMW);
175
-
176
- // GraphQL API - требует user-level аутентификацию (не server tokens)
177
- app.use('/graphql', async (req, res, next) => {
178
- try {
179
- const authError = await getMultiAuthError(req);
180
- if (authError) {
181
- return res.status(authError.code).send(authError.message);
182
- }
183
-
184
- const authInfo = (req as any).authInfo;
185
- if (authInfo.authType === 'permanentServerTokens') {
186
- return res.status(403).json({
187
- error: 'GraphQL API requires user authentication, server tokens not allowed',
188
- });
189
- }
190
-
191
- return next();
192
- } catch (error) {
193
- return res.status(500).send('Authentication error');
194
- }
195
- });
196
-
197
- // WebSocket API - только JWT токены (для real-time connections)
198
- app.use('/ws', async (req, res, next) => {
199
- try {
200
- const authError = await getMultiAuthError(req);
201
- if (authError) {
202
- return res.status(authError.code).send(authError.message);
203
- }
204
-
205
- const authInfo = (req as any).authInfo;
206
- if (authInfo.authType !== 'jwtToken' && authInfo.authType !== 'oauth2') {
207
- return res.status(403).json({
208
- error: 'WebSocket API requires JWT or OAuth2 tokens for session management',
209
- });
210
- }
211
-
212
- return next();
213
- } catch {
214
- return res.status(500).send('Authentication error');
215
- }
216
- });
217
-
218
- // ========================================================================
219
- // УТИЛИТНЫЕ ФУНКЦИИ
220
- // ========================================================================
221
-
222
- export function getPermissionsForAuthType (authType: string): string[] {
223
- const permissions: Record<string, string[]> = {
224
- 'permanentServerTokens': ['read', 'write', 'admin', 'server'],
225
- 'oauth2': ['read', 'write', 'user'],
226
- 'jwtToken': ['read', 'write', 'session'],
227
- 'pat': ['read', 'write', 'api'],
228
- 'basic': ['read', 'basic'],
229
- };
230
-
231
- return permissions[authType] || ['read'];
232
- }
233
-
234
- // ========================================================================
235
- // ПРИМЕР 7: ИНИЦИАЛИЗАЦИЯ С ДИАГНОСТИКОЙ
236
- // ========================================================================
237
-
238
- export function initializeAuthSystem () {
239
- const authConfig = appConfig.webServer.auth;
240
-
241
- console.log('🔐 Initializing Multi-Authentication System...');
242
-
243
- // Диагностика конфигурации
244
- const detection = detectAuthConfiguration(authConfig);
245
-
246
- console.log('📊 Auth Configuration:');
247
- console.log(` Enabled: ${authConfig.enabled}`);
248
- console.log(` Configured: ${detection.configured.join(', ')}`);
249
- console.log(` Valid: ${detection.valid.join(', ')}`);
250
-
251
- if (Object.keys(detection.errors).length > 0) {
252
- console.warn('⚠️ Configuration Issues:');
253
- Object.entries(detection.errors).forEach(([type, errors]) => {
254
- console.warn(` ${type}: ${(errors as string[]).join(', ')}`);
255
- });
256
- }
257
-
258
- // Логирование для отладки
259
- logAuthConfiguration(authConfig);
260
-
261
- console.log('✅ Multi-Authentication System initialized successfully');
262
-
263
- return {
264
- configured: detection.configured,
265
- valid: detection.valid,
266
- errors: detection.errors,
267
- usingMultiAuth: !!(authConfig.pat || authConfig.basic || authConfig.oauth2),
268
- };
269
- }
270
-
271
- // ========================================================================
272
- // ПРИМЕР 8: ТЕСТИРОВАНИЕ КОНФИГУРАЦИИ
273
- // ========================================================================
274
-
275
- export async function testAuthConfiguration () {
276
- const authConfig = appConfig.webServer.auth;
277
-
278
- console.log('🧪 Testing Authentication Configuration...');
279
-
280
- const testCases = [
281
- // Тест permanent token
282
- {
283
- name: 'Permanent Server Token',
284
- token: authConfig.permanentServerTokens[0],
285
- expectedType: 'permanentServerTokens',
286
- },
287
- // Тест PAT
288
- {
289
- name: 'Personal Access Token',
290
- token: authConfig.pat,
291
- expectedType: 'pat',
292
- },
293
- // Тест basic auth
294
- {
295
- name: 'Basic Authentication',
296
- token: authConfig.basic
297
- ? Buffer.from(`${authConfig.basic.username}:${authConfig.basic.password}`).toString('base64')
298
- : undefined,
299
- expectedType: 'basic',
300
- },
301
- // Тест OAuth2
302
- {
303
- name: 'OAuth2 Bearer Token',
304
- token: authConfig.oauth2 ? `Bearer ${authConfig.oauth2.accessToken}` : undefined,
305
- expectedType: 'oauth2',
306
- },
307
- ];
308
-
309
- for (const testCase of testCases) {
310
- if (!testCase.token) {
311
- console.log(`⏭️ Skipping ${testCase.name}: not configured`);
312
- continue;
313
- }
314
-
315
- try {
316
- const result = await checkMultiAuth(testCase.token, authConfig);
317
-
318
- if (result.success && result.authType === testCase.expectedType) {
319
- console.log(`✅ ${testCase.name}: PASSED`);
320
- } else {
321
- console.log(`❌ ${testCase.name}: FAILED - ${result.error || 'Unexpected auth type'}`);
322
- }
323
- } catch (error) {
324
- console.log(`❌ ${testCase.name}: FAILED - Authentication test error`);
325
- }
326
- }
327
-
328
- console.log('🧪 Authentication testing completed');
329
- }
330
-
331
- // ========================================================================
332
- // ЭКСПОРТ ДЛЯ ИСПОЛЬЗОВАНИЯ
333
- // ========================================================================
@@ -1,27 +0,0 @@
1
- export interface ISearchParams {
2
- query: string; // Search query string
3
- limit?: number; // Maximum number of results (default: 20)
4
- threshold?: number; // Minimum similarity threshold (0-1)
5
- }
6
-
7
- export interface ISearchResultRow {
8
- similarity_score: number;
9
- word_similarity_score: number;
10
- final_score: number;
11
- similarity: number; // mapped from final_score
12
-
13
- [prop: string]: number | string;
14
- }
15
-
16
- export interface ISearchResultRow {
17
- similarity_score: number;
18
- word_similarity_score: number;
19
- final_score: number;
20
-
21
- [prop: string]: number | string;
22
- }
23
-
24
- export type ISearchResult = {
25
- similarity: number; // mapped from final_score
26
- [prop: string]: number | string | undefined;
27
- }[]
@@ -1,35 +0,0 @@
1
- import { Router, Request, Response } from 'express';
2
- import { logger, authTokenMW, IEndpointsOn404 } from 'fa-mcp-sdk';
3
-
4
- export const apiRouter: Router | null = Router();
5
-
6
- /**
7
- * Template for API routes
8
- * Modify this file to implement your specific API endpoints
9
- */
10
-
11
- // Example protected endpoint using auth middleware
12
- apiRouter.get('/example', authTokenMW, async (req: Request, res: Response) => {
13
- try {
14
- logger.info('Example endpoint called');
15
-
16
- res.json({
17
- success: true,
18
- message: 'This is a template endpoint',
19
- data: {
20
- timestamp: new Date().toISOString(),
21
- },
22
- });
23
- } catch (error) {
24
- logger.error('Error in example endpoint:', error);
25
- res.status(500).json({
26
- success: false,
27
- error: error instanceof Error ? error.message : 'Unknown error',
28
- });
29
- }
30
- });
31
-
32
- export const endpointsOn404: IEndpointsOn404 = {
33
- myEndpoints1: ['/my-endpoint-1', '/my-endpoint-2'],
34
- myEndpoint3: '/my-endpoint-3',
35
- };
@@ -1,167 +0,0 @@
1
- import swaggerJsdoc from 'swagger-jsdoc';
2
- import swaggerUi from 'swagger-ui-express';
3
- import { appConfig } from 'fa-mcp-sdk';
4
-
5
- /**
6
- * Generic Swagger configuration template for MCP Server
7
- * Customize this file according to your API endpoints and schemas
8
- */
9
-
10
- // Build servers array from config with fallback
11
- const buildServers = () => {
12
- const servers = [];
13
-
14
- // Use servers from config if available
15
- if (appConfig.swagger?.servers?.length) {
16
- appConfig.swagger.servers.forEach((server: any) => {
17
- servers.push({
18
- url: server.url,
19
- description: server.description
20
- });
21
- });
22
- } else {
23
- // Fallback to default development server
24
- servers.push({
25
- url: `http://localhost:${appConfig.webServer.port}`,
26
- description: 'Development server'
27
- });
28
- }
29
-
30
- return servers;
31
- };
32
-
33
- const options = {
34
- definition: {
35
- openapi: '3.0.0',
36
- info: {
37
- title: 'MCP Server API',
38
- version: appConfig.version,
39
- description: `
40
- REST API for your MCP Server. This is a template configuration.
41
- Customize the endpoints, schemas, and documentation according to your needs.
42
- `,
43
- },
44
- servers: buildServers(),
45
- components: {
46
- schemas: {
47
- HealthResponse: {
48
- type: 'object',
49
- description: 'Health check response',
50
- properties: {
51
- status: {
52
- type: 'string',
53
- example: 'ok'
54
- },
55
- timestamp: {
56
- type: 'string',
57
- format: 'date-time',
58
- example: '2024-11-05T12:00:00.000Z'
59
- },
60
- version: {
61
- type: 'string',
62
- example: '1.0.0'
63
- }
64
- },
65
- required: ['status', 'timestamp', 'version']
66
- },
67
- ErrorResponse: {
68
- type: 'object',
69
- description: 'Error response format',
70
- properties: {
71
- success: {
72
- type: 'boolean',
73
- description: 'Indicates failed operation',
74
- example: false
75
- },
76
- error: {
77
- type: 'string',
78
- description: 'Human-readable error message',
79
- example: 'Validation failed'
80
- },
81
- code: {
82
- type: 'string',
83
- description: 'Error code for programmatic handling',
84
- example: 'VALIDATION_ERROR'
85
- }
86
- },
87
- required: ['success', 'error', 'code']
88
- }
89
- }
90
- },
91
- paths: {
92
- '/health': {
93
- get: {
94
- summary: 'Health check',
95
- description: 'Simple health check endpoint for monitoring',
96
- tags: ['Server'],
97
- responses: {
98
- '200': {
99
- description: 'Service is healthy',
100
- content: {
101
- 'application/json': {
102
- schema: {
103
- $ref: '#/components/schemas/HealthResponse'
104
- }
105
- }
106
- }
107
- }
108
- }
109
- }
110
- },
111
- '/example': {
112
- get: {
113
- summary: 'Example endpoint',
114
- description: 'Template endpoint - customize as needed',
115
- tags: ['Example'],
116
- responses: {
117
- '200': {
118
- description: 'Success response',
119
- content: {
120
- 'application/json': {
121
- schema: {
122
- type: 'object',
123
- properties: {
124
- success: {
125
- type: 'boolean',
126
- example: true
127
- },
128
- message: {
129
- type: 'string',
130
- example: 'Template endpoint response'
131
- }
132
- }
133
- }
134
- }
135
- }
136
- },
137
- '400': {
138
- description: 'Bad request',
139
- content: {
140
- 'application/json': {
141
- schema: {
142
- $ref: '#/components/schemas/ErrorResponse'
143
- }
144
- }
145
- }
146
- }
147
- }
148
- }
149
- }
150
- },
151
- tags: [
152
- {
153
- name: 'Server',
154
- description: 'Server management endpoints'
155
- },
156
- {
157
- name: 'Example',
158
- description: 'Template endpoints to customize'
159
- }
160
- ]
161
- },
162
- apis: [] // Add your API files here if using JSDoc comments
163
- };
164
-
165
- const swaggerSpecs = swaggerJsdoc(options);
166
-
167
- export const swagger = { swaggerSpecs, swaggerUi };
@@ -1,3 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
2
- <rect width="16" height="16" fill="${appConfig.uiColor.primary || '#007ACC'}"/>
3
- </svg>
@@ -1,12 +0,0 @@
1
- // @ts-ignore
2
- import { IResourceData } from 'fa-mcp-sdk';
3
-
4
- export const customResources: IResourceData[] = [
5
- {
6
- uri: 'custom-resource://resource1',
7
- name: 'Custom Resource',
8
- description: 'Custom resource description',
9
- mimeType: 'text/plain',
10
- content: 'Custom resource content',
11
- }
12
- ];
@@ -1,8 +0,0 @@
1
- /**
2
- * Level 1: Brief agent description
3
- * Used when LLM selects agents from a list based on user query
4
- * LLM doesn't see tools at this level
5
- */
6
-
7
- export const AGENT_BRIEF = 'Agent brief';
8
-
@@ -1,10 +0,0 @@
1
- /**
2
- * Level 2: Agent description This prompt becomes visible to the LLM after the
3
- * agent router has selected this agent from among others based on their short
4
- * descriptions. At that point, the LLM gains access to the full list of tools
5
- * and this detailed prompt, which may include instructions on how to call those
6
- * tools. In simple scenarios, this prompt can be very short or even empty if
7
- * the tool descriptions alone are sufficient.
8
- */
9
-
10
- export const AGENT_PROMPT = 'Agent Prompt';
@@ -1,12 +0,0 @@
1
- import { IPromptData, IGetPromptRequest } from 'fa-mcp-sdk';
2
-
3
- export const customPrompts: IPromptData[] = [
4
- {
5
- name: 'custom_prompt',
6
- description: 'Custom prompt',
7
- arguments: [],
8
- content: (request: IGetPromptRequest) => {
9
- return `Custom prompt content ${request.method}`;
10
- },
11
- },
12
- ];
@@ -1,71 +0,0 @@
1
- // Import all project data from existing files
2
- // @ts-ignore
3
- import { appConfig, initMcpServer, McpServerData, getAsset } from 'fa-mcp-sdk';
4
- import { tools } from './tools/tools.js';
5
- import { handleToolCall } from './tools/handle-tool-call.js';
6
- import { AGENT_BRIEF } from './prompts/agent-brief.js';
7
- import { AGENT_PROMPT } from './prompts/agent-prompt.js';
8
- import { customPrompts } from './prompts/custom-prompts.js';
9
- import { customResources } from './custom-resources.js';
10
- import { apiRouter, endpointsOn404 } from './api/router.js';
11
- import { swagger } from './api/swagger.js';
12
-
13
- const isConsulProd = (process.env.NODE_CONSUL_ENV || process.env.NODE_ENV) === 'production';
14
-
15
- /**
16
- * Main function that assembles all project data and starts the MCP server
17
- */
18
- const startProject = async (): Promise<void> => {
19
- // Read favicon from assets
20
- const favicon = getAsset('favicon.svg')!;
21
-
22
- // Assemble all data to pass to the core
23
- const serverData: McpServerData = {
24
- // MCP components
25
- tools,
26
- toolHandler: handleToolCall,
27
-
28
- // Prompts
29
- agentBrief: AGENT_BRIEF,
30
- agentPrompt: AGENT_PROMPT,
31
- customPrompts,
32
- requiredHttpHeaders: [{ name: 'Authorization', description: 'JWT Token issued on request' }],
33
- // Resources
34
- customResources,
35
-
36
- // HTTP components
37
- httpComponents: {
38
- apiRouter,
39
- endpointsOn404,
40
- swagger: {
41
- swaggerSpecs: swagger.swaggerSpecs,
42
- swaggerUi: swagger.swaggerUi,
43
- },
44
- },
45
-
46
- // Assets
47
- assets: {
48
- favicon,
49
- maintainerHtml: '<a href="https://support.com/page/2805" target="_blank" rel="noopener" class="clickable">Support</a>',
50
- },
51
- // Function to get Consul UI address (if consul enabled: consul.service.enable = true)
52
- getConsulUIAddress: (serviceId: string) => {
53
- const { agent } = appConfig.consul || {};
54
- if (!agent?.dev?.host || !agent?.prd?.host) {
55
- return '--consul-ui-not-configured--';
56
- }
57
- return `${isConsulProd
58
- ? `https://${agent.prd.host}/ui/dc-msk-infra`
59
- : `https://${agent.dev.host}/ui/dc-dev`
60
- }/services/${serviceId}/instances`;
61
- },
62
- };
63
-
64
- // Start MCP server with assembled data
65
- await initMcpServer(serverData);
66
- };
67
-
68
- startProject().catch(error => {
69
- console.error('Failed to start project:', error);
70
- process.exit(1);
71
- });