@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,250 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configure-auth
|
|
3
|
+
description: Set up authentication with public, transparent, local, or remote auth modes. Use when adding auth, OAuth, login, session security, or protecting tools and resources.
|
|
4
|
+
tags:
|
|
5
|
+
- auth
|
|
6
|
+
- oauth
|
|
7
|
+
- security
|
|
8
|
+
bundle:
|
|
9
|
+
- recommended
|
|
10
|
+
- full
|
|
11
|
+
visibility: both
|
|
12
|
+
priority: 10
|
|
13
|
+
parameters:
|
|
14
|
+
- name: mode
|
|
15
|
+
description: Authentication mode (public, transparent, local, remote)
|
|
16
|
+
type: string
|
|
17
|
+
required: false
|
|
18
|
+
default: public
|
|
19
|
+
- name: provider
|
|
20
|
+
description: OAuth provider URL for transparent or remote modes
|
|
21
|
+
type: string
|
|
22
|
+
required: false
|
|
23
|
+
examples:
|
|
24
|
+
- scenario: Public mode with anonymous scopes
|
|
25
|
+
parameters:
|
|
26
|
+
mode: public
|
|
27
|
+
expected-outcome: Server accepts all connections with anonymous scopes and session TTL
|
|
28
|
+
- scenario: Transparent mode validating external JWTs
|
|
29
|
+
parameters:
|
|
30
|
+
mode: transparent
|
|
31
|
+
provider: https://auth.example.com
|
|
32
|
+
expected-outcome: Server validates JWTs from the configured provider against the expected audience
|
|
33
|
+
- scenario: Local mode with server-signed tokens
|
|
34
|
+
parameters:
|
|
35
|
+
mode: local
|
|
36
|
+
expected-outcome: Server signs its own JWT tokens for client authentication
|
|
37
|
+
- scenario: Remote mode with full OAuth flow
|
|
38
|
+
parameters:
|
|
39
|
+
mode: remote
|
|
40
|
+
provider: https://auth.example.com
|
|
41
|
+
expected-outcome: Server redirects clients through a remote OAuth authorization flow
|
|
42
|
+
license: Apache-2.0
|
|
43
|
+
compatibility: Requires Node.js 18+ and @frontmcp/auth package
|
|
44
|
+
metadata:
|
|
45
|
+
category: auth
|
|
46
|
+
difficulty: intermediate
|
|
47
|
+
docs: https://docs.agentfront.dev/frontmcp/authentication/overview
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
# Configure Authentication for FrontMCP
|
|
51
|
+
|
|
52
|
+
This skill covers setting up authentication in a FrontMCP server. FrontMCP supports four auth modes, each suited to different deployment scenarios. All authentication logic lives in the `@frontmcp/auth` library.
|
|
53
|
+
|
|
54
|
+
## Auth Modes Overview
|
|
55
|
+
|
|
56
|
+
| Mode | Use Case | Token Issuer |
|
|
57
|
+
| ------------- | ------------------------------------------ | ------------------- |
|
|
58
|
+
| `public` | Open access with optional scoping | None |
|
|
59
|
+
| `transparent` | Validate externally-issued JWTs | External provider |
|
|
60
|
+
| `local` | Server signs its own tokens | The FrontMCP server |
|
|
61
|
+
| `remote` | Full OAuth 2.1 flow with external provider | External provider |
|
|
62
|
+
|
|
63
|
+
## Mode 1: Public
|
|
64
|
+
|
|
65
|
+
Public mode allows all connections without authentication. Use this for development or open APIs where access control is handled elsewhere.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
@App({
|
|
69
|
+
auth: {
|
|
70
|
+
mode: 'public',
|
|
71
|
+
sessionTtl: 3600,
|
|
72
|
+
anonymousScopes: ['read'],
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
class MyApp {}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- `sessionTtl` -- session lifetime in seconds.
|
|
79
|
+
- `anonymousScopes` -- scopes granted to all unauthenticated clients.
|
|
80
|
+
|
|
81
|
+
## Mode 2: Transparent
|
|
82
|
+
|
|
83
|
+
Transparent mode validates JWTs issued by an external provider without initiating an OAuth flow. The server fetches the provider's JWKS to verify token signatures.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
@App({
|
|
87
|
+
auth: {
|
|
88
|
+
mode: 'transparent',
|
|
89
|
+
provider: 'https://auth.example.com',
|
|
90
|
+
expectedAudience: 'my-api',
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
class MyApp {}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- `provider` -- the authorization server URL. FrontMCP fetches JWKS from `{provider}/.well-known/jwks.json`.
|
|
97
|
+
- `expectedAudience` -- the `aud` claim value that tokens must contain.
|
|
98
|
+
|
|
99
|
+
Use transparent mode when clients already have tokens from your identity provider and the server only needs to verify them.
|
|
100
|
+
|
|
101
|
+
## Mode 3: Local
|
|
102
|
+
|
|
103
|
+
Local mode lets the FrontMCP server sign its own JWT tokens. This is useful for internal services or environments where an external identity provider is not available.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
@App({
|
|
107
|
+
auth: {
|
|
108
|
+
mode: 'local',
|
|
109
|
+
local: {
|
|
110
|
+
issuer: 'my-server',
|
|
111
|
+
audience: 'my-api',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
class MyApp {}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- `local.issuer` -- the `iss` claim set in generated tokens.
|
|
119
|
+
- `local.audience` -- the `aud` claim set in generated tokens.
|
|
120
|
+
|
|
121
|
+
The server generates a signing key pair on startup (or loads one from the configured key store). Clients obtain tokens through a server-provided endpoint.
|
|
122
|
+
|
|
123
|
+
## Mode 4: Remote
|
|
124
|
+
|
|
125
|
+
Remote mode performs a full OAuth 2.1 authorization flow with an external provider. Clients are redirected to the provider for authentication and return with an authorization code.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
@App({
|
|
129
|
+
auth: {
|
|
130
|
+
mode: 'remote',
|
|
131
|
+
provider: 'https://auth.example.com',
|
|
132
|
+
clientId: 'xxx',
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
class MyApp {}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- `provider` -- the OAuth 2.1 authorization server URL.
|
|
139
|
+
- `clientId` -- the OAuth client identifier registered with the provider.
|
|
140
|
+
|
|
141
|
+
## OAuth Local Dev Flow
|
|
142
|
+
|
|
143
|
+
For local development with `remote` or `transparent` mode, you can skip the full OAuth flow by setting the environment to development:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
@App({
|
|
147
|
+
auth: {
|
|
148
|
+
mode: 'remote',
|
|
149
|
+
provider: 'https://auth.example.com',
|
|
150
|
+
clientId: 'dev-client-id',
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
class MyApp {}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
When `NODE_ENV=development`, FrontMCP relaxes token validation to support local identity provider instances (e.g., a local Keycloak or mock OAuth server). Tokens are still validated, but HTTPS requirements and strict issuer checks are loosened.
|
|
157
|
+
|
|
158
|
+
## Multi-App Auth
|
|
159
|
+
|
|
160
|
+
Each `@App` in a FrontMCP server can have a different auth configuration. This is useful when a single server hosts multiple logical applications with different security requirements:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
@App({
|
|
164
|
+
name: 'public-api',
|
|
165
|
+
auth: {
|
|
166
|
+
mode: 'public',
|
|
167
|
+
sessionTtl: 3600,
|
|
168
|
+
anonymousScopes: ['read'],
|
|
169
|
+
},
|
|
170
|
+
tools: [PublicSearchTool, PublicInfoTool],
|
|
171
|
+
})
|
|
172
|
+
class PublicApi {}
|
|
173
|
+
|
|
174
|
+
@App({
|
|
175
|
+
name: 'admin-api',
|
|
176
|
+
auth: {
|
|
177
|
+
mode: 'remote',
|
|
178
|
+
provider: 'https://auth.example.com',
|
|
179
|
+
clientId: 'admin-client',
|
|
180
|
+
},
|
|
181
|
+
tools: [AdminTool, ConfigTool],
|
|
182
|
+
})
|
|
183
|
+
class AdminApi {}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Credential Vault
|
|
187
|
+
|
|
188
|
+
The credential vault stores downstream API tokens obtained during the OAuth flow. Use it when your MCP tools need to call external APIs on behalf of the authenticated user:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
@App({
|
|
192
|
+
auth: {
|
|
193
|
+
mode: 'remote',
|
|
194
|
+
provider: 'https://auth.example.com',
|
|
195
|
+
clientId: 'mcp-client-id',
|
|
196
|
+
},
|
|
197
|
+
vault: {
|
|
198
|
+
encryption: {
|
|
199
|
+
secret: process.env['VAULT_SECRET'],
|
|
200
|
+
},
|
|
201
|
+
providers: [
|
|
202
|
+
{
|
|
203
|
+
name: 'github',
|
|
204
|
+
type: 'oauth2',
|
|
205
|
+
scopes: ['repo', 'read:user'],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: 'slack',
|
|
209
|
+
type: 'oauth2',
|
|
210
|
+
scopes: ['chat:write', 'channels:read'],
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
})
|
|
215
|
+
class MyApp {}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Tools access downstream credentials via the `this.authProviders` context extension:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
@Tool({ name: 'create_github_issue' })
|
|
222
|
+
class CreateGithubIssueTool extends ToolContext {
|
|
223
|
+
async execute(input: { title: string; body: string }) {
|
|
224
|
+
// Access downstream credentials via the authProviders context extension
|
|
225
|
+
const github = await this.authProviders.get('github');
|
|
226
|
+
const headers = await this.authProviders.headers('github');
|
|
227
|
+
// Use headers to call GitHub API
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The `authProviders` accessor (from `@frontmcp/auth`) provides:
|
|
233
|
+
|
|
234
|
+
- `get(provider)` -- get the credential/token for a provider.
|
|
235
|
+
- `headers(provider)` -- get pre-formatted auth headers for HTTP requests.
|
|
236
|
+
- `has(provider)` -- check if a provider is configured.
|
|
237
|
+
- `refresh(provider)` -- force refresh the credential.
|
|
238
|
+
|
|
239
|
+
## Common Mistakes
|
|
240
|
+
|
|
241
|
+
- **Using memory session store in production** -- sessions are lost on restart. Use Redis or Vercel KV.
|
|
242
|
+
- **Hardcoding secrets** -- use environment variables for `clientId`, vault secrets, and Redis passwords.
|
|
243
|
+
- **Missing audience validation** -- always set the audience field. Without it, tokens from any audience would be accepted.
|
|
244
|
+
|
|
245
|
+
## Reference
|
|
246
|
+
|
|
247
|
+
- Auth docs: [docs.agentfront.dev/frontmcp/authentication/overview](https://docs.agentfront.dev/frontmcp/authentication/overview)
|
|
248
|
+
- Auth package: `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth)
|
|
249
|
+
- Auth options interface: import `AuthOptionsInput` from `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth/src/options)
|
|
250
|
+
- Credential vault: import from `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth/src/vault)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Auth Modes Detailed Comparison
|
|
2
|
+
|
|
3
|
+
## Public Mode
|
|
4
|
+
|
|
5
|
+
No authentication required. All requests get anonymous access.
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
auth: {
|
|
9
|
+
mode: 'public',
|
|
10
|
+
sessionTtl: 3600,
|
|
11
|
+
anonymousScopes: ['read', 'write'],
|
|
12
|
+
publicAccess: { tools: true, resources: true, prompts: true },
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Use when:** Development, internal tools, public APIs.
|
|
17
|
+
|
|
18
|
+
## Transparent Mode
|
|
19
|
+
|
|
20
|
+
Server validates tokens from an upstream identity provider. Does not issue or refresh tokens.
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
auth: {
|
|
24
|
+
mode: 'transparent',
|
|
25
|
+
provider: 'https://auth.example.com',
|
|
26
|
+
expectedAudience: 'my-api',
|
|
27
|
+
clientId: 'my-client-id',
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Use when:** Behind an API gateway or reverse proxy that handles auth.
|
|
32
|
+
|
|
33
|
+
## Local Mode
|
|
34
|
+
|
|
35
|
+
Server signs its own JWT tokens. Full control over token lifecycle.
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
auth: {
|
|
39
|
+
mode: 'local',
|
|
40
|
+
local: {
|
|
41
|
+
issuer: 'my-server',
|
|
42
|
+
audience: 'my-api',
|
|
43
|
+
},
|
|
44
|
+
tokenStorage: 'redis',
|
|
45
|
+
consent: { enabled: true },
|
|
46
|
+
incrementalAuth: { enabled: true },
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Use when:** Standalone servers with full auth control, development with local OAuth.
|
|
51
|
+
|
|
52
|
+
## Remote Mode
|
|
53
|
+
|
|
54
|
+
Server delegates to an upstream auth orchestrator for token management.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
auth: {
|
|
58
|
+
mode: 'remote',
|
|
59
|
+
provider: 'https://auth.example.com',
|
|
60
|
+
clientId: 'my-client-id',
|
|
61
|
+
clientSecret: process.env.AUTH_SECRET,
|
|
62
|
+
tokenStorage: 'redis',
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Use when:** Enterprise deployments with centralized identity management.
|
|
67
|
+
|
|
68
|
+
## Comparison Table
|
|
69
|
+
|
|
70
|
+
| Feature | Public | Transparent | Local | Remote |
|
|
71
|
+
| ---------------- | ------------- | --------------- | ----------- | ------------ |
|
|
72
|
+
| Token issuance | Anonymous JWT | None (upstream) | Self-signed | Orchestrator |
|
|
73
|
+
| Token refresh | No | No | Yes | Yes |
|
|
74
|
+
| PKCE support | No | No | Yes | Yes |
|
|
75
|
+
| Credential vault | No | No | Yes | Yes |
|
|
76
|
+
| Consent flow | No | No | Optional | Optional |
|
|
77
|
+
| Federated auth | No | No | Optional | Optional |
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configure-session
|
|
3
|
+
description: Configure session storage with Redis, Vercel KV, or in-memory backends. Use when setting up sessions, choosing a storage provider, or configuring TTL and key prefixes.
|
|
4
|
+
tags:
|
|
5
|
+
- session
|
|
6
|
+
- storage
|
|
7
|
+
- redis
|
|
8
|
+
- memory
|
|
9
|
+
bundle:
|
|
10
|
+
- recommended
|
|
11
|
+
- full
|
|
12
|
+
visibility: both
|
|
13
|
+
priority: 5
|
|
14
|
+
parameters:
|
|
15
|
+
- name: provider
|
|
16
|
+
description: Session storage provider
|
|
17
|
+
type: string
|
|
18
|
+
required: false
|
|
19
|
+
default: memory
|
|
20
|
+
- name: ttl
|
|
21
|
+
description: Default session TTL in milliseconds
|
|
22
|
+
type: number
|
|
23
|
+
required: false
|
|
24
|
+
default: 3600000
|
|
25
|
+
- name: key-prefix
|
|
26
|
+
description: Redis/KV key prefix for session keys
|
|
27
|
+
type: string
|
|
28
|
+
required: false
|
|
29
|
+
default: 'mcp:session:'
|
|
30
|
+
examples:
|
|
31
|
+
- scenario: Configure Redis session store for production
|
|
32
|
+
parameters:
|
|
33
|
+
provider: redis
|
|
34
|
+
expected-outcome: Sessions are persisted in Redis with automatic TTL expiration and key prefixing
|
|
35
|
+
- scenario: Configure Vercel KV for serverless deployment
|
|
36
|
+
parameters:
|
|
37
|
+
provider: vercel-kv
|
|
38
|
+
expected-outcome: Sessions use Vercel KV with environment-based credentials
|
|
39
|
+
- scenario: Use memory store for local development
|
|
40
|
+
parameters:
|
|
41
|
+
provider: memory
|
|
42
|
+
expected-outcome: Sessions are stored in-process memory, suitable for development only
|
|
43
|
+
license: Apache-2.0
|
|
44
|
+
compatibility: Requires Node.js 18+. Redis provider requires ioredis. Vercel KV provider requires @vercel/kv.
|
|
45
|
+
metadata:
|
|
46
|
+
category: auth
|
|
47
|
+
difficulty: beginner
|
|
48
|
+
docs: https://docs.agentfront.dev/frontmcp/deployment/redis-setup
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
# Configure Session Management
|
|
52
|
+
|
|
53
|
+
This skill covers setting up session storage in FrontMCP. Sessions track authenticated user state, token storage, and request context across MCP interactions.
|
|
54
|
+
|
|
55
|
+
## Storage Providers
|
|
56
|
+
|
|
57
|
+
| Provider | Use Case | Persistence | Package Required |
|
|
58
|
+
| ----------- | ------------------- | ----------- | ---------------- |
|
|
59
|
+
| `memory` | Development/testing | None | None (default) |
|
|
60
|
+
| `redis` | Node.js production | Yes | `ioredis` |
|
|
61
|
+
| `vercel-kv` | Vercel deployments | Yes | `@vercel/kv` |
|
|
62
|
+
|
|
63
|
+
Never use the memory store in production. Sessions are lost on process restart, which breaks authentication for all connected clients.
|
|
64
|
+
|
|
65
|
+
## Redis (Production)
|
|
66
|
+
|
|
67
|
+
Configure Redis session storage via the `@FrontMcp` decorator:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { FrontMcp, App } from '@frontmcp/sdk';
|
|
71
|
+
|
|
72
|
+
@App()
|
|
73
|
+
class MyApp {}
|
|
74
|
+
|
|
75
|
+
@FrontMcp({
|
|
76
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
77
|
+
apps: [MyApp],
|
|
78
|
+
redis: {
|
|
79
|
+
provider: 'redis',
|
|
80
|
+
host: process.env['REDIS_HOST'] ?? 'localhost',
|
|
81
|
+
port: Number(process.env['REDIS_PORT'] ?? 6379),
|
|
82
|
+
password: process.env['REDIS_PASSWORD'],
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
class MyServer {}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The SDK internally calls `createSessionStore()` to create a `RedisSessionStore`. The factory lazy-loads `ioredis` so it is not bundled when you use a different provider.
|
|
89
|
+
|
|
90
|
+
## Vercel KV
|
|
91
|
+
|
|
92
|
+
For Vercel deployments, use the `vercel-kv` provider. Credentials are read from environment variables set automatically by the Vercel platform:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
@FrontMcp({
|
|
96
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
97
|
+
apps: [MyApp],
|
|
98
|
+
redis: { provider: 'vercel-kv' },
|
|
99
|
+
})
|
|
100
|
+
class MyServer {}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Required environment variables (auto-injected when a KV store is linked to your Vercel project):
|
|
104
|
+
|
|
105
|
+
| Variable | Description |
|
|
106
|
+
| ------------------- | ------------------------------ |
|
|
107
|
+
| `KV_REST_API_URL` | Vercel KV REST endpoint |
|
|
108
|
+
| `KV_REST_API_TOKEN` | Vercel KV authentication token |
|
|
109
|
+
|
|
110
|
+
## Memory (Development Default)
|
|
111
|
+
|
|
112
|
+
When no Redis or KV configuration is provided, the SDK falls back to an in-memory store. This is suitable only for development:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
@FrontMcp({
|
|
116
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
117
|
+
apps: [MyApp],
|
|
118
|
+
// No redis config -- defaults to memory
|
|
119
|
+
})
|
|
120
|
+
class MyServer {}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Key Prefix
|
|
124
|
+
|
|
125
|
+
All persistent stores support a `keyPrefix` option that namespaces session keys. This is important when multiple FrontMCP servers share the same Redis instance:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
@FrontMcp({
|
|
129
|
+
info: { name: 'billing-server', version: '1.0.0' },
|
|
130
|
+
apps: [MyApp],
|
|
131
|
+
redis: {
|
|
132
|
+
provider: 'redis',
|
|
133
|
+
host: 'shared-redis.internal',
|
|
134
|
+
port: 6379,
|
|
135
|
+
keyPrefix: 'billing-mcp:session:',
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
class BillingServer {}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Use a unique prefix per server to prevent session key collisions.
|
|
142
|
+
|
|
143
|
+
## TTL Configuration
|
|
144
|
+
|
|
145
|
+
The `defaultTtlMs` option controls how long sessions live before expiring:
|
|
146
|
+
|
|
147
|
+
| Scenario | Recommended TTL |
|
|
148
|
+
| ---------------------------- | ----------------------- |
|
|
149
|
+
| Interactive user sessions | `3_600_000` (1 hour) |
|
|
150
|
+
| Long-running agent workflows | `86_400_000` (24 hours) |
|
|
151
|
+
| Short-lived CI/CD operations | `600_000` (10 minutes) |
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
@FrontMcp({
|
|
155
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
156
|
+
apps: [MyApp],
|
|
157
|
+
redis: {
|
|
158
|
+
provider: 'redis',
|
|
159
|
+
host: 'localhost',
|
|
160
|
+
port: 6379,
|
|
161
|
+
defaultTtlMs: 86_400_000, // 24 hours for agent workflows
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
class MyServer {}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Pub/Sub for Resource Subscriptions
|
|
168
|
+
|
|
169
|
+
If your server uses resource subscriptions (clients subscribe to resource change notifications), you need a pub/sub channel. Vercel KV does not support pub/sub, so you must use Redis for the pub/sub channel even when using Vercel KV for sessions:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { createSessionStore, createPubsubStore } from '@frontmcp/sdk/auth/session';
|
|
173
|
+
|
|
174
|
+
// Sessions in Vercel KV
|
|
175
|
+
const sessionStore = await createSessionStore({
|
|
176
|
+
provider: 'vercel-kv',
|
|
177
|
+
url: process.env['KV_REST_API_URL'],
|
|
178
|
+
token: process.env['KV_REST_API_TOKEN'],
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Pub/sub requires Redis
|
|
182
|
+
const pubsubStore = createPubsubStore({
|
|
183
|
+
provider: 'redis',
|
|
184
|
+
host: process.env['REDIS_HOST'] ?? 'localhost',
|
|
185
|
+
port: 6379,
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Common Mistakes
|
|
190
|
+
|
|
191
|
+
- **Constructing stores directly** -- always use factory functions (`createSessionStore`). Direct construction bypasses lazy-loading and key prefix normalization.
|
|
192
|
+
- **Using memory store in production** -- sessions vanish on restart. Clients must re-authenticate and in-flight workflows are lost.
|
|
193
|
+
- **Missing `await` for Vercel KV** -- the `createSessionStore` factory is async when the provider is `vercel-kv`. Forgetting to await causes the store to be used before its connection is ready.
|
|
194
|
+
- **Sharing key prefixes** -- if two servers share a Redis instance with the same prefix, their sessions collide. Always use a unique prefix per server.
|
|
195
|
+
|
|
196
|
+
## Reference
|
|
197
|
+
|
|
198
|
+
- Session docs: [docs.agentfront.dev/frontmcp/deployment/redis-setup](https://docs.agentfront.dev/frontmcp/deployment/redis-setup)
|
|
199
|
+
- Session store factory: `createSessionStore()` — import from `@frontmcp/sdk`
|
|
200
|
+
- Redis session store: import from `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth/src/session)
|
|
201
|
+
- Vercel KV session store: import from `@frontmcp/auth` — [source](https://github.com/agentfront/frontmcp/tree/main/libs/auth/src/session)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configure-elicitation
|
|
3
|
+
description: Enable interactive user input requests from tools during execution. Use when tools need to ask the user for confirmation, choices, or additional data mid-execution.
|
|
4
|
+
tags: [elicitation, user-input, interactive, confirmation, form]
|
|
5
|
+
examples:
|
|
6
|
+
- scenario: Tool asks user for confirmation before destructive action
|
|
7
|
+
expected-outcome: Execution pauses, user confirms, tool proceeds
|
|
8
|
+
- scenario: Tool presents a form for user to fill in
|
|
9
|
+
expected-outcome: User fills form fields, tool receives structured input
|
|
10
|
+
priority: 6
|
|
11
|
+
visibility: both
|
|
12
|
+
license: Apache-2.0
|
|
13
|
+
metadata:
|
|
14
|
+
docs: https://docs.agentfront.dev/frontmcp/servers/elicitation
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Configuring Elicitation
|
|
18
|
+
|
|
19
|
+
Elicitation allows tools to request interactive input from users mid-execution — confirmations, choices, or structured form data.
|
|
20
|
+
|
|
21
|
+
## When to Use
|
|
22
|
+
|
|
23
|
+
Enable elicitation when:
|
|
24
|
+
|
|
25
|
+
- Tools need user confirmation before destructive actions (delete, deploy, overwrite)
|
|
26
|
+
- Tools need additional input during execution (file selection, parameter choice)
|
|
27
|
+
- Building multi-step workflows that require user decisions at each stage
|
|
28
|
+
|
|
29
|
+
## Enable Elicitation
|
|
30
|
+
|
|
31
|
+
### Basic (In-Memory)
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
@FrontMcp({
|
|
35
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
36
|
+
apps: [MyApp],
|
|
37
|
+
elicitation: {
|
|
38
|
+
enabled: true,
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
class Server {}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### With Redis (Distributed/Production)
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
@FrontMcp({
|
|
48
|
+
info: { name: 'my-server', version: '1.0.0' },
|
|
49
|
+
apps: [MyApp],
|
|
50
|
+
elicitation: {
|
|
51
|
+
enabled: true,
|
|
52
|
+
redis: { provider: 'redis', host: 'localhost', port: 6379 },
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
class Server {}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## ElicitationOptionsInput
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
interface ElicitationOptionsInput {
|
|
62
|
+
enabled?: boolean; // default: false
|
|
63
|
+
redis?: RedisOptionsInput; // storage for elicitation state
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Using Elicitation in Tools
|
|
68
|
+
|
|
69
|
+
When elicitation is enabled, tools can request user input via the MCP elicitation protocol:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
73
|
+
import { z } from 'zod';
|
|
74
|
+
|
|
75
|
+
@Tool({
|
|
76
|
+
name: 'delete_records',
|
|
77
|
+
description: 'Delete records from the database',
|
|
78
|
+
inputSchema: {
|
|
79
|
+
table: z.string(),
|
|
80
|
+
filter: z.string(),
|
|
81
|
+
},
|
|
82
|
+
outputSchema: { deleted: z.number() },
|
|
83
|
+
})
|
|
84
|
+
class DeleteRecordsTool extends ToolContext {
|
|
85
|
+
async execute(input: { table: string; filter: string }) {
|
|
86
|
+
// Count records that would be deleted
|
|
87
|
+
const db = this.get(DB_TOKEN);
|
|
88
|
+
const count = await db.count(input.table, input.filter);
|
|
89
|
+
|
|
90
|
+
// Request confirmation from user before proceeding
|
|
91
|
+
const confirmation = await this.elicit({
|
|
92
|
+
message: `This will delete ${count} records from ${input.table}. Are you sure?`,
|
|
93
|
+
requestedSchema: {
|
|
94
|
+
type: 'object',
|
|
95
|
+
properties: {
|
|
96
|
+
confirmed: { type: 'boolean', description: 'Confirm deletion' },
|
|
97
|
+
},
|
|
98
|
+
required: ['confirmed'],
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (!confirmation || !confirmation.confirmed) {
|
|
103
|
+
return { deleted: 0 };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const deleted = await db.delete(input.table, input.filter);
|
|
107
|
+
return { deleted };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## How It Works
|
|
113
|
+
|
|
114
|
+
1. Tool calls `this.elicit()` with a message and requested schema
|
|
115
|
+
2. Server sends an `elicitation/request` to the client
|
|
116
|
+
3. Client displays the request to the user (UI varies by client)
|
|
117
|
+
4. User responds with structured data matching the schema
|
|
118
|
+
5. `this.elicit()` returns the user's response
|
|
119
|
+
6. Tool continues execution with the response
|
|
120
|
+
|
|
121
|
+
## Notes
|
|
122
|
+
|
|
123
|
+
- When `enabled: false` (default), `this.elicit()` is not available — keeps resource overhead low
|
|
124
|
+
- When enabled, tool output schemas are automatically extended with elicitation fallback type
|
|
125
|
+
- Use Redis storage for production/multi-instance deployments
|
|
126
|
+
- Not all MCP clients support elicitation — handle gracefully when `this.elicit()` returns `undefined`
|
|
127
|
+
|
|
128
|
+
## Verification
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Enable elicitation and start
|
|
132
|
+
frontmcp dev
|
|
133
|
+
|
|
134
|
+
# Test with an MCP client that supports elicitation
|
|
135
|
+
# The tool should pause and request user input
|
|
136
|
+
```
|