@frontmcp/skills 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +135 -0
- package/catalog/TEMPLATE.md +49 -0
- package/catalog/adapters/create-adapter/SKILL.md +127 -0
- package/catalog/adapters/official-adapters/SKILL.md +136 -0
- package/catalog/auth/configure-auth/SKILL.md +250 -0
- package/catalog/auth/configure-auth/references/auth-modes.md +77 -0
- package/catalog/auth/configure-session/SKILL.md +201 -0
- package/catalog/config/configure-elicitation/SKILL.md +136 -0
- package/catalog/config/configure-http/SKILL.md +167 -0
- package/catalog/config/configure-throttle/SKILL.md +189 -0
- package/catalog/config/configure-throttle/references/guard-config.md +68 -0
- package/catalog/config/configure-transport/SKILL.md +151 -0
- package/catalog/config/configure-transport/references/protocol-presets.md +57 -0
- package/catalog/deployment/build-for-browser/SKILL.md +95 -0
- package/catalog/deployment/build-for-cli/SKILL.md +100 -0
- package/catalog/deployment/build-for-sdk/SKILL.md +218 -0
- package/catalog/deployment/deploy-to-cloudflare/SKILL.md +192 -0
- package/catalog/deployment/deploy-to-lambda/SKILL.md +304 -0
- package/catalog/deployment/deploy-to-node/SKILL.md +229 -0
- package/catalog/deployment/deploy-to-node/references/Dockerfile.example +45 -0
- package/catalog/deployment/deploy-to-vercel/SKILL.md +196 -0
- package/catalog/deployment/deploy-to-vercel/references/vercel.json.example +60 -0
- package/catalog/development/create-agent/SKILL.md +563 -0
- package/catalog/development/create-agent/references/llm-config.md +46 -0
- package/catalog/development/create-job/SKILL.md +566 -0
- package/catalog/development/create-prompt/SKILL.md +400 -0
- package/catalog/development/create-provider/SKILL.md +233 -0
- package/catalog/development/create-resource/SKILL.md +437 -0
- package/catalog/development/create-skill/SKILL.md +526 -0
- package/catalog/development/create-skill-with-tools/SKILL.md +579 -0
- package/catalog/development/create-tool/SKILL.md +418 -0
- package/catalog/development/create-tool/references/output-schema-types.md +56 -0
- package/catalog/development/create-tool/references/tool-annotations.md +34 -0
- package/catalog/development/create-workflow/SKILL.md +709 -0
- package/catalog/development/decorators-guide/SKILL.md +598 -0
- package/catalog/plugins/create-plugin/SKILL.md +336 -0
- package/catalog/plugins/create-plugin-hooks/SKILL.md +282 -0
- package/catalog/plugins/official-plugins/SKILL.md +667 -0
- package/catalog/setup/frontmcp-skills-usage/SKILL.md +200 -0
- package/catalog/setup/multi-app-composition/SKILL.md +358 -0
- package/catalog/setup/nx-workflow/SKILL.md +357 -0
- package/catalog/setup/project-structure-nx/SKILL.md +186 -0
- package/catalog/setup/project-structure-standalone/SKILL.md +153 -0
- package/catalog/setup/setup-project/SKILL.md +493 -0
- package/catalog/setup/setup-redis/SKILL.md +385 -0
- package/catalog/setup/setup-sqlite/SKILL.md +359 -0
- package/catalog/skills-manifest.json +414 -0
- package/catalog/testing/setup-testing/SKILL.md +539 -0
- package/catalog/testing/setup-testing/references/test-auth.md +88 -0
- package/catalog/testing/setup-testing/references/test-browser-build.md +57 -0
- package/catalog/testing/setup-testing/references/test-cli-binary.md +48 -0
- package/catalog/testing/setup-testing/references/test-direct-client.md +62 -0
- package/catalog/testing/setup-testing/references/test-e2e-handler.md +51 -0
- package/catalog/testing/setup-testing/references/test-tool-unit.md +41 -0
- package/package.json +34 -0
- package/src/index.d.ts +3 -0
- package/src/index.js +16 -0
- package/src/index.js.map +1 -0
- package/src/loader.d.ts +46 -0
- package/src/loader.js +75 -0
- package/src/loader.js.map +1 -0
- package/src/manifest.d.ts +81 -0
- package/src/manifest.js +26 -0
- package/src/manifest.js.map +1 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configure-http
|
|
3
|
+
description: Configure HTTP server options including port, CORS, unix sockets, and entry path. Use when customizing the HTTP listener, enabling CORS, or binding to a unix socket.
|
|
4
|
+
tags: [http, cors, port, socket, server, configuration]
|
|
5
|
+
parameters:
|
|
6
|
+
- name: port
|
|
7
|
+
description: HTTP server port
|
|
8
|
+
type: number
|
|
9
|
+
default: 3001
|
|
10
|
+
examples:
|
|
11
|
+
- scenario: Configure CORS for a specific frontend origin
|
|
12
|
+
expected-outcome: Server accepts requests only from the allowed origin
|
|
13
|
+
- scenario: Bind to a unix socket for local-only access
|
|
14
|
+
expected-outcome: Server listens on unix socket instead of TCP port
|
|
15
|
+
priority: 7
|
|
16
|
+
visibility: both
|
|
17
|
+
license: Apache-2.0
|
|
18
|
+
metadata:
|
|
19
|
+
docs: https://docs.agentfront.dev/frontmcp/deployment/local-dev-server
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Configuring HTTP Options
|
|
23
|
+
|
|
24
|
+
Configure the HTTP server — port, CORS policy, unix sockets, and entry path prefix.
|
|
25
|
+
|
|
26
|
+
## When to Use
|
|
27
|
+
|
|
28
|
+
Configure HTTP options when:
|
|
29
|
+
|
|
30
|
+
- Changing the default port (3001)
|
|
31
|
+
- Enabling CORS for a frontend application
|
|
32
|
+
- Mounting the MCP server under a URL prefix
|
|
33
|
+
- Binding to a unix socket for local daemon mode
|
|
34
|
+
|
|
35
|
+
## HttpOptionsInput
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
@FrontMcp({
|
|
39
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
40
|
+
apps: [MyApp],
|
|
41
|
+
http: {
|
|
42
|
+
port: 3001, // default: 3001
|
|
43
|
+
entryPath: '', // default: '' (root)
|
|
44
|
+
socketPath: undefined, // unix socket path (overrides port)
|
|
45
|
+
cors: {
|
|
46
|
+
// default: permissive (all origins)
|
|
47
|
+
origin: ['https://myapp.com'],
|
|
48
|
+
credentials: true,
|
|
49
|
+
maxAge: 86400,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
class Server {}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Port Configuration
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// Default: port 3001
|
|
60
|
+
http: {
|
|
61
|
+
port: 3001;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Use environment variable
|
|
65
|
+
http: {
|
|
66
|
+
port: Number(process.env.PORT) || 3001;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Random port (useful for testing)
|
|
70
|
+
http: {
|
|
71
|
+
port: 0;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## CORS Configuration
|
|
76
|
+
|
|
77
|
+
### Permissive (Default)
|
|
78
|
+
|
|
79
|
+
When `cors` is not specified, the server allows all origins without credentials:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// All origins allowed (default behavior)
|
|
83
|
+
http: {
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Restrict to Specific Origins
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
http: {
|
|
91
|
+
cors: {
|
|
92
|
+
origin: ['https://myapp.com', 'https://staging.myapp.com'],
|
|
93
|
+
credentials: true,
|
|
94
|
+
maxAge: 86400, // Cache preflight for 24 hours
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Disable CORS Entirely
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
http: {
|
|
103
|
+
cors: false, // No CORS headers at all
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Dynamic Origin
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
http: {
|
|
111
|
+
cors: {
|
|
112
|
+
origin: (origin: string) => {
|
|
113
|
+
// Allow any *.myapp.com subdomain
|
|
114
|
+
return origin.endsWith('.myapp.com');
|
|
115
|
+
},
|
|
116
|
+
credentials: true,
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### CORS Fields
|
|
122
|
+
|
|
123
|
+
| Field | Type | Default | Description |
|
|
124
|
+
| ------------- | ------------------------------------------- | ------------ | ---------------------------------- |
|
|
125
|
+
| `origin` | `boolean \| string \| string[] \| function` | `true` (all) | Allowed origins |
|
|
126
|
+
| `credentials` | `boolean` | `false` | Allow cookies/auth headers |
|
|
127
|
+
| `maxAge` | `number` | — | Preflight cache duration (seconds) |
|
|
128
|
+
|
|
129
|
+
## Entry Path Prefix
|
|
130
|
+
|
|
131
|
+
Mount the MCP server under a URL prefix:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
http: {
|
|
135
|
+
entryPath: '/api/mcp',
|
|
136
|
+
}
|
|
137
|
+
// Server endpoints become: /api/mcp/sse, /api/mcp/, etc.
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Useful when running behind a reverse proxy or alongside other services.
|
|
141
|
+
|
|
142
|
+
## Unix Socket Mode
|
|
143
|
+
|
|
144
|
+
Bind to a unix socket instead of a TCP port for local-only access:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
http: {
|
|
148
|
+
socketPath: '/tmp/my-mcp-server.sock',
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- Mutually exclusive with `port` — if `socketPath` is set, `port` is ignored
|
|
153
|
+
- Use for local daemons, CLI tools, and process manager integrations
|
|
154
|
+
- Combine with `sqlite` for fully local deployments
|
|
155
|
+
|
|
156
|
+
## Verification
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Start with custom port
|
|
160
|
+
PORT=8080 frontmcp dev
|
|
161
|
+
|
|
162
|
+
# Test CORS
|
|
163
|
+
curl -v -H "Origin: https://myapp.com" http://localhost:8080/
|
|
164
|
+
|
|
165
|
+
# Test unix socket
|
|
166
|
+
curl --unix-socket /tmp/my-mcp-server.sock http://localhost/
|
|
167
|
+
```
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configure-throttle
|
|
3
|
+
description: Set up rate limiting, concurrency control, timeouts, and IP filtering at server and per-tool level. Use when protecting against abuse, limiting request rates, or configuring IP allow/deny lists.
|
|
4
|
+
tags: [throttle, rate-limit, concurrency, timeout, security, guard, ip-filter]
|
|
5
|
+
parameters:
|
|
6
|
+
- name: maxRequests
|
|
7
|
+
description: Maximum requests per window
|
|
8
|
+
type: number
|
|
9
|
+
default: 100
|
|
10
|
+
examples:
|
|
11
|
+
- scenario: Rate limit all tools to 100 requests per minute
|
|
12
|
+
expected-outcome: Requests beyond limit receive 429 response
|
|
13
|
+
- scenario: Limit concurrent executions of expensive tool to 5
|
|
14
|
+
expected-outcome: 6th concurrent call queues or fails
|
|
15
|
+
- scenario: Block requests from specific IP ranges
|
|
16
|
+
expected-outcome: Blocked IPs receive 403 response
|
|
17
|
+
priority: 7
|
|
18
|
+
visibility: both
|
|
19
|
+
license: Apache-2.0
|
|
20
|
+
metadata:
|
|
21
|
+
docs: https://docs.agentfront.dev/frontmcp/servers/guard
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Configuring Throttle, Rate Limits, and IP Filtering
|
|
25
|
+
|
|
26
|
+
Protect your FrontMCP server with rate limiting, concurrency control, execution timeouts, and IP filtering — at both server and per-tool levels.
|
|
27
|
+
|
|
28
|
+
## When to Use
|
|
29
|
+
|
|
30
|
+
Configure throttle when:
|
|
31
|
+
|
|
32
|
+
- Protecting against abuse or DDoS
|
|
33
|
+
- Limiting expensive tool executions
|
|
34
|
+
- Enforcing per-session or per-IP request quotas
|
|
35
|
+
- Blocking or allowing specific IP ranges
|
|
36
|
+
- Setting execution timeouts for long-running tools
|
|
37
|
+
|
|
38
|
+
## Server-Level Throttle (GuardConfig)
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
@FrontMcp({
|
|
42
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
43
|
+
apps: [MyApp],
|
|
44
|
+
throttle: {
|
|
45
|
+
enabled: true,
|
|
46
|
+
|
|
47
|
+
// Global rate limit (all requests combined)
|
|
48
|
+
global: {
|
|
49
|
+
maxRequests: 1000,
|
|
50
|
+
windowMs: 60000, // 1 minute window
|
|
51
|
+
partitionBy: 'global', // shared across all clients
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
// Global concurrency limit
|
|
55
|
+
globalConcurrency: {
|
|
56
|
+
maxConcurrent: 50,
|
|
57
|
+
partitionBy: 'global',
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// Default limits for individual tools (applied unless tool overrides)
|
|
61
|
+
defaultRateLimit: {
|
|
62
|
+
maxRequests: 100,
|
|
63
|
+
windowMs: 60000,
|
|
64
|
+
},
|
|
65
|
+
defaultConcurrency: {
|
|
66
|
+
maxConcurrent: 10,
|
|
67
|
+
},
|
|
68
|
+
defaultTimeout: {
|
|
69
|
+
executeMs: 30000, // 30 second timeout
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
// IP filtering
|
|
73
|
+
ipFilter: {
|
|
74
|
+
allowList: ['10.0.0.0/8', '172.16.0.0/12'], // CIDR ranges
|
|
75
|
+
denyList: ['192.168.1.100'],
|
|
76
|
+
defaultAction: 'allow', // 'allow' | 'deny'
|
|
77
|
+
trustProxy: true, // trust X-Forwarded-For
|
|
78
|
+
trustedProxyDepth: 1, // proxy depth to trust
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
})
|
|
82
|
+
class Server {}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Per-Tool Rate Limiting
|
|
86
|
+
|
|
87
|
+
Override server defaults on individual tools:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
@Tool({
|
|
91
|
+
name: 'expensive_query',
|
|
92
|
+
description: 'Run an expensive database query',
|
|
93
|
+
inputSchema: {
|
|
94
|
+
query: z.string(),
|
|
95
|
+
},
|
|
96
|
+
outputSchema: { rows: z.array(z.record(z.unknown())) },
|
|
97
|
+
|
|
98
|
+
// Per-tool limits
|
|
99
|
+
rateLimit: {
|
|
100
|
+
maxRequests: 10,
|
|
101
|
+
windowMs: 60000,
|
|
102
|
+
partitionBy: 'session', // per-session rate limit
|
|
103
|
+
},
|
|
104
|
+
concurrency: {
|
|
105
|
+
maxConcurrent: 3,
|
|
106
|
+
queueTimeoutMs: 5000, // wait up to 5s for a slot
|
|
107
|
+
partitionBy: 'session',
|
|
108
|
+
},
|
|
109
|
+
timeout: {
|
|
110
|
+
executeMs: 60000, // 60 second timeout for this tool
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
class ExpensiveQueryTool extends ToolContext {
|
|
114
|
+
async execute(input: { query: string }) {
|
|
115
|
+
const db = this.get(DB_TOKEN);
|
|
116
|
+
return { rows: await db.query(input.query) };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Configuration Types
|
|
122
|
+
|
|
123
|
+
### RateLimitConfig
|
|
124
|
+
|
|
125
|
+
| Field | Type | Default | Description |
|
|
126
|
+
| ------------- | ------------------------------- | ---------- | ------------------------- |
|
|
127
|
+
| `maxRequests` | `number` | — | Max requests per window |
|
|
128
|
+
| `windowMs` | `number` | `60000` | Window duration in ms |
|
|
129
|
+
| `partitionBy` | `'global' \| 'ip' \| 'session'` | `'global'` | How to partition counters |
|
|
130
|
+
|
|
131
|
+
### ConcurrencyConfig
|
|
132
|
+
|
|
133
|
+
| Field | Type | Default | Description |
|
|
134
|
+
| ---------------- | ------------------------------- | ---------- | -------------------------------------------------- |
|
|
135
|
+
| `maxConcurrent` | `number` | — | Max simultaneous executions |
|
|
136
|
+
| `queueTimeoutMs` | `number` | `0` | How long to wait for a slot (0 = fail immediately) |
|
|
137
|
+
| `partitionBy` | `'global' \| 'ip' \| 'session'` | `'global'` | How to partition counters |
|
|
138
|
+
|
|
139
|
+
### TimeoutConfig
|
|
140
|
+
|
|
141
|
+
| Field | Type | Default | Description |
|
|
142
|
+
| ----------- | -------- | ------- | ------------------------ |
|
|
143
|
+
| `executeMs` | `number` | — | Max execution time in ms |
|
|
144
|
+
|
|
145
|
+
### IpFilterConfig
|
|
146
|
+
|
|
147
|
+
| Field | Type | Default | Description |
|
|
148
|
+
| ------------------- | ------------------- | --------- | ----------------------------------- |
|
|
149
|
+
| `allowList` | `string[]` | — | Allowed IPs or CIDR ranges |
|
|
150
|
+
| `denyList` | `string[]` | — | Blocked IPs or CIDR ranges |
|
|
151
|
+
| `defaultAction` | `'allow' \| 'deny'` | `'allow'` | Action when IP matches neither list |
|
|
152
|
+
| `trustProxy` | `boolean` | `false` | Trust X-Forwarded-For header |
|
|
153
|
+
| `trustedProxyDepth` | `number` | `1` | How many proxy hops to trust |
|
|
154
|
+
|
|
155
|
+
## Partition Strategies
|
|
156
|
+
|
|
157
|
+
- **`'global'`** — Single shared counter for all clients. Use for global capacity limits.
|
|
158
|
+
- **`'ip'`** — Separate counter per client IP. Use for per-client rate limiting.
|
|
159
|
+
- **`'session'`** — Separate counter per MCP session. Use for per-session fairness.
|
|
160
|
+
|
|
161
|
+
## Distributed Rate Limiting
|
|
162
|
+
|
|
163
|
+
For multi-instance deployments, configure Redis storage in the guard:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
throttle: {
|
|
167
|
+
enabled: true,
|
|
168
|
+
storage: {
|
|
169
|
+
type: 'redis',
|
|
170
|
+
redis: { provider: 'redis', host: 'redis.internal' },
|
|
171
|
+
},
|
|
172
|
+
global: { maxRequests: 1000, windowMs: 60000 },
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Verification
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Start server
|
|
180
|
+
frontmcp dev
|
|
181
|
+
|
|
182
|
+
# Test rate limiting (send 101 requests rapidly)
|
|
183
|
+
for i in $(seq 1 101); do
|
|
184
|
+
curl -s -o /dev/null -w "%{http_code}\n" -X POST http://localhost:3001/ \
|
|
185
|
+
-H 'Content-Type: application/json' \
|
|
186
|
+
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
|
|
187
|
+
done
|
|
188
|
+
# Should see 429 responses after limit is exceeded
|
|
189
|
+
```
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# GuardConfig Full Reference
|
|
2
|
+
|
|
3
|
+
## Complete Configuration
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
interface GuardConfig {
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
|
|
9
|
+
// Storage for distributed rate limiting
|
|
10
|
+
storage?: {
|
|
11
|
+
type: 'memory' | 'redis';
|
|
12
|
+
redis?: RedisOptionsInput;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
keyPrefix?: string; // default: 'mcp:guard:'
|
|
16
|
+
|
|
17
|
+
// Server-wide limits
|
|
18
|
+
global?: RateLimitConfig;
|
|
19
|
+
globalConcurrency?: ConcurrencyConfig;
|
|
20
|
+
|
|
21
|
+
// Default per-tool limits (overridden by tool-level config)
|
|
22
|
+
defaultRateLimit?: RateLimitConfig;
|
|
23
|
+
defaultConcurrency?: ConcurrencyConfig;
|
|
24
|
+
defaultTimeout?: TimeoutConfig;
|
|
25
|
+
|
|
26
|
+
// IP-based access control
|
|
27
|
+
ipFilter?: IpFilterConfig;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface RateLimitConfig {
|
|
31
|
+
maxRequests: number;
|
|
32
|
+
windowMs?: number; // default: 60000 (1 minute)
|
|
33
|
+
partitionBy?: 'global' | 'ip' | 'session'; // default: 'global'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface ConcurrencyConfig {
|
|
37
|
+
maxConcurrent: number;
|
|
38
|
+
queueTimeoutMs?: number; // default: 0 (fail immediately)
|
|
39
|
+
partitionBy?: 'global' | 'ip' | 'session';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface TimeoutConfig {
|
|
43
|
+
executeMs: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface IpFilterConfig {
|
|
47
|
+
allowList?: string[]; // IP addresses or CIDR ranges
|
|
48
|
+
denyList?: string[];
|
|
49
|
+
defaultAction?: 'allow' | 'deny'; // default: 'allow'
|
|
50
|
+
trustProxy?: boolean; // default: false
|
|
51
|
+
trustedProxyDepth?: number; // default: 1
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Partition Strategies
|
|
56
|
+
|
|
57
|
+
- **`'global'`**: Single counter shared by all clients. Protects total server capacity.
|
|
58
|
+
- **`'ip'`**: Separate counter per client IP. Fair per-client limiting.
|
|
59
|
+
- **`'session'`**: Separate counter per MCP session. Fair per-session limiting.
|
|
60
|
+
|
|
61
|
+
## Priority Order
|
|
62
|
+
|
|
63
|
+
1. IP filter (allow/deny) — checked first
|
|
64
|
+
2. Global rate limit — checked second
|
|
65
|
+
3. Global concurrency — checked third
|
|
66
|
+
4. Per-tool rate limit — checked per tool
|
|
67
|
+
5. Per-tool concurrency — checked per tool
|
|
68
|
+
6. Per-tool timeout — enforced during execution
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configure-transport
|
|
3
|
+
description: Choose and configure transport protocols — SSE, Streamable HTTP, stateless API, or legacy. Use when deciding between transport modes, enabling distributed sessions, or configuring event stores.
|
|
4
|
+
tags: [transport, sse, streamable-http, stateless, protocol, session]
|
|
5
|
+
parameters:
|
|
6
|
+
- name: preset
|
|
7
|
+
description: Protocol preset (legacy, modern, stateless-api, full)
|
|
8
|
+
type: string
|
|
9
|
+
default: legacy
|
|
10
|
+
examples:
|
|
11
|
+
- scenario: Use modern SSE + Streamable HTTP for production
|
|
12
|
+
expected-outcome: Server accepts both SSE and streamable HTTP connections
|
|
13
|
+
- scenario: Configure stateless API for serverless
|
|
14
|
+
expected-outcome: No session state, pure request/response
|
|
15
|
+
priority: 8
|
|
16
|
+
visibility: both
|
|
17
|
+
license: Apache-2.0
|
|
18
|
+
metadata:
|
|
19
|
+
docs: https://docs.agentfront.dev/frontmcp/deployment/runtime-modes
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Configuring Transport
|
|
23
|
+
|
|
24
|
+
Configure how clients connect to your FrontMCP server — SSE, Streamable HTTP, stateless API, or a combination.
|
|
25
|
+
|
|
26
|
+
## When to Use
|
|
27
|
+
|
|
28
|
+
Configure transport when:
|
|
29
|
+
|
|
30
|
+
- Choosing between SSE and Streamable HTTP protocols
|
|
31
|
+
- Deploying to serverless (needs stateless mode)
|
|
32
|
+
- Running multiple server instances (needs distributed sessions)
|
|
33
|
+
- Enabling SSE event resumability
|
|
34
|
+
|
|
35
|
+
## TransportOptionsInput
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
@FrontMcp({
|
|
39
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
40
|
+
apps: [MyApp],
|
|
41
|
+
transport: {
|
|
42
|
+
sessionMode: 'stateful', // 'stateful' | 'stateless'
|
|
43
|
+
protocol: 'legacy', // preset or custom ProtocolConfig
|
|
44
|
+
persistence: {
|
|
45
|
+
// false to disable
|
|
46
|
+
redis: { provider: 'redis', host: 'localhost', port: 6379 },
|
|
47
|
+
defaultTtlMs: 3600000,
|
|
48
|
+
},
|
|
49
|
+
distributedMode: 'auto', // boolean | 'auto'
|
|
50
|
+
eventStore: {
|
|
51
|
+
enabled: true,
|
|
52
|
+
provider: 'redis', // 'memory' | 'redis'
|
|
53
|
+
maxEvents: 10000,
|
|
54
|
+
ttlMs: 300000,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
class Server {}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Protocol Presets
|
|
62
|
+
|
|
63
|
+
Choose a preset that matches your deployment:
|
|
64
|
+
|
|
65
|
+
| Preset | SSE | Streamable HTTP | JSON | Stateless | Legacy SSE | Strict Session |
|
|
66
|
+
| -------------------- | --- | --------------- | ---- | --------- | ---------- | -------------- |
|
|
67
|
+
| `'legacy'` (default) | Yes | Yes | No | No | Yes | Yes |
|
|
68
|
+
| `'modern'` | Yes | Yes | No | No | No | Yes |
|
|
69
|
+
| `'stateless-api'` | No | No | No | Yes | No | No |
|
|
70
|
+
| `'full'` | Yes | Yes | Yes | Yes | Yes | No |
|
|
71
|
+
|
|
72
|
+
### When to Use Each
|
|
73
|
+
|
|
74
|
+
- **`'legacy'`** — Default. Maximum compatibility with all MCP clients (Claude Desktop, etc.). Best for Node.js deployments.
|
|
75
|
+
- **`'modern'`** — Drop legacy SSE support. Use when all clients support modern MCP protocol.
|
|
76
|
+
- **`'stateless-api'`** — No sessions, pure request/response. Use for **Vercel**, **Lambda**, and other serverless targets.
|
|
77
|
+
- **`'full'`** — All protocols enabled. Use for development or when you need every transport option.
|
|
78
|
+
|
|
79
|
+
### Custom Protocol Config
|
|
80
|
+
|
|
81
|
+
Override individual protocol flags:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
transport: {
|
|
85
|
+
protocol: {
|
|
86
|
+
sse: true, // SSE listener endpoint
|
|
87
|
+
streamable: true, // Streamable HTTP POST
|
|
88
|
+
json: false, // JSON-only responses (no streaming)
|
|
89
|
+
stateless: false, // Stateless HTTP (no sessions)
|
|
90
|
+
legacy: false, // Legacy SSE transport
|
|
91
|
+
strictSession: true, // Require session ID for streamable HTTP
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Distributed Sessions
|
|
97
|
+
|
|
98
|
+
For multi-instance deployments (load balanced), enable persistence with Redis:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
transport: {
|
|
102
|
+
distributedMode: true,
|
|
103
|
+
persistence: {
|
|
104
|
+
redis: { provider: 'redis', host: 'redis.internal', port: 6379 },
|
|
105
|
+
defaultTtlMs: 3600000, // 1 hour session TTL
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- `distributedMode: 'auto'` — auto-detect based on whether Redis is configured
|
|
111
|
+
- `distributedMode: true` — force distributed mode (requires Redis)
|
|
112
|
+
- `distributedMode: false` — single-instance mode (in-memory sessions)
|
|
113
|
+
|
|
114
|
+
## Event Store (SSE Resumability)
|
|
115
|
+
|
|
116
|
+
Enable event store so clients can resume SSE connections after disconnects:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
transport: {
|
|
120
|
+
eventStore: {
|
|
121
|
+
enabled: true,
|
|
122
|
+
provider: 'redis', // 'memory' for single instance, 'redis' for distributed
|
|
123
|
+
maxEvents: 10000, // max events to store
|
|
124
|
+
ttlMs: 300000, // 5 minute TTL
|
|
125
|
+
redis: { provider: 'redis', host: 'localhost' },
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Target-Specific Recommendations
|
|
131
|
+
|
|
132
|
+
| Target | Recommended Preset | Persistence | Event Store |
|
|
133
|
+
| ------------------------ | ------------------ | ----------- | ----------- |
|
|
134
|
+
| Node.js (single) | `'legacy'` | `false` | Memory |
|
|
135
|
+
| Node.js (multi-instance) | `'modern'` | Redis | Redis |
|
|
136
|
+
| Vercel | `'stateless-api'` | `false` | Disabled |
|
|
137
|
+
| Lambda | `'stateless-api'` | `false` | Disabled |
|
|
138
|
+
| Cloudflare | `'stateless-api'` | `false` | Disabled |
|
|
139
|
+
|
|
140
|
+
## Verification
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Start server and test SSE
|
|
144
|
+
frontmcp dev
|
|
145
|
+
|
|
146
|
+
# Test SSE endpoint
|
|
147
|
+
curl -N http://localhost:3001/sse
|
|
148
|
+
|
|
149
|
+
# Test streamable HTTP
|
|
150
|
+
curl -X POST http://localhost:3001/ -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
|
|
151
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Transport Protocol Presets Reference
|
|
2
|
+
|
|
3
|
+
## Preset Configurations
|
|
4
|
+
|
|
5
|
+
### `'legacy'` (Default)
|
|
6
|
+
|
|
7
|
+
Maximum compatibility with all MCP clients including older versions.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
{ sse: true, streamable: true, json: false, stateless: false, legacy: true, strictSession: true }
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### `'modern'`
|
|
14
|
+
|
|
15
|
+
Modern protocol only. Drops legacy SSE support.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
{ sse: true, streamable: true, json: false, stateless: false, legacy: false, strictSession: true }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### `'stateless-api'`
|
|
22
|
+
|
|
23
|
+
No sessions. Pure request/response for serverless.
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
{ sse: false, streamable: false, json: false, stateless: true, legacy: false, strictSession: false }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### `'full'`
|
|
30
|
+
|
|
31
|
+
All protocols enabled. Maximum flexibility.
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
{ sse: true, streamable: true, json: true, stateless: true, legacy: true, strictSession: false }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Protocol Fields
|
|
38
|
+
|
|
39
|
+
| Field | Description | Effect when `true` |
|
|
40
|
+
| --------------- | -------------------- | ----------------------------------------------------- |
|
|
41
|
+
| `sse` | SSE endpoint | Enables `/sse` endpoint for server-sent events |
|
|
42
|
+
| `streamable` | Streamable HTTP POST | Enables streaming responses via HTTP POST |
|
|
43
|
+
| `json` | JSON-only responses | Returns complete JSON without streaming |
|
|
44
|
+
| `stateless` | Stateless HTTP | No session management, each request standalone |
|
|
45
|
+
| `legacy` | Legacy SSE transport | Backwards-compatible SSE for older clients |
|
|
46
|
+
| `strictSession` | Require session ID | Streamable HTTP POST requires `mcp-session-id` header |
|
|
47
|
+
|
|
48
|
+
## Deployment Recommendations
|
|
49
|
+
|
|
50
|
+
| Deployment | Preset | Why |
|
|
51
|
+
| ------------------------- | ------------------------------ | ----------------------------------------- |
|
|
52
|
+
| Node.js (single instance) | `'legacy'` | Max compatibility, simple setup |
|
|
53
|
+
| Node.js (load balanced) | `'modern'` + Redis persistence | Modern protocol with distributed sessions |
|
|
54
|
+
| Vercel | `'stateless-api'` | No persistent connections allowed |
|
|
55
|
+
| AWS Lambda | `'stateless-api'` | Stateless execution model |
|
|
56
|
+
| Cloudflare Workers | `'stateless-api'` | Stateless edge runtime |
|
|
57
|
+
| Development | `'full'` | Test all protocols |
|