fa-mcp-sdk 0.2.239 → 0.2.243
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/cli-template/FA-MCP-SDK-DOC/00-FA-MCP-SDK-index.md +21 -15
- package/cli-template/FA-MCP-SDK-DOC/01-getting-started.md +93 -5
- package/cli-template/FA-MCP-SDK-DOC/02-1-tools-and-api.md +201 -9
- package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +1 -2
- package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +107 -25
- package/cli-template/FA-MCP-SDK-DOC/05-ad-authorization.md +90 -38
- package/cli-template/FA-MCP-SDK-DOC/06-utilities.md +136 -1
- package/cli-template/FA-MCP-SDK-DOC/07-testing-and-operations.md +92 -7
- package/cli-template/package.json +1 -1
- package/config/default.yaml +3 -3
- package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js +0 -9
- package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js.map +1 -1
- package/package.json +1 -1
|
@@ -54,16 +54,16 @@ npm install fa-mcp-sdk
|
|
|
54
54
|
|
|
55
55
|
## Documentation Structure
|
|
56
56
|
|
|
57
|
-
| File
|
|
58
|
-
|
|
59
|
-
| [01-getting-started.md](01-getting-started.md)
|
|
60
|
-
| [02-1-tools-and-api.md](02-1-tools-and-api.md)
|
|
57
|
+
| File | Content | Read When |
|
|
58
|
+
|----------------------------------------------------------------|---------|-----------|
|
|
59
|
+
| [01-getting-started.md](01-getting-started.md) | Installation, project structure, `initMcpServer()`, core types (`McpServerData`, `IPromptData`, `IResourceData`), Configuration API (`AppConfig`, `getProjectData`, `getSafeAppConfig`) | Starting a new project, understanding project structure |
|
|
60
|
+
| [02-1-tools-and-api.md](02-1-tools-and-api.md) | Tool definitions, `toolHandler`, HTTP headers, REST API with tsoa decorators, OpenAPI/Swagger (`configureOpenAPI`, `OpenAPISpecResponse`, `SwaggerUIConfig`) | Creating MCP tools, adding REST endpoints, configuring Swagger |
|
|
61
61
|
| [02-2-prompts-and-resources.md](02-2-prompts-and-resources.md) | Standard prompts (agent-brief, agent-prompt), custom prompts, standard resources, custom resources, `requireAuth` | Configuring prompts and resources |
|
|
62
|
-
| [03-configuration.md](03-configuration.md)
|
|
63
|
-
| [04-authentication.md](04-authentication.md)
|
|
64
|
-
| [05-ad-authorization.md](05-ad-authorization.md)
|
|
65
|
-
| [06-utilities.md](06-utilities.md)
|
|
66
|
-
| [07-testing-and-operations.md](07-testing-and-operations.md)
|
|
62
|
+
| [03-configuration.md](03-configuration.md) | `appConfig`, YAML configuration, cache management, database integration (PostgreSQL) | Configuring the server, using cache or database |
|
|
63
|
+
| [04-authentication.md](04-authentication.md) | Multi-auth system, JWT tokens (`TTokenType`), Basic auth, server tokens, custom validators, `createAuthMW()`, Token Generator (`generateTokenApp`) | Setting up authentication, generating tokens |
|
|
64
|
+
| [05-ad-authorization.md](05-ad-authorization.md) | AD configuration types (`IADConfig`, `IDcConfig`), AD group-based authorization examples: HTTP level, all tools, per-tool | Implementing AD group restrictions |
|
|
65
|
+
| [06-utilities.md](06-utilities.md) | Error handling (`ServerError`), utility functions (`normalizeHeaders`, `getTools`), constants (`ROOT_PROJECT_DIR`), logging, events, Consul integration, graceful shutdown | Error handling, logging, service discovery |
|
|
66
|
+
| [07-testing-and-operations.md](07-testing-and-operations.md) | Test clients (STDIO, HTTP, SSE, Streamable HTTP - `McpStreamableHttpClient`), transport types, best practices | Testing, deployment, operations |
|
|
67
67
|
|
|
68
68
|
## Common Tasks Quick Reference
|
|
69
69
|
|
|
@@ -121,13 +121,16 @@ Read: `07-testing-and-operations.md`
|
|
|
121
121
|
import { initMcpServer, McpServerData } from 'fa-mcp-sdk';
|
|
122
122
|
|
|
123
123
|
// Configuration
|
|
124
|
-
import { appConfig } from 'fa-mcp-sdk';
|
|
124
|
+
import { appConfig, AppConfig, getProjectData, getSafeAppConfig, ROOT_PROJECT_DIR } from 'fa-mcp-sdk';
|
|
125
125
|
|
|
126
126
|
// Authentication
|
|
127
|
-
import { createAuthMW,
|
|
127
|
+
import { createAuthMW, generateToken, getAuthHeadersForTests, TTokenType, generateTokenApp } from 'fa-mcp-sdk';
|
|
128
128
|
|
|
129
129
|
// Tools
|
|
130
|
-
import { formatToolResult, ToolExecutionError } from 'fa-mcp-sdk';
|
|
130
|
+
import { formatToolResult, ToolExecutionError, getTools } from 'fa-mcp-sdk';
|
|
131
|
+
|
|
132
|
+
// Errors
|
|
133
|
+
import { ServerError, BaseMcpError, ValidationError } from 'fa-mcp-sdk';
|
|
131
134
|
|
|
132
135
|
// Database
|
|
133
136
|
import { queryMAIN, execMAIN, oneRowMAIN, checkMainDB } from 'fa-mcp-sdk';
|
|
@@ -139,13 +142,16 @@ import { getCache } from 'fa-mcp-sdk';
|
|
|
139
142
|
import { logger, fileLogger } from 'fa-mcp-sdk';
|
|
140
143
|
|
|
141
144
|
// Utilities
|
|
142
|
-
import { trim, ppj, toError, toStr } from 'fa-mcp-sdk';
|
|
145
|
+
import { trim, ppj, toError, toStr, normalizeHeaders } from 'fa-mcp-sdk';
|
|
143
146
|
|
|
144
147
|
// Test clients
|
|
145
|
-
import { McpHttpClient, McpStdioClient, McpSseClient } from 'fa-mcp-sdk';
|
|
148
|
+
import { McpHttpClient, McpStdioClient, McpSseClient, McpStreamableHttpClient } from 'fa-mcp-sdk';
|
|
146
149
|
|
|
147
150
|
// AD Groups
|
|
148
|
-
import { initADGroupChecker } from 'fa-mcp-sdk';
|
|
151
|
+
import { initADGroupChecker, IADConfig, IDcConfig } from 'fa-mcp-sdk';
|
|
152
|
+
|
|
153
|
+
// OpenAPI/Swagger
|
|
154
|
+
import { configureOpenAPI, createSwaggerUIAssetsMiddleware, OpenAPISpecResponse, SwaggerUIConfig } from 'fa-mcp-sdk';
|
|
149
155
|
```
|
|
150
156
|
|
|
151
157
|
## Project Structure
|
|
@@ -108,8 +108,8 @@ Main configuration interface for your MCP server.
|
|
|
108
108
|
```typescript
|
|
109
109
|
interface McpServerData {
|
|
110
110
|
// MCP Core Components
|
|
111
|
-
tools: Tool[];
|
|
112
|
-
toolHandler: (params:
|
|
111
|
+
tools: Tool[] | (() => Promise<Tool[]>); // Your tool definitions (static array or async function)
|
|
112
|
+
toolHandler: (params: IToolHandlerParams) => Promise<any>; // Tool execution function
|
|
113
113
|
|
|
114
114
|
// Agent Configuration
|
|
115
115
|
agentBrief: string; // Brief description of your agent
|
|
@@ -121,7 +121,8 @@ interface McpServerData {
|
|
|
121
121
|
customResources?: IResourceData[] | null; // Custom resource definitions
|
|
122
122
|
|
|
123
123
|
// Authentication
|
|
124
|
-
customAuthValidator?: CustomAuthValidator;
|
|
124
|
+
customAuthValidator?: CustomAuthValidator; // Custom authentication validator function
|
|
125
|
+
tokenGenAuthHandler?: TokenGenAuthHandler; // Custom authorization for Token Generator admin page
|
|
125
126
|
|
|
126
127
|
// HTTP Server Components (for HTTP transport)
|
|
127
128
|
httpComponents?: {
|
|
@@ -130,13 +131,20 @@ interface McpServerData {
|
|
|
130
131
|
|
|
131
132
|
// UI Assets
|
|
132
133
|
assets?: {
|
|
133
|
-
|
|
134
|
+
logoSvg?: string; // SVG content for logo/favicon
|
|
134
135
|
maintainerHtml?: string; // Support contact HTML snippet
|
|
135
136
|
};
|
|
136
137
|
|
|
137
138
|
// Consul Integration
|
|
138
139
|
getConsulUIAddress?: (serviceId: string) => string; // Function to generate Consul UI URLs
|
|
139
140
|
}
|
|
141
|
+
|
|
142
|
+
interface IToolHandlerParams {
|
|
143
|
+
name: string;
|
|
144
|
+
arguments?: any;
|
|
145
|
+
headers?: Record<string, string>;
|
|
146
|
+
payload?: { user: string; [key: string]: any } | undefined; // JWT payload if authenticated
|
|
147
|
+
}
|
|
140
148
|
```
|
|
141
149
|
|
|
142
150
|
### `IPromptData`
|
|
@@ -184,9 +192,13 @@ interface IResourceData {
|
|
|
184
192
|
title?: string; // Optional display title
|
|
185
193
|
description: string; // Human-readable description
|
|
186
194
|
mimeType: string; // MIME type (e.g., "text/plain", "application/json")
|
|
187
|
-
content: IResourceContent; // Static
|
|
195
|
+
content: IResourceContent; // Static string, object, or dynamic function
|
|
188
196
|
requireAuth?: boolean; // Whether authentication is required
|
|
189
197
|
}
|
|
198
|
+
|
|
199
|
+
// Content types for resources
|
|
200
|
+
type IResourceContent = string | object | TResourceContentFunction;
|
|
201
|
+
type TResourceContentFunction = (uri: string) => string | Promise<string>;
|
|
190
202
|
```
|
|
191
203
|
|
|
192
204
|
Example `src/custom-resources.ts`:
|
|
@@ -205,3 +217,79 @@ export const customResources: IResourceData[] = [
|
|
|
205
217
|
},
|
|
206
218
|
];
|
|
207
219
|
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Configuration API
|
|
224
|
+
|
|
225
|
+
### `AppConfig`
|
|
226
|
+
|
|
227
|
+
Base configuration type for MCP server applications. Extends multiple configuration interfaces for database, logging, web server, MCP, and Active Directory settings.
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
import { appConfig, AppConfig } from 'fa-mcp-sdk';
|
|
231
|
+
|
|
232
|
+
// appConfig is a singleton with merged configuration from:
|
|
233
|
+
// - config/default.yaml (base)
|
|
234
|
+
// - config/{NODE_ENV}.yaml (environment-specific)
|
|
235
|
+
// - Environment variables (highest priority)
|
|
236
|
+
|
|
237
|
+
// Access configuration values
|
|
238
|
+
const port = appConfig.webServer.port;
|
|
239
|
+
const serviceName = appConfig.name;
|
|
240
|
+
const isAuthEnabled = appConfig.webServer.auth.enabled;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Key Properties:**
|
|
244
|
+
|
|
245
|
+
| Property | Type | Description |
|
|
246
|
+
|----------|------|-------------|
|
|
247
|
+
| `name` | string | Package name from package.json |
|
|
248
|
+
| `shortName` | string | Name without 'mcp' suffix |
|
|
249
|
+
| `version` | string | Package version |
|
|
250
|
+
| `description` | string | Package description |
|
|
251
|
+
| `webServer` | object | HTTP server configuration (host, port, auth) |
|
|
252
|
+
| `mcp` | object | MCP protocol settings (transportType, rateLimit) |
|
|
253
|
+
| `logger` | object | Logging configuration (level, useFileLogger) |
|
|
254
|
+
| `ad` | object | Active Directory configuration |
|
|
255
|
+
| `consul` | object | Consul service discovery settings |
|
|
256
|
+
|
|
257
|
+
### `getProjectData()`
|
|
258
|
+
|
|
259
|
+
Retrieves the MCP server project data that was passed to `initMcpServer()`.
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import { getProjectData, McpServerData } from 'fa-mcp-sdk';
|
|
263
|
+
|
|
264
|
+
// Function Signature:
|
|
265
|
+
function getProjectData(): McpServerData;
|
|
266
|
+
|
|
267
|
+
// Example - Access project data from anywhere in your application:
|
|
268
|
+
const projectData = getProjectData();
|
|
269
|
+
console.log('Agent brief:', projectData.agentBrief);
|
|
270
|
+
console.log('Tools count:', projectData.tools.length);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### `getSafeAppConfig()`
|
|
274
|
+
|
|
275
|
+
Returns a deep clone of the application configuration with sensitive data masked. Use this for logging configuration without exposing secrets.
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { getSafeAppConfig } from 'fa-mcp-sdk';
|
|
279
|
+
|
|
280
|
+
// Function Signature:
|
|
281
|
+
function getSafeAppConfig(): any;
|
|
282
|
+
|
|
283
|
+
// Example - Log configuration safely:
|
|
284
|
+
const safeConfig = getSafeAppConfig();
|
|
285
|
+
console.log('Current configuration:', JSON.stringify(safeConfig, null, 2));
|
|
286
|
+
|
|
287
|
+
// Sensitive values are masked:
|
|
288
|
+
// - Database passwords: '[MASKED]'
|
|
289
|
+
// - JWT keys, API tokens, etc.
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Typical Use Cases:**
|
|
293
|
+
- Debugging configuration issues
|
|
294
|
+
- Audit logging of startup parameters
|
|
295
|
+
- Displaying configuration in admin interfaces
|
|
@@ -33,10 +33,11 @@ export const tools: Tool[] = [
|
|
|
33
33
|
### Tool Handler in `src/tools/handle-tool-call.ts`
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
|
-
import { formatToolResult, ToolExecutionError, logger } from 'fa-mcp-sdk';
|
|
36
|
+
import { formatToolResult, ToolExecutionError, logger, IToolHandlerParams } from 'fa-mcp-sdk';
|
|
37
37
|
|
|
38
|
-
export const handleToolCall = async (params:
|
|
39
|
-
const { name, arguments: args, headers } = params;
|
|
38
|
+
export const handleToolCall = async (params: IToolHandlerParams): Promise<any> => {
|
|
39
|
+
const { name, arguments: args, headers, payload } = params;
|
|
40
|
+
// payload contains { user: string, ... } if JWT authentication is enabled
|
|
40
41
|
|
|
41
42
|
logger.info(`Tool called: ${name}`);
|
|
42
43
|
|
|
@@ -93,12 +94,10 @@ The FA-MCP-SDK automatically passes normalized HTTP headers to your `toolHandler
|
|
|
93
94
|
**Example Usage:**
|
|
94
95
|
|
|
95
96
|
```typescript
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}): Promise<any> => {
|
|
101
|
-
const { name, arguments: args, headers } = params;
|
|
97
|
+
import { IToolHandlerParams } from 'fa-mcp-sdk';
|
|
98
|
+
|
|
99
|
+
export const handleToolCall = async (params: IToolHandlerParams): Promise<any> => {
|
|
100
|
+
const { name, arguments: args, headers, payload } = params;
|
|
102
101
|
|
|
103
102
|
// Access client information via headers
|
|
104
103
|
if (headers) {
|
|
@@ -319,3 +318,196 @@ export class PublicController {
|
|
|
319
318
|
}
|
|
320
319
|
}
|
|
321
320
|
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## OpenAPI/Swagger API Reference
|
|
325
|
+
|
|
326
|
+
### Types
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
import {
|
|
330
|
+
configureOpenAPI,
|
|
331
|
+
createSwaggerUIAssetsMiddleware,
|
|
332
|
+
OpenAPISpecResponse,
|
|
333
|
+
SwaggerUIConfig
|
|
334
|
+
} from 'fa-mcp-sdk';
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### `OpenAPISpecResponse`
|
|
338
|
+
|
|
339
|
+
Type representing the OpenAPI 3.0 specification structure.
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
interface OpenAPISpecResponse {
|
|
343
|
+
openapi: string; // '3.0.0'
|
|
344
|
+
info: {
|
|
345
|
+
title: string;
|
|
346
|
+
version: string;
|
|
347
|
+
description?: string;
|
|
348
|
+
};
|
|
349
|
+
servers?: Array<{
|
|
350
|
+
url: string;
|
|
351
|
+
description: string;
|
|
352
|
+
}>;
|
|
353
|
+
paths: Record<string, any>; // API endpoint definitions
|
|
354
|
+
components?: {
|
|
355
|
+
schemas?: Record<string, any>;
|
|
356
|
+
securitySchemes?: Record<string, any>;
|
|
357
|
+
};
|
|
358
|
+
tags?: Array<{
|
|
359
|
+
name: string;
|
|
360
|
+
description: string;
|
|
361
|
+
}>;
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### `SwaggerUIConfig`
|
|
366
|
+
|
|
367
|
+
Configuration options for customizing Swagger UI appearance and behavior.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
interface SwaggerUIConfig {
|
|
371
|
+
customCss?: string; // Custom CSS overrides
|
|
372
|
+
customSiteTitle?: string; // Browser tab title
|
|
373
|
+
customfavIcon?: string; // Custom favicon URL
|
|
374
|
+
swaggerOptions?: {
|
|
375
|
+
persistAuthorization?: boolean; // Remember auth between reloads
|
|
376
|
+
displayRequestDuration?: boolean; // Show request timing
|
|
377
|
+
docExpansion?: 'none' | 'list' | 'full'; // Default expansion
|
|
378
|
+
defaultModelsExpandDepth?: number; // Schema expansion depth
|
|
379
|
+
urls?: Array<{ // Multiple spec sources
|
|
380
|
+
name: string;
|
|
381
|
+
url: string;
|
|
382
|
+
}>;
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### `configureOpenAPI()`
|
|
388
|
+
|
|
389
|
+
Automatically configures and serves OpenAPI documentation for APIs with tsoa decorators. Called internally by `initMcpServer()` when `httpComponents.apiRouter` is provided.
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
// Function Signature:
|
|
393
|
+
async function configureOpenAPI(apiRouter?: Router | null): Promise<{
|
|
394
|
+
swaggerUi?: any;
|
|
395
|
+
swaggerSpecs?: any;
|
|
396
|
+
} | null>;
|
|
397
|
+
|
|
398
|
+
// Behavior:
|
|
399
|
+
// 1. Checks for swagger/openapi.yaml in project root
|
|
400
|
+
// 2. If not found, generates spec using tsoa programmatic API
|
|
401
|
+
// 3. Enhances spec with app configuration (servers, auth, info)
|
|
402
|
+
// 4. Creates /api/openapi.json and /api/openapi.yaml endpoints
|
|
403
|
+
// 5. Returns Swagger UI middleware for /docs endpoint
|
|
404
|
+
|
|
405
|
+
// The function is called automatically - typically no manual invocation needed
|
|
406
|
+
// To customize, modify config/default.yaml:
|
|
407
|
+
|
|
408
|
+
// config/default.yaml
|
|
409
|
+
swagger:
|
|
410
|
+
servers:
|
|
411
|
+
- url: 'https://api.production.com'
|
|
412
|
+
description: 'Production server'
|
|
413
|
+
- url: 'https://api.staging.com'
|
|
414
|
+
description: 'Staging server'
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### `createSwaggerUIAssetsMiddleware()`
|
|
418
|
+
|
|
419
|
+
Creates Express middleware for serving Swagger UI static assets. Used internally to set up the `/docs` endpoint.
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
import { createSwaggerUIAssetsMiddleware } from 'fa-mcp-sdk';
|
|
423
|
+
|
|
424
|
+
// Function Signature:
|
|
425
|
+
function createSwaggerUIAssetsMiddleware(): RequestHandler[];
|
|
426
|
+
|
|
427
|
+
// Returns swagger-ui-express.serve middleware array
|
|
428
|
+
// Typically used internally by configureOpenAPI()
|
|
429
|
+
|
|
430
|
+
// Manual usage (advanced):
|
|
431
|
+
import express from 'express';
|
|
432
|
+
const app = express();
|
|
433
|
+
|
|
434
|
+
app.use('/docs', createSwaggerUIAssetsMiddleware(), swaggerUiSetup);
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### OpenAPI Specification Generation
|
|
438
|
+
|
|
439
|
+
The OpenAPI specification is generated automatically when the server starts:
|
|
440
|
+
|
|
441
|
+
1. **Automatic Generation**: If `swagger/openapi.yaml` doesn't exist, it's generated from tsoa-decorated controllers
|
|
442
|
+
2. **Manual Regeneration**: Delete `swagger/openapi.yaml` and restart the server
|
|
443
|
+
3. **Source Files**: Controllers in `src/api/*.ts` are scanned for decorators
|
|
444
|
+
|
|
445
|
+
**Generated Spec Location:**
|
|
446
|
+
- `swagger/openapi.yaml` - YAML format (primary)
|
|
447
|
+
- Runtime endpoints: `/api/openapi.json`, `/api/openapi.yaml`
|
|
448
|
+
|
|
449
|
+
**Accessing Documentation:**
|
|
450
|
+
- Swagger UI: `http://localhost:{port}/docs`
|
|
451
|
+
- Raw spec: `http://localhost:{port}/api/openapi.json`
|
|
452
|
+
|
|
453
|
+
### Configuration via YAML
|
|
454
|
+
|
|
455
|
+
```yaml
|
|
456
|
+
# config/default.yaml
|
|
457
|
+
swagger:
|
|
458
|
+
servers:
|
|
459
|
+
- url: 'http://localhost:3000'
|
|
460
|
+
description: 'Development server'
|
|
461
|
+
- url: 'https://api.example.com'
|
|
462
|
+
description: 'Production server'
|
|
463
|
+
|
|
464
|
+
webServer:
|
|
465
|
+
auth:
|
|
466
|
+
enabled: true # Adds Bearer auth to OpenAPI spec
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Example: Complete API Setup
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
// src/api/router.ts
|
|
473
|
+
import { Router } from 'express';
|
|
474
|
+
import { Route, Get, Post, Body, Tags, Security } from 'tsoa';
|
|
475
|
+
|
|
476
|
+
export const apiRouter: Router = Router();
|
|
477
|
+
|
|
478
|
+
interface DataResponse {
|
|
479
|
+
id: string;
|
|
480
|
+
value: string;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
@Route('api')
|
|
484
|
+
export class DataController {
|
|
485
|
+
/**
|
|
486
|
+
* Get data by ID
|
|
487
|
+
* @param id Unique identifier
|
|
488
|
+
*/
|
|
489
|
+
@Get('data/{id}')
|
|
490
|
+
@Tags('Data')
|
|
491
|
+
@Security('bearerAuth')
|
|
492
|
+
public async getData(id: string): Promise<DataResponse> {
|
|
493
|
+
return { id, value: 'example' };
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Create new data entry
|
|
498
|
+
*/
|
|
499
|
+
@Post('data')
|
|
500
|
+
@Tags('Data')
|
|
501
|
+
@Security('bearerAuth')
|
|
502
|
+
public async createData(
|
|
503
|
+
@Body() body: { value: string }
|
|
504
|
+
): Promise<DataResponse> {
|
|
505
|
+
return { id: 'new-id', value: body.value };
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
After starting the server with this controller:
|
|
511
|
+
- Swagger UI available at `/docs`
|
|
512
|
+
- Endpoints documented with authentication requirements
|
|
513
|
+
- Request/response schemas generated from TypeScript types
|
|
@@ -315,8 +315,7 @@ const execMAIN = async (
|
|
|
315
315
|
): Promise<number | undefined> {...}
|
|
316
316
|
|
|
317
317
|
// Examples:
|
|
318
|
-
await execMAIN('INSERT INTO logs (message, created_at) VALUES ($1, $2)',
|
|
319
|
-
['Server started', new Date()]);
|
|
318
|
+
await execMAIN({ sqlText: 'INSERT INTO logs (message, created_at) VALUES ($1, $2)', sqlValues: ['Server started', new Date()] });
|
|
320
319
|
await execMAIN({ sqlText: 'UPDATE users SET active = $1 WHERE id = $2', sqlValues: [false, userId] });
|
|
321
320
|
|
|
322
321
|
// queryRsMAIN - execute SQL and return rows array directly
|
|
@@ -1,14 +1,44 @@
|
|
|
1
1
|
# Authentication and Security
|
|
2
2
|
|
|
3
|
+
## Authentication Types
|
|
4
|
+
|
|
5
|
+
### `TTokenType`
|
|
6
|
+
|
|
7
|
+
Type identifier for authentication methods. Used to indicate which authentication mechanism was used for a request.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { TTokenType } from 'fa-mcp-sdk';
|
|
11
|
+
|
|
12
|
+
// Type Definition:
|
|
13
|
+
type TTokenType = 'permanent' | 'JWT';
|
|
14
|
+
|
|
15
|
+
// Usage in authentication results:
|
|
16
|
+
interface AuthResult {
|
|
17
|
+
success: boolean;
|
|
18
|
+
authType?: TTokenType; // Indicates which auth method succeeded
|
|
19
|
+
username?: string;
|
|
20
|
+
// ...
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
| Value | Description |
|
|
25
|
+
|-------|-------------|
|
|
26
|
+
| `'permanent'` | Permanent server token from `permanentServerTokens` config |
|
|
27
|
+
| `'JWT'` | JSON Web Token authentication |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
3
31
|
## Token-based Authentication
|
|
4
32
|
|
|
5
33
|
```typescript
|
|
6
34
|
import {
|
|
7
35
|
ICheckTokenResult,
|
|
8
|
-
|
|
36
|
+
ITokenPayload,
|
|
9
37
|
generateToken
|
|
10
38
|
} from 'fa-mcp-sdk';
|
|
11
39
|
|
|
40
|
+
// Note: checkJwtToken is internal. Use createAuthMW() or getMultiAuthError() for authentication.
|
|
41
|
+
|
|
12
42
|
// Types used:
|
|
13
43
|
export interface ICheckTokenResult {
|
|
14
44
|
payload?: ITokenPayload, // Token payload with user data
|
|
@@ -22,26 +52,8 @@ export interface ITokenPayload {
|
|
|
22
52
|
[key: string]: any, // Additional payload data
|
|
23
53
|
}
|
|
24
54
|
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
const checkJwtToken = (arg: {
|
|
28
|
-
token: string,
|
|
29
|
-
expectedUser?: string,
|
|
30
|
-
expectedService?: string,
|
|
31
|
-
}): ICheckTokenResult {...}
|
|
32
|
-
|
|
33
|
-
// Example:
|
|
34
|
-
const tokenResult = checkJwtToken({
|
|
35
|
-
token: 'user_provided_token',
|
|
36
|
-
expectedUser: 'john_doe',
|
|
37
|
-
expectedService: 'my-mcp-server'
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (!tokenResult.errorReason) {
|
|
41
|
-
console.log('Valid token for user:', tokenResult.payload?.user);
|
|
42
|
-
} else {
|
|
43
|
-
console.log('Auth failed:', tokenResult.errorReason);
|
|
44
|
-
}
|
|
55
|
+
// Note: Token validation is handled automatically by createAuthMW() middleware.
|
|
56
|
+
// For programmatic validation, use getMultiAuthError() which supports all auth methods.
|
|
45
57
|
|
|
46
58
|
// generateToken - create JWT token
|
|
47
59
|
// Function Signature:
|
|
@@ -291,9 +303,10 @@ export interface AuthResult {
|
|
|
291
303
|
|
|
292
304
|
// Authentication detection result
|
|
293
305
|
export interface AuthDetectionResult {
|
|
294
|
-
configured: AuthType[];
|
|
295
|
-
|
|
296
|
-
|
|
306
|
+
configured: AuthType[]; // Authentication types found in configuration
|
|
307
|
+
configuredSet: Set<AuthType>; // Set of configured auth types for quick lookup
|
|
308
|
+
configuredTypes: string; // Comma-separated string of configured types
|
|
309
|
+
errors: Record<string, string[]>; // Configuration errors by auth type
|
|
297
310
|
}
|
|
298
311
|
```
|
|
299
312
|
|
|
@@ -320,7 +333,7 @@ function detectAuthConfiguration(): AuthDetectionResult {...}
|
|
|
320
333
|
// Example:
|
|
321
334
|
const detection = detectAuthConfiguration();
|
|
322
335
|
console.log('Configured auth types:', detection.configured);
|
|
323
|
-
console.log('
|
|
336
|
+
console.log('Configured types string:', detection.configuredTypes);
|
|
324
337
|
console.log('Configuration errors:', detection.errors);
|
|
325
338
|
|
|
326
339
|
// logAuthConfiguration - log auth system status (debugging)
|
|
@@ -542,3 +555,72 @@ See the separate documentation file `05-ad-authorization.md` for detailed exampl
|
|
|
542
555
|
1. **HTTP Server Level Access Restriction** - Using `customAuthValidator`
|
|
543
556
|
2. **Access Restriction to ALL MCP Tools** - Checking in `toolHandler`
|
|
544
557
|
3. **Access Restriction to SPECIFIC MCP Tools** - Per-tool group requirements
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## Token Generator Application
|
|
562
|
+
|
|
563
|
+
### `generateTokenApp()`
|
|
564
|
+
|
|
565
|
+
Launches a standalone Token Generator web application for administrative JWT token generation. The application provides a web UI for creating and validating tokens.
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
import { generateTokenApp } from 'fa-mcp-sdk';
|
|
569
|
+
|
|
570
|
+
// Function Signature:
|
|
571
|
+
function generateTokenApp(port?: number): Server;
|
|
572
|
+
|
|
573
|
+
// Start Token Generator on default port (3030)
|
|
574
|
+
generateTokenApp();
|
|
575
|
+
|
|
576
|
+
// Start on custom port
|
|
577
|
+
generateTokenApp(8080);
|
|
578
|
+
|
|
579
|
+
// Can also be run directly from command line:
|
|
580
|
+
// npx ts-node node_modules/fa-mcp-sdk/dist/core/auth/token-generator/server.js
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
**Features:**
|
|
584
|
+
- Web UI for JWT token generation
|
|
585
|
+
- Token validation interface
|
|
586
|
+
- NTLM authentication support (if configured in AD settings)
|
|
587
|
+
- Service info endpoint with authentication status
|
|
588
|
+
|
|
589
|
+
**Environment Variables:**
|
|
590
|
+
- `TOKEN_GEN_PORT` - Override default port (3030)
|
|
591
|
+
|
|
592
|
+
**Endpoints:**
|
|
593
|
+
|
|
594
|
+
| Endpoint | Method | Description |
|
|
595
|
+
|-----------------------------|--------|---------------------------|
|
|
596
|
+
| `/` | GET | Token Generator web UI |
|
|
597
|
+
| `/admin/api/generate-token` | POST | Generate new JWT token |
|
|
598
|
+
| `/admin/api/validate-token` | POST | Validate existing token |
|
|
599
|
+
| `/admin/api/service-info` | GET | Get service information |
|
|
600
|
+
| `/admin/api/auth-status` | GET | Get authentication status |
|
|
601
|
+
| `/admin/logout` | GET | Logout endpoint |
|
|
602
|
+
|
|
603
|
+
**Request Body for Token Generation:**
|
|
604
|
+
|
|
605
|
+
```typescript
|
|
606
|
+
interface GenerateTokenRequest {
|
|
607
|
+
user: string; // Username for the token
|
|
608
|
+
timeValue: number; // Duration value
|
|
609
|
+
timeUnit: 'minutes' | 'hours' | 'days' | 'months' | 'years';
|
|
610
|
+
payload?: Record<string, any>; // Optional additional payload
|
|
611
|
+
}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
**Example Usage:**
|
|
615
|
+
|
|
616
|
+
```typescript
|
|
617
|
+
// Programmatic token generation (without UI)
|
|
618
|
+
import { generateToken } from 'fa-mcp-sdk';
|
|
619
|
+
|
|
620
|
+
// Generate a 1-hour token
|
|
621
|
+
const token = generateToken('john.doe', 3600, { role: 'admin' });
|
|
622
|
+
console.log('Generated token:', token);
|
|
623
|
+
|
|
624
|
+
// Token validation is handled automatically by createAuthMW() middleware
|
|
625
|
+
// or use getMultiAuthError() for programmatic validation
|
|
626
|
+
```
|
|
@@ -4,6 +4,76 @@ This document demonstrates how to implement additional authorization based on Ac
|
|
|
4
4
|
group membership. These examples assume JWT token authentication (`jwtToken`) is configured,
|
|
5
5
|
and the user information is extracted from the JWT payload.
|
|
6
6
|
|
|
7
|
+
## AD Configuration Types
|
|
8
|
+
|
|
9
|
+
### `IADConfig`
|
|
10
|
+
|
|
11
|
+
Main Active Directory configuration interface for group membership checks and NTLM authentication.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { IADConfig } from 'fa-mcp-sdk';
|
|
15
|
+
|
|
16
|
+
// Type Definition:
|
|
17
|
+
interface IADConfig {
|
|
18
|
+
ad: {
|
|
19
|
+
domains: {
|
|
20
|
+
// Key is domain name (e.g., 'OFFICE', 'CORP')
|
|
21
|
+
[domainName: string]: IDcConfig;
|
|
22
|
+
};
|
|
23
|
+
tlsOptions?: ConnectionOptions; // TLS options for LDAPS connections
|
|
24
|
+
strategy?: EAuthStrategy; // NTLM authentication strategy
|
|
25
|
+
groupCacheTtlMs?: number; // Cache TTL for group checks (default: 10 minutes)
|
|
26
|
+
dnCacheTtlMs?: number; // Cache TTL for DN lookups (default: 24 hours)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### `IDcConfig`
|
|
32
|
+
|
|
33
|
+
Domain Controller configuration for individual AD domains.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { IDcConfig } from 'fa-mcp-sdk';
|
|
37
|
+
|
|
38
|
+
// Type Definition:
|
|
39
|
+
interface IDcConfig {
|
|
40
|
+
controllers: string[]; // LDAP URLs: ['ldap://dc1.corp.com', 'ldap://dc2.corp.com']
|
|
41
|
+
username: string; // Service account for LDAP queries
|
|
42
|
+
password: string; // Service account password
|
|
43
|
+
baseDn?: string; // Base DN for searches (auto-derived from URL if not set)
|
|
44
|
+
default?: boolean; // Mark as default domain for operations
|
|
45
|
+
|
|
46
|
+
// Internal fields (assigned during config processing):
|
|
47
|
+
name?: string; // Domain name
|
|
48
|
+
hostReSource?: string; // RegExp source for hostname matching
|
|
49
|
+
hostRe?: RegExp; // Compiled hostname matcher
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Configuration Example (`config/default.yaml`):**
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
ad:
|
|
57
|
+
groupCacheTtlMs: 600000 # 10 minutes
|
|
58
|
+
dnCacheTtlMs: 86400000 # 24 hours
|
|
59
|
+
domains:
|
|
60
|
+
CORP:
|
|
61
|
+
default: true
|
|
62
|
+
controllers:
|
|
63
|
+
- 'ldap://dc1.corp.com'
|
|
64
|
+
- 'ldap://dc2.corp.com'
|
|
65
|
+
username: 'svc_mcp@corp.com'
|
|
66
|
+
password: '${AD_SERVICE_PASSWORD}' # From environment variable
|
|
67
|
+
baseDn: 'DC=corp,DC=com' # Optional, auto-derived if omitted
|
|
68
|
+
PARTNER:
|
|
69
|
+
controllers:
|
|
70
|
+
- 'ldap://dc1.partner.local'
|
|
71
|
+
username: 'svc_reader@partner.local'
|
|
72
|
+
password: '${AD_PARTNER_PASSWORD}'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
7
77
|
## Configuration for AD Group Authorization
|
|
8
78
|
|
|
9
79
|
First, extend your configuration to include the required AD group:
|
|
@@ -51,8 +121,9 @@ import {
|
|
|
51
121
|
CustomAuthValidator,
|
|
52
122
|
AuthResult,
|
|
53
123
|
initADGroupChecker,
|
|
54
|
-
checkJwtToken,
|
|
55
124
|
} from 'fa-mcp-sdk';
|
|
125
|
+
// Note: JWT validation is handled automatically by the SDK's multi-auth system.
|
|
126
|
+
// The customAuthValidator receives parsed JWT payload when jwtToken auth is enabled.
|
|
56
127
|
import { tools } from './tools/tools.js';
|
|
57
128
|
import { handleToolCall } from './tools/handle-tool-call.js';
|
|
58
129
|
import { AGENT_BRIEF } from './prompts/agent-brief.js';
|
|
@@ -67,38 +138,28 @@ const { isUserInGroup } = initADGroupChecker();
|
|
|
67
138
|
|
|
68
139
|
/**
|
|
69
140
|
* Custom authentication validator with AD group membership check
|
|
141
|
+
* This validator is called AFTER the SDK's standard JWT validation.
|
|
142
|
+
* The req object contains parsed authInfo from the standard auth flow.
|
|
70
143
|
* Returns 403 Forbidden if user is not in the required AD group
|
|
71
144
|
*/
|
|
72
145
|
const customAuthValidator: CustomAuthValidator = async (req): Promise<AuthResult> => {
|
|
73
|
-
|
|
146
|
+
// Extract user info from request (populated by standard auth)
|
|
147
|
+
const authInfo = (req as any).authInfo;
|
|
74
148
|
|
|
75
|
-
|
|
76
|
-
|
|
149
|
+
// If standard auth failed or no user info, let standard auth handle it
|
|
150
|
+
if (!authInfo?.username) {
|
|
151
|
+
return { success: false, error: 'User information not available' };
|
|
77
152
|
}
|
|
78
153
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
// Validate JWT token
|
|
82
|
-
const tokenResult = checkJwtToken({ token });
|
|
83
|
-
if (tokenResult.errorReason) {
|
|
84
|
-
return { success: false, error: tokenResult.errorReason };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const payload = tokenResult.payload;
|
|
88
|
-
if (!payload?.user) {
|
|
89
|
-
return { success: false, error: 'Invalid token: missing user' };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const username = payload.user;
|
|
154
|
+
const username = authInfo.username;
|
|
93
155
|
|
|
94
156
|
// Bypass group check if configured (for debugging)
|
|
95
157
|
if (config.groupAccess.bypassGroupCheck) {
|
|
96
158
|
return {
|
|
97
159
|
success: true,
|
|
98
|
-
authType:
|
|
160
|
+
authType: authInfo.authType,
|
|
99
161
|
username,
|
|
100
|
-
payload,
|
|
101
|
-
isTokenDecrypted: tokenResult.isTokenDecrypted,
|
|
162
|
+
payload: authInfo.payload,
|
|
102
163
|
};
|
|
103
164
|
}
|
|
104
165
|
|
|
@@ -116,10 +177,9 @@ const customAuthValidator: CustomAuthValidator = async (req): Promise<AuthResult
|
|
|
116
177
|
|
|
117
178
|
return {
|
|
118
179
|
success: true,
|
|
119
|
-
authType:
|
|
180
|
+
authType: authInfo.authType,
|
|
120
181
|
username,
|
|
121
|
-
payload,
|
|
122
|
-
isTokenDecrypted: tokenResult.isTokenDecrypted,
|
|
182
|
+
payload: authInfo.payload,
|
|
123
183
|
};
|
|
124
184
|
} catch (error) {
|
|
125
185
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -168,6 +228,7 @@ import {
|
|
|
168
228
|
logger,
|
|
169
229
|
appConfig,
|
|
170
230
|
initADGroupChecker,
|
|
231
|
+
IToolHandlerParams,
|
|
171
232
|
} from 'fa-mcp-sdk';
|
|
172
233
|
import { CustomAppConfig } from '../_types_/custom-config.js';
|
|
173
234
|
|
|
@@ -180,7 +241,7 @@ const { isUserInGroup } = initADGroupChecker();
|
|
|
180
241
|
/**
|
|
181
242
|
* Check if user has access to MCP tools based on AD group membership
|
|
182
243
|
*/
|
|
183
|
-
async function checkToolAccess(payload:
|
|
244
|
+
async function checkToolAccess(payload: IToolHandlerParams['payload']): Promise<void> {
|
|
184
245
|
// Skip check if bypass is enabled
|
|
185
246
|
if (config.groupAccess.bypassGroupCheck) {
|
|
186
247
|
return;
|
|
@@ -212,12 +273,7 @@ async function checkToolAccess(payload: { user: string; [key: string]: any } | u
|
|
|
212
273
|
}
|
|
213
274
|
}
|
|
214
275
|
|
|
215
|
-
export const handleToolCall = async (params: {
|
|
216
|
-
name: string;
|
|
217
|
-
arguments?: any;
|
|
218
|
-
headers?: Record<string, string>;
|
|
219
|
-
payload?: { user: string; [key: string]: any };
|
|
220
|
-
}): Promise<any> => {
|
|
276
|
+
export const handleToolCall = async (params: IToolHandlerParams): Promise<any> => {
|
|
221
277
|
const { name, arguments: args, headers, payload } = params;
|
|
222
278
|
|
|
223
279
|
logger.info(`Tool called: ${name} by user: ${payload?.user || 'unknown'}`);
|
|
@@ -317,6 +373,7 @@ import {
|
|
|
317
373
|
logger,
|
|
318
374
|
appConfig,
|
|
319
375
|
initADGroupChecker,
|
|
376
|
+
IToolHandlerParams,
|
|
320
377
|
} from 'fa-mcp-sdk';
|
|
321
378
|
import { CustomAppConfig } from '../_types_/custom-config.js';
|
|
322
379
|
|
|
@@ -331,7 +388,7 @@ const { isUserInGroup } = initADGroupChecker();
|
|
|
331
388
|
*/
|
|
332
389
|
async function checkToolAccess(
|
|
333
390
|
toolName: string,
|
|
334
|
-
payload:
|
|
391
|
+
payload: IToolHandlerParams['payload']
|
|
335
392
|
): Promise<void> {
|
|
336
393
|
const toolAccess = config.toolGroupAccess;
|
|
337
394
|
|
|
@@ -389,12 +446,7 @@ async function checkToolAccess(
|
|
|
389
446
|
}
|
|
390
447
|
}
|
|
391
448
|
|
|
392
|
-
export const handleToolCall = async (params: {
|
|
393
|
-
name: string;
|
|
394
|
-
arguments?: any;
|
|
395
|
-
headers?: Record<string, string>;
|
|
396
|
-
payload?: { user: string; [key: string]: any };
|
|
397
|
-
}): Promise<any> => {
|
|
449
|
+
export const handleToolCall = async (params: IToolHandlerParams): Promise<any> => {
|
|
398
450
|
const { name, arguments: args, headers, payload } = params;
|
|
399
451
|
|
|
400
452
|
logger.info(`Tool called: ${name} by user: ${payload?.user || 'unknown'}`);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
### Custom Error Classes
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
|
-
import { BaseMcpError, ToolExecutionError, ValidationError } from 'fa-mcp-sdk';
|
|
8
|
+
import { BaseMcpError, ToolExecutionError, ValidationError, ServerError } from 'fa-mcp-sdk';
|
|
9
9
|
|
|
10
10
|
// Create custom error types
|
|
11
11
|
class MyCustomError extends BaseMcpError {
|
|
@@ -24,6 +24,40 @@ if (toolFailed) {
|
|
|
24
24
|
}
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
### `ServerError`
|
|
28
|
+
|
|
29
|
+
Server-related error class for internal MCP server failures. Use for unexpected server-side errors that aren't tool-specific.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { ServerError } from 'fa-mcp-sdk';
|
|
33
|
+
|
|
34
|
+
// Class Definition:
|
|
35
|
+
class ServerError extends BaseMcpError {
|
|
36
|
+
constructor(
|
|
37
|
+
message: string,
|
|
38
|
+
details?: Record<string, unknown>,
|
|
39
|
+
printed?: boolean
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Examples:
|
|
44
|
+
throw new ServerError('Database connection failed');
|
|
45
|
+
|
|
46
|
+
throw new ServerError('Configuration error', {
|
|
47
|
+
configKey: 'webServer.port',
|
|
48
|
+
expected: 'number',
|
|
49
|
+
received: 'string'
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// With printed flag (prevents duplicate logging)
|
|
53
|
+
throw new ServerError('Internal error', undefined, true);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Properties:**
|
|
57
|
+
- `code`: Always `'SERVER_ERROR'`
|
|
58
|
+
- `httpStatus`: Always `500`
|
|
59
|
+
- `details`: Optional additional error context
|
|
60
|
+
|
|
27
61
|
### Error Utilities
|
|
28
62
|
|
|
29
63
|
```typescript
|
|
@@ -79,6 +113,35 @@ addErrorMessage(originalError, 'Database operation failed');
|
|
|
79
113
|
|
|
80
114
|
---
|
|
81
115
|
|
|
116
|
+
## Constants
|
|
117
|
+
|
|
118
|
+
### `ROOT_PROJECT_DIR`
|
|
119
|
+
|
|
120
|
+
Absolute path to the project root directory. Calculated at runtime based on `process.cwd()`.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { ROOT_PROJECT_DIR } from 'fa-mcp-sdk';
|
|
124
|
+
|
|
125
|
+
// Constant Definition:
|
|
126
|
+
const ROOT_PROJECT_DIR: string = process.cwd();
|
|
127
|
+
|
|
128
|
+
// Example usage:
|
|
129
|
+
import * as path from 'path';
|
|
130
|
+
|
|
131
|
+
const configPath = path.join(ROOT_PROJECT_DIR, 'config', 'default.yaml');
|
|
132
|
+
const assetsPath = path.join(ROOT_PROJECT_DIR, 'src', 'assets');
|
|
133
|
+
|
|
134
|
+
console.log('Project root:', ROOT_PROJECT_DIR);
|
|
135
|
+
// Output: /home/user/my-mcp-server
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Use Cases:**
|
|
139
|
+
- Building absolute paths to project files
|
|
140
|
+
- Locating configuration files
|
|
141
|
+
- Resolving asset paths
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
82
145
|
## Utility Functions
|
|
83
146
|
|
|
84
147
|
### General Utilities
|
|
@@ -165,6 +228,78 @@ const logoContent = getAsset('logo.svg'); // Reads from src/asset/logo.s
|
|
|
165
228
|
const iconContent = getAsset('icons/star.svg'); // Reads from src/asset/icons/star.svg
|
|
166
229
|
```
|
|
167
230
|
|
|
231
|
+
### HTTP Utilities
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import { normalizeHeaders } from 'fa-mcp-sdk';
|
|
235
|
+
|
|
236
|
+
// normalizeHeaders - Normalize HTTP headers for consistent access
|
|
237
|
+
// Function Signature:
|
|
238
|
+
function normalizeHeaders(headers: Record<string, any>): Record<string, string>;
|
|
239
|
+
|
|
240
|
+
// Features:
|
|
241
|
+
// - Converts all header names to lowercase
|
|
242
|
+
// - Joins array values with ', ' separator
|
|
243
|
+
// - Filters out null/undefined values
|
|
244
|
+
// - Converts non-string values to strings
|
|
245
|
+
|
|
246
|
+
// Example:
|
|
247
|
+
const rawHeaders = {
|
|
248
|
+
'Authorization': 'Bearer token123',
|
|
249
|
+
'X-Custom-Header': 'value',
|
|
250
|
+
'Accept-Language': ['en', 'ru'],
|
|
251
|
+
'X-Null-Header': null,
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const normalized = normalizeHeaders(rawHeaders);
|
|
255
|
+
// Result:
|
|
256
|
+
// {
|
|
257
|
+
// 'authorization': 'Bearer token123',
|
|
258
|
+
// 'x-custom-header': 'value',
|
|
259
|
+
// 'accept-language': 'en, ru'
|
|
260
|
+
// }
|
|
261
|
+
|
|
262
|
+
// Common use case - accessing headers in tool handler:
|
|
263
|
+
import { IToolHandlerParams } from 'fa-mcp-sdk';
|
|
264
|
+
|
|
265
|
+
export const handleToolCall = async (params: IToolHandlerParams): Promise<any> => {
|
|
266
|
+
const { headers } = params;
|
|
267
|
+
|
|
268
|
+
// Headers are already normalized by SDK, access with lowercase keys
|
|
269
|
+
const authHeader = headers?.authorization;
|
|
270
|
+
const userAgent = headers?.['user-agent'];
|
|
271
|
+
const clientIP = headers?.['x-real-ip'] || headers?.['x-forwarded-for'];
|
|
272
|
+
|
|
273
|
+
// ...
|
|
274
|
+
};
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Tool Utilities
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import { getTools } from 'fa-mcp-sdk';
|
|
281
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
282
|
+
|
|
283
|
+
// getTools - Get the list of registered MCP tools
|
|
284
|
+
// Function Signature:
|
|
285
|
+
async function getTools(): Promise<Tool[]>;
|
|
286
|
+
|
|
287
|
+
// Retrieves tools from the project data passed to initMcpServer()
|
|
288
|
+
// Supports both static arrays and dynamic tool functions
|
|
289
|
+
|
|
290
|
+
// Example:
|
|
291
|
+
const tools = await getTools();
|
|
292
|
+
console.log(`Registered tools: ${tools.length}`);
|
|
293
|
+
tools.forEach(tool => {
|
|
294
|
+
console.log(`- ${tool.name}: ${tool.description}`);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Useful for:
|
|
298
|
+
// - Introspection and debugging
|
|
299
|
+
// - Dynamic tool documentation
|
|
300
|
+
// - Tool validation in tests
|
|
301
|
+
```
|
|
302
|
+
|
|
168
303
|
### Network Utilities
|
|
169
304
|
|
|
170
305
|
```typescript
|
|
@@ -8,8 +8,7 @@ Create tests in your `tests/` directory:
|
|
|
8
8
|
|
|
9
9
|
**`tests/utils.ts`** - Test utilities:
|
|
10
10
|
```typescript
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// Test result interface for tracking test outcomes
|
|
13
12
|
export interface ITestResult {
|
|
14
13
|
fullId: string;
|
|
15
14
|
toolName: string;
|
|
@@ -22,11 +21,21 @@ export interface ITestResult {
|
|
|
22
21
|
error: string | null;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
// Example utility functions for your test suite
|
|
25
|
+
export const formatResultAsMarkdown = (result: ITestResult): string => {
|
|
26
|
+
const statusIcon = result.status === 'passed' ? '✅' : '❌';
|
|
27
|
+
return `${statusIcon} ${result.toolName} - ${result.description}\n` +
|
|
28
|
+
`Duration: ${result.duration}ms\n` +
|
|
29
|
+
(result.error ? `Error: ${result.error}\n` : '');
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const logResultToFile = async (result: ITestResult): Promise<void> => {
|
|
33
|
+
const fs = await import('fs/promises');
|
|
34
|
+
const path = await import('path');
|
|
35
|
+
const filename = `${result.toolName}.md`;
|
|
36
|
+
const filepath = path.join(process.cwd(), '_logs/mcp', filename);
|
|
37
|
+
await fs.writeFile(filepath, formatResultAsMarkdown(result), 'utf-8');
|
|
38
|
+
};
|
|
30
39
|
```
|
|
31
40
|
|
|
32
41
|
### Test Clients
|
|
@@ -77,6 +86,82 @@ const client = new McpSseClient('http://localhost:3000');
|
|
|
77
86
|
const result = await client.callTool('my_custom_tool', { query: 'test' });
|
|
78
87
|
```
|
|
79
88
|
|
|
89
|
+
**Streamable HTTP Transport Testing (MCP 2025 Specification):**
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { McpStreamableHttpClient } from 'fa-mcp-sdk';
|
|
93
|
+
|
|
94
|
+
// McpStreamableHttpClient - Test client for MCP Streamable HTTP transport
|
|
95
|
+
// Implements the new MCP 2025 streamable HTTP specification with NDJSON
|
|
96
|
+
// Supports long-lived connections, multiple requests/responses, and notifications
|
|
97
|
+
|
|
98
|
+
// Constructor:
|
|
99
|
+
const client = new McpStreamableHttpClient(baseUrl: string, options?: {
|
|
100
|
+
endpointPath?: string; // Default: '/mcp'
|
|
101
|
+
headers?: Record<string, string>;
|
|
102
|
+
requestTimeoutMs?: number; // Default: 120000 (2 minutes)
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Example usage:
|
|
106
|
+
const client = new McpStreamableHttpClient('http://localhost:3000', {
|
|
107
|
+
headers: { 'Authorization': 'Bearer your-token' },
|
|
108
|
+
requestTimeoutMs: 60000,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Initialize connection (required before other operations)
|
|
112
|
+
await client.initialize({
|
|
113
|
+
protocolVersion: '2024-11-05',
|
|
114
|
+
clientInfo: { name: 'test-client', version: '1.0.0' },
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
console.log('Server:', client.serverInfo);
|
|
118
|
+
console.log('Capabilities:', client.capabilities);
|
|
119
|
+
|
|
120
|
+
// Call tools
|
|
121
|
+
const toolResult = await client.callTool('my_custom_tool', { query: 'test' });
|
|
122
|
+
console.log('Tool result:', toolResult);
|
|
123
|
+
|
|
124
|
+
// Get prompts
|
|
125
|
+
const prompt = await client.getPrompt('agent_brief');
|
|
126
|
+
|
|
127
|
+
// List and read resources
|
|
128
|
+
const resources = await client.listResources();
|
|
129
|
+
const content = await client.readResource('custom-resource://data1');
|
|
130
|
+
|
|
131
|
+
// Subscribe to notifications
|
|
132
|
+
const unsubscribe = client.onNotification('notifications/tools/list_changed', (params) => {
|
|
133
|
+
console.log('Tools changed:', params);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Send custom RPC
|
|
137
|
+
const customResult = await client.sendRpc('custom/method', { foo: 'bar' });
|
|
138
|
+
|
|
139
|
+
// Close connection when done
|
|
140
|
+
await client.close();
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Key Features:**
|
|
144
|
+
- **NDJSON Streaming**: Newline-delimited JSON over HTTP for efficient communication
|
|
145
|
+
- **Bidirectional**: Supports both requests and server notifications
|
|
146
|
+
- **Persistent Connection**: Single HTTP connection for multiple operations
|
|
147
|
+
- **Timeout Handling**: Configurable request timeouts with automatic cleanup
|
|
148
|
+
|
|
149
|
+
**Available Methods:**
|
|
150
|
+
|
|
151
|
+
| Method | Description |
|
|
152
|
+
|-------------------------------------|-----------------------------------|
|
|
153
|
+
| `initialize(params)` | Initialize MCP session |
|
|
154
|
+
| `close()` | Close connection gracefully |
|
|
155
|
+
| `callTool(name, args, headers?)` | Execute an MCP tool |
|
|
156
|
+
| `getPrompt(name, args?)` | Retrieve a prompt |
|
|
157
|
+
| `listResources()` | List available resources |
|
|
158
|
+
| `readResource(uri)` | Read resource content |
|
|
159
|
+
| `listTools()` | List available tools |
|
|
160
|
+
| `listPrompts()` | List available prompts |
|
|
161
|
+
| `sendRpc(method, params, timeout?)` | Send custom JSON-RPC request |
|
|
162
|
+
| `notify(method, params?)` | Send notification (no response) |
|
|
163
|
+
| `onNotification(method, handler)` | Subscribe to server notifications |
|
|
164
|
+
|
|
80
165
|
### Test Categories and Recommendations
|
|
81
166
|
|
|
82
167
|
1. **Prompt Tests**:
|
package/config/default.yaml
CHANGED
|
@@ -78,10 +78,10 @@ consul:
|
|
|
78
78
|
token: '***'
|
|
79
79
|
service:
|
|
80
80
|
enable: {{consul.service.enable}} # true - Allows registration of the service with the consul
|
|
81
|
-
name: <name> # <name> will be replaced by <package.json>.name at initialization
|
|
81
|
+
name: <name> # Here you can specify an alternative name for the service. String "<name>" will be replaced by <package.json>.name at initialization
|
|
82
82
|
instance: '{{SERVICE_INSTANCE}}' # This value will be specified as a suffix in the id of the service
|
|
83
|
-
version: <version> # <version> will be replaced by <package.json>.version at initialization
|
|
84
|
-
description: <description> # <description> will be replaced by <package.json>.description at initialization
|
|
83
|
+
version: <version> # String "<version>" will be replaced by <package.json>.version at initialization
|
|
84
|
+
description: <description> # Here you can specify an alternative name description. String "<description>" will be replaced by <package.json>.description at initialization
|
|
85
85
|
tags: [ ] # If null or empty array - Will be pulled up from package.keywords at initialization
|
|
86
86
|
meta:
|
|
87
87
|
# "Home" page link template
|
|
@@ -57,13 +57,4 @@ export const tokenGenDomainConfig = {
|
|
|
57
57
|
strategy: isNTLMEnabled ? (appConfig.ad.strategy || 'NTLM') : undefined, // from config or default NTLM
|
|
58
58
|
tlsOptions: isNTLMEnabled ? appConfig.ad.tlsOptions : undefined, // from config if specified
|
|
59
59
|
};
|
|
60
|
-
// Debug info VVR
|
|
61
|
-
if (isNTLMEnabled) {
|
|
62
|
-
console.log(`[TOKEN-GEN] Configured domains: ${Object.keys(tokenGenDomains).join(', ')}`);
|
|
63
|
-
console.log(`[TOKEN-GEN] Default domain: ${tokenGenDomainConfig.defaultDomain}`);
|
|
64
|
-
console.log(`[TOKEN-GEN] Strategy: ${tokenGenDomainConfig.strategy}`);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
console.log('[TOKEN-GEN] NTLM authentication disabled - no domain configuration available');
|
|
68
|
-
}
|
|
69
60
|
//# sourceMappingURL=ntlm-domain-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ntlm-domain-config.js","sourceRoot":"","sources":["../../../../../src/core/auth/token-generator/ntlm/ntlm-domain-config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ntlm-domain-config.js","sourceRoot":"","sources":["../../../../../src/core/auth/token-generator/ntlm/ntlm-domain-config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fa-mcp-sdk",
|
|
3
3
|
"productName": "FA MCP SDK",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.243",
|
|
5
5
|
"description": "Core infrastructure and templates for building Model Context Protocol (MCP) servers with TypeScript",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/core/index.js",
|