fa-mcp-sdk 0.3.16 → 0.3.18

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 (50) hide show
  1. package/README.md +1 -1
  2. package/cli-template/.claude/agents/architect.md +99 -99
  3. package/cli-template/.claude/agents/auditor.md +92 -92
  4. package/cli-template/.claude/agents/fa-mcp-sdk.md +1 -1
  5. package/cli-template/.claude/agents/planner.md +122 -122
  6. package/cli-template/.claude/agents/prd-writer.md +88 -88
  7. package/cli-template/.claude/agents/refactor.md +74 -74
  8. package/cli-template/.claude/agents/worker.md +132 -132
  9. package/cli-template/CLAUDE.md +1 -1
  10. package/cli-template/FA-MCP-SDK-DOC/01-getting-started.md +1 -1
  11. package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +3 -0
  12. package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +77 -4
  13. package/cli-template/FA-MCP-SDK-DOC/05-ad-authorization.md +35 -16
  14. package/cli-template/README.md +105 -105
  15. package/cli-template/package.json +2 -2
  16. package/cli-template/prompt-example-new-MCP.md +2 -1
  17. package/cli-template/prompt_2026-03-17_13-53.md +15 -0
  18. package/cli-template/r/TEST HTTP.xml +9 -9
  19. package/cli-template/r/TEST SSE.xml +5 -5
  20. package/cli-template/r/TEST STDIO.xml +5 -5
  21. package/cli-template/r/generate-token.xml +13 -13
  22. package/cli-template/r/lint-fix-build.xml +12 -12
  23. package/cli-template/r/remove-nul.xml +11 -11
  24. package/config/custom-environment-variables.yaml +1 -0
  25. package/config/default.yaml +3 -0
  26. package/config/development.yaml +4 -4
  27. package/config/production.yaml +4 -4
  28. package/dist/core/_types_/config.d.ts +1 -0
  29. package/dist/core/_types_/config.d.ts.map +1 -1
  30. package/dist/core/auth/ip-check.d.ts +18 -0
  31. package/dist/core/auth/ip-check.d.ts.map +1 -0
  32. package/dist/core/auth/ip-check.js +148 -0
  33. package/dist/core/auth/ip-check.js.map +1 -0
  34. package/dist/core/auth/jwt.d.ts +1 -0
  35. package/dist/core/auth/jwt.d.ts.map +1 -1
  36. package/dist/core/auth/jwt.js +15 -1
  37. package/dist/core/auth/jwt.js.map +1 -1
  38. package/dist/core/auth/multi-auth.d.ts.map +1 -1
  39. package/dist/core/auth/multi-auth.js +19 -14
  40. package/dist/core/auth/multi-auth.js.map +1 -1
  41. package/dist/core/auth/token-generator/ntlm/ntlm-templates.js +221 -221
  42. package/dist/core/web/static/token-gen/index.html +9 -0
  43. package/dist/core/web/static/token-gen/logout.svg +4 -4
  44. package/dist/core/web/static/token-gen/script.js +7 -1
  45. package/dist/core/web/static/token-gen/user.svg +4 -4
  46. package/package.json +1 -1
  47. package/scripts/publish.sh +78 -78
  48. package/scripts/update-doc.js +18 -18
  49. package/config/local-2.yaml +0 -20
  50. package/config/local.yaml +0 -101
@@ -104,20 +104,52 @@ if (authError) {
104
104
 
105
105
  ### Custom Authentication
106
106
 
107
+ `customAuthValidator` runs **before** standard auth (`Authorization` header check).
108
+
109
+ **Execution order:**
110
+ 1. `customAuthValidator` is called first
111
+ 2. If `success: true` → request is allowed, standard auth is **skipped**
112
+ 3. If `success: false` → falls through to standard auth (`permanentServerTokens` / `basic` / `jwtToken`)
113
+ 4. If standard auth also fails → 401
114
+
115
+ This allows using service-specific credentials (e.g. `x-api-key`, `x-service-token`) as an alternative
116
+ to the MCP `Authorization` header, without disabling standard auth entirely.
117
+
107
118
  ```typescript
108
119
  import { CustomAuthValidator, AuthResult } from 'fa-mcp-sdk';
109
120
 
121
+ // Example: bypass MCP auth if service-specific header is present
110
122
  const customValidator: CustomAuthValidator = async (req): Promise<AuthResult> => {
111
123
  const apiKey = req.headers['x-api-key'];
112
- const valid = await validateApiKey(apiKey);
113
-
114
- if (valid) return { success: true, authType: 'custom', username: 'api-user' };
115
- return { success: false, error: 'Invalid API key' };
124
+ if (apiKey && await validateApiKey(apiKey)) {
125
+ return { success: true, authType: 'custom', username: 'api-user' };
126
+ }
127
+ // Return false falls through to standard Authorization header check
128
+ return { success: false, error: 'No valid API key' };
116
129
  };
117
130
 
118
131
  const serverData: McpServerData = { ..., customAuthValidator: customValidator };
119
132
  ```
120
133
 
134
+ **Example: allow requests with upstream service headers to bypass MCP auth**
135
+
136
+ ```typescript
137
+ // Clients that pass x-service-token OR x-username+x-password are allowed in
138
+ // without an MCP Authorization token. Clients without these headers still
139
+ // need a valid Authorization header (permanentToken / basic / JWT).
140
+ const serviceHeadersValidator: CustomAuthValidator = (req) => {
141
+ const h = req.headers as Record<string, string>;
142
+ if (h['x-service-token'] || (h['x-username'] && h['x-password'])) {
143
+ return { success: true, authType: 'custom' };
144
+ }
145
+ return { success: false, error: 'No service credentials and no MCP Authorization token' };
146
+ };
147
+ ```
148
+
149
+ > **Note:** `customAuthValidator` receives a request with **normalized** (lowercased) header names.
150
+ > `authInfo` is **not** set on `req` when the validator runs — it is set by the middleware only after
151
+ > successful authentication completes.
152
+
121
153
  ## AD Group Checking
122
154
 
123
155
  ### Configuration
@@ -144,6 +176,47 @@ const isAdmin = await isUserInGroup('john.doe', 'Admins');
144
176
  groupChecker.clearCache(); // Clear if needed
145
177
  ```
146
178
 
179
+ ## JWT IP Restriction
180
+
181
+ When `webServer.auth.jwtToken.isCheckIP` is `true`, JWT tokens can include an `ip` field in their payload to restrict which client IPs may use the token.
182
+
183
+ ### Configuration
184
+
185
+ ```yaml
186
+ # config/default.yaml
187
+ webServer:
188
+ auth:
189
+ jwtToken:
190
+ isCheckIP: true # Enable IP checking
191
+ ```
192
+
193
+ ### Token Generation
194
+
195
+ When generating a token (via admin UI or `generateToken()`), include the `ip` field in the payload:
196
+
197
+ ```typescript
198
+ const token = generateToken('john_doe', 3600, {
199
+ service: 'my-mcp-server',
200
+ ip: '192.168.1.100, 10.0.0.0/24',
201
+ });
202
+ ```
203
+
204
+ The `ip` field is a string of IP addresses and/or CIDR masks, separated by commas, semicolons, or spaces.
205
+
206
+ In the admin UI (`/admin`), there is a dedicated "Allowed IP addresses" field for entering these values.
207
+
208
+ ### Behavior
209
+
210
+ | `isCheckIP` | `payload.ip` | Client IP | Result |
211
+ |-------------|-------------|-----------|--------|
212
+ | `false` | any | any | IP not checked |
213
+ | `true` | empty/missing | any | IP not checked (pass-through) |
214
+ | `true` | `10.0.0.0/24` | `10.0.0.5` | Allowed |
215
+ | `true` | `10.0.0.0/24` | `192.168.1.1` | Denied |
216
+ | `true` | `192.168.1.1, 10.0.0.0/8` | `10.5.5.5` | Allowed (covered by /8) |
217
+
218
+ Supported formats: IPv4, IPv6, CIDR notation (e.g., `10.0.0.0/24`, `fe80::/10`), IPv4-mapped IPv6 (`::ffff:192.168.1.1`).
219
+
147
220
  ## Client Examples
148
221
 
149
222
  ```bash
@@ -56,33 +56,46 @@ groupAccess:
56
56
 
57
57
  ## Example 1: HTTP Level Restriction
58
58
 
59
- Block unauthorized users at HTTP level (403 before MCP processing):
59
+ Block unauthorized users at HTTP level (403 before MCP processing).
60
+
61
+ > **Important:** `customAuthValidator` runs **before** standard auth and before `authInfo` is set on
62
+ > the request. It cannot read `(req as any).authInfo` — that value is populated by the middleware
63
+ > only after successful authentication. Use `httpComponents.apiRouter` to add a post-auth middleware
64
+ > if you need to check group membership after the user has been authenticated.
60
65
 
61
66
  ```typescript
62
67
  // src/start.ts
63
- import { appConfig, initMcpServer, CustomAuthValidator, initADGroupChecker } from 'fa-mcp-sdk';
68
+ import { Router } from 'express';
69
+ import { appConfig, initMcpServer, getMultiAuthError, initADGroupChecker } from 'fa-mcp-sdk';
64
70
  import { CustomAppConfig } from './_types_/custom-config.js';
65
71
 
66
72
  const config = appConfig as CustomAppConfig;
67
73
  const { isUserInGroup } = initADGroupChecker();
68
74
 
69
- const customAuthValidator: CustomAuthValidator = async (req) => {
70
- const authInfo = (req as any).authInfo;
71
- if (!authInfo?.username) return { success: false, error: 'User info unavailable' };
75
+ // Post-auth AD group check: runs after standard auth has verified the token
76
+ // and set authInfo on the request.
77
+ const groupCheckRouter = Router();
78
+ groupCheckRouter.use(async (req, res, next) => {
79
+ // Verify standard auth first (sets authInfo on req)
80
+ const authError = await getMultiAuthError(req);
81
+ if (authError) return res.status(authError.code).send(authError.message);
72
82
 
73
- if (config.groupAccess.bypassGroupCheck) {
74
- return { success: true, authType: authInfo.authType, username: authInfo.username };
75
- }
83
+ if (config.groupAccess.bypassGroupCheck) return next();
76
84
 
77
- const isInGroup = await isUserInGroup(authInfo.username, config.groupAccess.requiredGroup);
78
- if (!isInGroup) {
79
- return { success: false, error: `Forbidden: Not in group '${config.groupAccess.requiredGroup}'` };
80
- }
85
+ const authInfo = (req as any).authInfo;
86
+ const username = authInfo?.username || authInfo?.payload?.user;
87
+ if (!username) return res.status(403).send('Forbidden: User info unavailable');
81
88
 
82
- return { success: true, authType: authInfo.authType, username: authInfo.username };
83
- };
89
+ const isInGroup = await isUserInGroup(username, config.groupAccess.requiredGroup);
90
+ if (!isInGroup) return res.status(403).send(`Forbidden: Not in group '${config.groupAccess.requiredGroup}'`);
84
91
 
85
- await initMcpServer({ ..., customAuthValidator });
92
+ next();
93
+ });
94
+
95
+ await initMcpServer({
96
+ ...,
97
+ httpComponents: { apiRouter: groupCheckRouter },
98
+ });
86
99
  ```
87
100
 
88
101
  ## Example 2: All Tools Restriction
@@ -172,6 +185,12 @@ export const handleToolCall = async (params: IToolHandlerParams) => {
172
185
 
173
186
  | Level | Location | Error Type | Use Case |
174
187
  |-------|----------|------------|----------|
175
- | HTTP Server | `customAuthValidator` | HTTP 403 | Block completely |
188
+ | Pre-auth bypass | `customAuthValidator` | HTTP 401 | Allow alternative credentials (no `Authorization` header) |
189
+ | HTTP Server (post-auth) | `httpComponents.apiRouter` + `getMultiAuthError` | HTTP 403 | Block completely after identity is known |
176
190
  | All Tools | `toolHandler` (global) | MCP Error | Allow HTTP, restrict tools |
177
191
  | Per Tool | `toolHandler` (per-tool) | MCP Error | Fine-grained permissions |
192
+
193
+ > `customAuthValidator` is a **pre-auth** hook — it runs before standard auth and before `authInfo`
194
+ > is available. Use it to allow alternative credentials, not to check group membership.
195
+ > For group checks that require a verified username, use `httpComponents.apiRouter` (post-auth)
196
+ > or `toolHandler` (per-call).
@@ -1,105 +1,105 @@
1
- # {{project.productName}}
2
-
3
- {{project.description}}
4
-
5
- ## Install & Run
6
-
7
- ### Quick Start
8
- ```bash
9
- # Install
10
- npm install
11
-
12
- # Configure (copy config/local.yaml from config/_local.yaml)
13
- # Add database credentials
14
-
15
- # Build
16
- npm run build
17
-
18
- # Run (STDIO mode for Claude Desktop)
19
- npm start
20
- ```
21
-
22
- ### Test Run
23
- ```bash
24
- # Unit tests
25
- npm test
26
-
27
- # MCP protocol tests
28
- npm run test:mcp # STDIO mode
29
- npm run test:mcp-http # HTTP mode
30
- npm run test:mcp-simple # Simple test
31
- ```
32
-
33
- ### Dual Transport System
34
-
35
- **STDIO Mode** (default for Claude Desktop):
36
- - Direct stdin/stdout communication
37
- - Optimal for Claude Desktop integration
38
- - No network ports required
39
-
40
- **HTTP Mode** (web integration):
41
- - HTTP server with Server-Sent Events (SSE)
42
- - Home page with server status at `http://localhost:{{port}}/`
43
- - Health check endpoint at `/health`
44
- - Direct JSON-RPC 2.0 endpoint at `/mcp`
45
-
46
-
47
- ## Features
48
-
49
-
50
-
51
- ## MCP Tools
52
-
53
-
54
-
55
- ## MCP Prompts
56
-
57
- ### `agent_brief`
58
- Brief description of agent capabilities for agent selection.
59
-
60
- ### `agent_prompt`
61
- Complete prompt with instructions.
62
-
63
- ## MCP Resources
64
-
65
- ### `staff://agent/brief`
66
- Same as `agent_brief` prompt. **MIME:** text/plain
67
-
68
- ### `staff://agent/prompt`
69
- Same as `agent_prompt` prompt. **MIME:** text/plain
70
-
71
-
72
- ## 2. Configuration
73
-
74
- **Option A: Configuration File**
75
-
76
- **Option B: Environment Variables**
77
-
78
-
79
- ## Claude Desktop Setup
80
-
81
- Add to `claude_desktop_config.json`:
82
-
83
- ```json
84
- {
85
- "mcpServers": {
86
- "{{project.name}}": {
87
- "command": "node",
88
- "args": [
89
- "<path-to-project>/mcp-staff-db/dist/src/index.js"
90
- ],
91
- "env": {
92
- }
93
- }
94
- }
95
- }
96
- ```
97
-
98
- ## HTTP Mode Endpoints
99
-
100
- - **/** - Home page
101
- - **/health** - Health check
102
- - **/sse** - Server-Sent Events
103
- - **/mcp** - JSON-RPC 2.0
104
-
105
- ## Security
1
+ # {{project.productName}}
2
+
3
+ {{project.description}}
4
+
5
+ ## Install & Run
6
+
7
+ ### Quick Start
8
+ ```bash
9
+ # Install
10
+ npm install
11
+
12
+ # Configure (copy config/local.yaml from config/_local.yaml)
13
+ # Add database credentials
14
+
15
+ # Build
16
+ npm run build
17
+
18
+ # Run (STDIO mode for Claude Desktop)
19
+ npm start
20
+ ```
21
+
22
+ ### Test Run
23
+ ```bash
24
+ # Unit tests
25
+ npm test
26
+
27
+ # MCP protocol tests
28
+ npm run test:mcp # STDIO mode
29
+ npm run test:mcp-http # HTTP mode
30
+ npm run test:mcp-simple # Simple test
31
+ ```
32
+
33
+ ### Dual Transport System
34
+
35
+ **STDIO Mode** (default for Claude Desktop):
36
+ - Direct stdin/stdout communication
37
+ - Optimal for Claude Desktop integration
38
+ - No network ports required
39
+
40
+ **HTTP Mode** (web integration):
41
+ - HTTP server with Server-Sent Events (SSE)
42
+ - Home page with server status at `http://localhost:{{port}}/`
43
+ - Health check endpoint at `/health`
44
+ - Direct JSON-RPC 2.0 endpoint at `/mcp`
45
+
46
+
47
+ ## Features
48
+
49
+
50
+
51
+ ## MCP Tools
52
+
53
+
54
+
55
+ ## MCP Prompts
56
+
57
+ ### `agent_brief`
58
+ Brief description of agent capabilities for agent selection.
59
+
60
+ ### `agent_prompt`
61
+ Complete prompt with instructions.
62
+
63
+ ## MCP Resources
64
+
65
+ ### `staff://agent/brief`
66
+ Same as `agent_brief` prompt. **MIME:** text/plain
67
+
68
+ ### `staff://agent/prompt`
69
+ Same as `agent_prompt` prompt. **MIME:** text/plain
70
+
71
+
72
+ ## 2. Configuration
73
+
74
+ **Option A: Configuration File**
75
+
76
+ **Option B: Environment Variables**
77
+
78
+
79
+ ## Claude Desktop Setup
80
+
81
+ Add to `claude_desktop_config.json`:
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "{{project.name}}": {
87
+ "command": "node",
88
+ "args": [
89
+ "<path-to-project>/mcp-staff-db/dist/src/index.js"
90
+ ],
91
+ "env": {
92
+ }
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ ## HTTP Mode Endpoints
99
+
100
+ - **/** - Home page
101
+ - **/health** - Health check
102
+ - **/sse** - Server-Sent Events
103
+ - **/mcp** - JSON-RPC 2.0
104
+
105
+ ## Security
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "project.name",
3
3
  "productName": "{{project.productName}}",
4
- "version": "0.0.3",
4
+ "version": "0.1.0",
5
5
  "description": "{{project.description}}",
6
6
  "type": "module",
7
7
  "main": "dist/src/start.js",
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "^1.26.0",
52
52
  "dotenv": "^17.2.4",
53
- "fa-mcp-sdk": "^0.3.16"
53
+ "fa-mcp-sdk": "^0.3.18"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/express": "^5.0.6",
@@ -18,7 +18,7 @@ Authorization: Bearer <appConfig.accessPoints.currencyService.token>
18
18
  Example:
19
19
 
20
20
  ```http request
21
- GET http://smart-trade-ml.com:5002/currency-service/?rate=THBRUB
21
+ GET http://smart-trade-ml.com:5001/currency-service/?rate=THBRUB
22
22
  Authorization: Bearer <appConfig.accessPoints.currencyService.token>
23
23
  ```
24
24
 
@@ -66,6 +66,7 @@ webServer:
66
66
  jwtToken:
67
67
  encryptKey: 'dbbe87db-90d0-4732-aae3-4089763ec392'
68
68
  checkMCPName: true
69
+ isCheckIP: false
69
70
  permanentServerTokens: ['psToken1']
70
71
 
71
72
  adminAuth:
@@ -0,0 +1,15 @@
1
+ # Цель
2
+
3
+
4
+ # Дополнительные сведения
5
+ Смотри документацию в D:\DEV\FA\_pub\fa-mcp-sdk\cli-template\FA-MCP-SDK-DOC
6
+ Конфигурация - D:\DEV\FA\_pub\fa-mcp-sdk\config\default.yaml
7
+ D:\DEV\FA\_pub\fa-mcp-sdk\src\core\_types_\config.ts
8
+
9
+ Код дергай отсюда
10
+ D:\DEV\FA\_pub\fa-mcp-sdk\src\core\consul
11
+ D:\DEV\FA\_pub\fa-mcp-sdk\src\core\bootstrap\init-config.ts
12
+ D:\DEV\FA\_pub\fa-mcp-sdk\src\core\bootstrap\startup-info.ts
13
+ ЗАпуск - D:\DEV\FA\_pub\fa-mcp-sdk\src\core\init-mcp-server.ts
14
+
15
+ # Задача
@@ -1,9 +1,9 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration
3
- default="false"
4
- name="TEST HTTP"
5
- type="NodeJSConfigurationType"
6
- path-to-js-file="tests/mcp/test-http.js" working-dir="$PROJECT_DIR$/">
7
- <method v="2" />
8
- </configuration>
9
- </component>
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration
3
+ default="false"
4
+ name="TEST HTTP"
5
+ type="NodeJSConfigurationType"
6
+ path-to-js-file="tests/mcp/test-http.js" working-dir="$PROJECT_DIR$/">
7
+ <method v="2" />
8
+ </configuration>
9
+ </component>
@@ -1,5 +1,5 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration default="false" name="TEST SSE" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-sse.js" working-dir="$PROJECT_DIR$/">
3
- <method v="2" />
4
- </configuration>
5
- </component>
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="false" name="TEST SSE" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-sse.js" working-dir="$PROJECT_DIR$/">
3
+ <method v="2" />
4
+ </configuration>
5
+ </component>
@@ -1,5 +1,5 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration default="false" name="TEST STDIO" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-stdio.js" working-dir="$PROJECT_DIR$">
3
- <method v="2" />
4
- </configuration>
5
- </component>
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="false" name="TEST STDIO" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-stdio.js" working-dir="$PROJECT_DIR$">
3
+ <method v="2" />
4
+ </configuration>
5
+ </component>
@@ -1,14 +1,14 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration default="false" name="generate-token" type="js.build_tools.npm" nameIsGenerated="true">
3
- <package-json value="$PROJECT_DIR$/package.json" />
4
- <command value="run" />
5
- <scripts>
6
- <script value="generate-token" />
7
- </scripts>
8
- <node-interpreter value="project" />
9
- <envs>
10
- <env name="DEBUG" value="ntlm:auth-flow,ntlm:ldap-proxy,ntlm:ldap-proxy-id" />
11
- </envs>
12
- <method v="2" />
13
- </configuration>
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="false" name="generate-token" type="js.build_tools.npm" nameIsGenerated="true">
3
+ <package-json value="$PROJECT_DIR$/package.json" />
4
+ <command value="run" />
5
+ <scripts>
6
+ <script value="generate-token" />
7
+ </scripts>
8
+ <node-interpreter value="project" />
9
+ <envs>
10
+ <env name="DEBUG" value="ntlm:auth-flow,ntlm:ldap-proxy,ntlm:ldap-proxy-id" />
11
+ </envs>
12
+ <method v="2" />
13
+ </configuration>
14
14
  </component>
@@ -1,12 +1,12 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration default="false" name="lint-fix-build" type="js.build_tools.npm" nameIsGenerated="true">
3
- <package-json value="$PROJECT_DIR$/package.json" />
4
- <command value="run" />
5
- <scripts>
6
- <script value="lint-fix-build" />
7
- </scripts>
8
- <node-interpreter value="project" />
9
- <envs />
10
- <method v="2" />
11
- </configuration>
12
- </component>
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="false" name="lint-fix-build" type="js.build_tools.npm" nameIsGenerated="true">
3
+ <package-json value="$PROJECT_DIR$/package.json" />
4
+ <command value="run" />
5
+ <scripts>
6
+ <script value="lint-fix-build" />
7
+ </scripts>
8
+ <node-interpreter value="project" />
9
+ <envs />
10
+ <method v="2" />
11
+ </configuration>
12
+ </component>
@@ -1,11 +1,11 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration
3
- default="false"
4
- name="remove-nul.js"
5
- type="NodeJSConfigurationType"
6
- nameIsGenerated="true"
7
- path-to-js-file="scripts/remove-nul.js"
8
- working-dir="$PROJECT_DIR$">
9
- <method v="2"/>
10
- </configuration>
11
- </component>
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration
3
+ default="false"
4
+ name="remove-nul.js"
5
+ type="NodeJSConfigurationType"
6
+ nameIsGenerated="true"
7
+ path-to-js-file="scripts/remove-nul.js"
8
+ working-dir="$PROJECT_DIR$">
9
+ <method v="2"/>
10
+ </configuration>
11
+ </component>
@@ -44,6 +44,7 @@ webServer:
44
44
  jwtToken:
45
45
  encryptKey: WS_TOKEN_ENCRYPT_KEY
46
46
  checkMCPName: WS_CHECK_MC_NAME
47
+ isCheckIP: WS_JWT_CHECK_IP
47
48
  basic:
48
49
  username: WS_AUTH_BASIC_USERNAME
49
50
  password: WS_AUTH_BASIC_PASSWORD
@@ -176,6 +176,9 @@ webServer:
176
176
  encryptKey: '***'
177
177
  # If webServer.auth.enabled and the parameter true, the service name and the service specified in the token will be checked
178
178
  checkMCPName: true
179
+ # If true and JWT token contains non-empty 'ip' field,
180
+ # the client IP will be checked against the allowed list in the token
181
+ isCheckIP: false
179
182
 
180
183
  # ========================================================================
181
184
  # Basic Authentication - Base64 encoded username:password
@@ -1,4 +1,4 @@
1
- ---
2
-
3
-
4
-
1
+ ---
2
+
3
+
4
+
@@ -1,4 +1,4 @@
1
- ---
2
-
3
-
4
-
1
+ ---
2
+
3
+
4
+
@@ -16,6 +16,7 @@ interface IWebServerConfig {
16
16
  jwtToken: {
17
17
  encryptKey: string;
18
18
  checkMCPName: boolean;
19
+ isCheckIP: boolean;
19
20
  };
20
21
  permanentServerTokens: string[];
21
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/core/_types_/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD,UAAU,gBAAgB;IACxB,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,IAAI,EAAE;YACJ,OAAO,EAAE,OAAO,CAAC;YACjB,KAAK,CAAC,EAAE;gBACN,QAAQ,EAAE,MAAM,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAC;aAClB,CAAC;YACF,QAAQ,EAAE;gBACR,UAAU,EAAE,MAAM,CAAC;gBACnB,YAAY,EAAE,OAAO,CAAC;aACvB,CAAA;YACD,qBAAqB,EAAE,MAAM,EAAE,CAAC;SACjC,CAAC;QACF,SAAS,EAAE;YACT,OAAO,EAAE,OAAO,CAAC;YACjB,IAAI,EAAE,uBAAuB,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;SAC/D,CAAC;KACH,CAAA;CACF;AAGD,UAAU,aAAa;IACrB,MAAM,EAAE;QACN,KAAK,EAAE,aAAa,CAAC;QACrB,aAAa,EAAE,OAAO,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAA;CACF;AAED,UAAU,UAAU;IAClB,GAAG,EAAE;QACH,SAAS,EAAE;YACT,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,YAAY,EAAE,MAAM,GAAG,mBAAmB,CAAA;QAC1C,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC;KACjC,CAAA;CACF;AAED,UAAU,cAAc;IACtB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE;YACR,GAAG,EAAE,MAAM,CAAC;YACZ,WAAW,EAAE,MAAM,CAAC;SACrB,EAAE,CAAC;KACL,CAAA;CACF;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAA;CACF;AAED,UAAU,YAAY;IACpB,KAAK,EAAE;QACL,UAAU,EAAE,GAAG,CAAC;QAChB,QAAQ,EAAE,IAAI,CAAC;KAChB,CAAA;CACF;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS,EAC1C,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,kBAAkB;IAElB,YAAY,EAAE,OAAO,CAAC;IAEtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,eAAe,GAAG;QACxB,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;KACH,CAAC;IACF,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;KACjB,CAAA;CACF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/core/_types_/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD,UAAU,gBAAgB;IACxB,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,IAAI,EAAE;YACJ,OAAO,EAAE,OAAO,CAAC;YACjB,KAAK,CAAC,EAAE;gBACN,QAAQ,EAAE,MAAM,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAC;aAClB,CAAC;YACF,QAAQ,EAAE;gBACR,UAAU,EAAE,MAAM,CAAC;gBACnB,YAAY,EAAE,OAAO,CAAC;gBACtB,SAAS,EAAE,OAAO,CAAC;aACpB,CAAA;YACD,qBAAqB,EAAE,MAAM,EAAE,CAAC;SACjC,CAAC;QACF,SAAS,EAAE;YACT,OAAO,EAAE,OAAO,CAAC;YACjB,IAAI,EAAE,uBAAuB,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;SAC/D,CAAC;KACH,CAAA;CACF;AAGD,UAAU,aAAa;IACrB,MAAM,EAAE;QACN,KAAK,EAAE,aAAa,CAAC;QACrB,aAAa,EAAE,OAAO,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAA;CACF;AAED,UAAU,UAAU;IAClB,GAAG,EAAE;QACH,SAAS,EAAE;YACT,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,YAAY,EAAE,MAAM,GAAG,mBAAmB,CAAA;QAC1C,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC;KACjC,CAAA;CACF;AAED,UAAU,cAAc;IACtB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE;YACR,GAAG,EAAE,MAAM,CAAC;YACZ,WAAW,EAAE,MAAM,CAAC;SACrB,EAAE,CAAC;KACL,CAAA;CACF;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAA;CACF;AAED,UAAU,YAAY;IACpB,KAAK,EAAE;QACL,UAAU,EAAE,GAAG,CAAC;QAChB,QAAQ,EAAE,IAAI,CAAC;KAChB,CAAA;CACF;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS,EAC1C,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,kBAAkB;IAElB,YAAY,EAAE,OAAO,CAAC;IAEtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,eAAe,GAAG;QACxB,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;KACH,CAAC;IACF,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;KACjB,CAAA;CACF"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * IP address parsing and CIDR matching utilities for JWT IP checking.
3
+ * Pure TypeScript implementation — no external dependencies.
4
+ */
5
+ /**
6
+ * Parses IP string (comma/semicolon/space-separated) into array of trimmed non-empty entries.
7
+ * Each entry is either a plain IP or a CIDR notation (e.g., "10.0.0.0/24").
8
+ */
9
+ export declare function parseIpList(ipStr: string): string[];
10
+ /**
11
+ * Checks if clientIp matches any entry in allowedIps.
12
+ * Supports:
13
+ * - Exact match (IPv4 and IPv6)
14
+ * - CIDR subnet match (e.g., 10.0.0.0/24)
15
+ * - IPv4-mapped IPv6 normalization (::ffff:x.x.x.x → x.x.x.x)
16
+ */
17
+ export declare function isIpAllowed(clientIp: string, allowedIps: string[]): boolean;
18
+ //# sourceMappingURL=ip-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-check.d.ts","sourceRoot":"","sources":["../../../src/core/auth/ip-check.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAQpD;AAmID;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAK5E"}