create-chaaskit 0.1.0
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/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +25 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add-infra.d.ts +6 -0
- package/dist/commands/add-infra.d.ts.map +1 -0
- package/dist/commands/add-infra.js +160 -0
- package/dist/commands/add-infra.js.map +1 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +63 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/db-sync.d.ts +13 -0
- package/dist/commands/db-sync.d.ts.map +1 -0
- package/dist/commands/db-sync.js +108 -0
- package/dist/commands/db-sync.js.map +1 -0
- package/dist/commands/dev.d.ts +7 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +61 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +214 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/.env.example +24 -0
- package/dist/templates/README.md +81 -0
- package/dist/templates/app/components/AcceptInviteClient.tsx +10 -0
- package/dist/templates/app/components/AdminDashboardClient.tsx +10 -0
- package/dist/templates/app/components/AdminTeamClient.tsx +10 -0
- package/dist/templates/app/components/AdminTeamsClient.tsx +10 -0
- package/dist/templates/app/components/AdminUsersClient.tsx +10 -0
- package/dist/templates/app/components/ApiKeysClient.tsx +10 -0
- package/dist/templates/app/components/AutomationsClient.tsx +10 -0
- package/dist/templates/app/components/ChatClient.tsx +13 -0
- package/dist/templates/app/components/ClientOnly.tsx +6 -0
- package/dist/templates/app/components/DocumentsClient.tsx +10 -0
- package/dist/templates/app/components/OAuthConsentClient.tsx +10 -0
- package/dist/templates/app/components/PricingClient.tsx +10 -0
- package/dist/templates/app/components/TeamSettingsClient.tsx +10 -0
- package/dist/templates/app/components/VerifyEmailClient.tsx +10 -0
- package/dist/templates/app/entry.client.tsx +12 -0
- package/dist/templates/app/entry.server.tsx +67 -0
- package/dist/templates/app/root.tsx +91 -0
- package/dist/templates/app/routes/_index.tsx +82 -0
- package/dist/templates/app/routes/admin._index.tsx +57 -0
- package/dist/templates/app/routes/admin.teams.$teamId.tsx +57 -0
- package/dist/templates/app/routes/admin.teams._index.tsx +57 -0
- package/dist/templates/app/routes/admin.users.tsx +57 -0
- package/dist/templates/app/routes/api-keys.tsx +57 -0
- package/dist/templates/app/routes/automations.tsx +57 -0
- package/dist/templates/app/routes/chat._index.tsx +11 -0
- package/dist/templates/app/routes/chat.admin._index.tsx +10 -0
- package/dist/templates/app/routes/chat.admin.teams.$teamId.tsx +10 -0
- package/dist/templates/app/routes/chat.admin.teams._index.tsx +10 -0
- package/dist/templates/app/routes/chat.admin.users.tsx +10 -0
- package/dist/templates/app/routes/chat.api-keys.tsx +10 -0
- package/dist/templates/app/routes/chat.automations.tsx +10 -0
- package/dist/templates/app/routes/chat.documents.tsx +10 -0
- package/dist/templates/app/routes/chat.team.$teamId.settings.tsx +10 -0
- package/dist/templates/app/routes/chat.thread.$threadId.tsx +11 -0
- package/dist/templates/app/routes/chat.tsx +39 -0
- package/dist/templates/app/routes/documents.tsx +57 -0
- package/dist/templates/app/routes/invite.$token.tsx +10 -0
- package/dist/templates/app/routes/login.tsx +334 -0
- package/dist/templates/app/routes/oauth.consent.tsx +10 -0
- package/dist/templates/app/routes/pricing.tsx +10 -0
- package/dist/templates/app/routes/privacy.tsx +197 -0
- package/dist/templates/app/routes/register.tsx +398 -0
- package/dist/templates/app/routes/shared.$shareId.tsx +226 -0
- package/dist/templates/app/routes/team.$teamId.settings.tsx +57 -0
- package/dist/templates/app/routes/terms.tsx +173 -0
- package/dist/templates/app/routes/thread.$threadId.tsx +102 -0
- package/dist/templates/app/routes/verify-email.tsx +10 -0
- package/dist/templates/app/routes.ts +47 -0
- package/dist/templates/config/app.config.ts +216 -0
- package/dist/templates/docs/admin.md +257 -0
- package/dist/templates/docs/api-keys.md +403 -0
- package/dist/templates/docs/authentication.md +247 -0
- package/dist/templates/docs/configuration.md +1212 -0
- package/dist/templates/docs/custom-pages.md +466 -0
- package/dist/templates/docs/deployment.md +362 -0
- package/dist/templates/docs/development.md +411 -0
- package/dist/templates/docs/documents.md +293 -0
- package/dist/templates/docs/extensions.md +639 -0
- package/dist/templates/docs/index.md +139 -0
- package/dist/templates/docs/installation.md +286 -0
- package/dist/templates/docs/mcp.md +952 -0
- package/dist/templates/docs/native-tools.md +688 -0
- package/dist/templates/docs/queue.md +514 -0
- package/dist/templates/docs/scheduled-prompts.md +279 -0
- package/dist/templates/docs/settings.md +415 -0
- package/dist/templates/docs/slack.md +318 -0
- package/dist/templates/docs/styling.md +288 -0
- package/dist/templates/extensions/agents/.gitkeep +0 -0
- package/dist/templates/extensions/pages/.gitkeep +0 -0
- package/dist/templates/extensions/payment-plans/.gitkeep +0 -0
- package/dist/templates/index.html +16 -0
- package/dist/templates/infra-aws/.github/workflows/deploy.yml +95 -0
- package/dist/templates/infra-aws/README.md +207 -0
- package/dist/templates/infra-aws/bin/cdk.ts +18 -0
- package/dist/templates/infra-aws/cdk.json +43 -0
- package/dist/templates/infra-aws/config/deployment.ts +156 -0
- package/dist/templates/infra-aws/lib/chaaskit-stack.ts +419 -0
- package/dist/templates/infra-aws/package.json +27 -0
- package/dist/templates/infra-aws/scripts/build-app.sh +63 -0
- package/dist/templates/infra-aws/tsconfig.json +25 -0
- package/dist/templates/package.json +46 -0
- package/dist/templates/prisma/schema/base.prisma +584 -0
- package/dist/templates/prisma/schema/custom.prisma +24 -0
- package/dist/templates/prisma/schema.prisma +271 -0
- package/dist/templates/public/favicon.svg +4 -0
- package/dist/templates/public/logo.svg +4 -0
- package/dist/templates/react-router.config.ts +11 -0
- package/dist/templates/server.js +52 -0
- package/dist/templates/src/main.tsx +8 -0
- package/dist/templates/tsconfig.json +26 -0
- package/dist/templates/vite.config.ts +26 -0
- package/package.json +46 -0
|
@@ -0,0 +1,952 @@
|
|
|
1
|
+
# MCP Integration
|
|
2
|
+
|
|
3
|
+
The Model Context Protocol (MCP) enables AI agents to use external tools. This template includes full MCP support for tool discovery, execution, and per-user authentication.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
MCP allows the AI assistant to:
|
|
8
|
+
- Access external data sources
|
|
9
|
+
- Execute commands on your behalf
|
|
10
|
+
- Interact with APIs and services
|
|
11
|
+
- Read and manipulate files
|
|
12
|
+
- Render rich UI widgets from tool responses
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
User Message --> Chat API --> AI Agent (Anthropic/OpenAI)
|
|
18
|
+
|
|
|
19
|
+
tool_use block
|
|
20
|
+
|
|
|
21
|
+
MCP Client Manager
|
|
22
|
+
|
|
|
23
|
+
Get User Credentials (if needed)
|
|
24
|
+
|
|
|
25
|
+
Execute Tool
|
|
26
|
+
|
|
|
27
|
+
Tool Result --> Continue AI Loop
|
|
28
|
+
|
|
|
29
|
+
Final Response --> User
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Configuration
|
|
33
|
+
|
|
34
|
+
Configure MCP servers in `config/app.config.ts`:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
mcp: {
|
|
38
|
+
servers: [
|
|
39
|
+
// Stdio server - no authentication (local process)
|
|
40
|
+
{
|
|
41
|
+
id: 'filesystem',
|
|
42
|
+
name: 'File System',
|
|
43
|
+
transport: 'stdio',
|
|
44
|
+
command: 'npx',
|
|
45
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
|
|
46
|
+
enabled: true,
|
|
47
|
+
},
|
|
48
|
+
// Streamable HTTP with admin API key (shared across all users)
|
|
49
|
+
{
|
|
50
|
+
id: 'company-tools',
|
|
51
|
+
name: 'Company Tools',
|
|
52
|
+
transport: 'streamable-http',
|
|
53
|
+
url: 'https://tools.company.com/mcp',
|
|
54
|
+
enabled: true,
|
|
55
|
+
authMode: 'admin',
|
|
56
|
+
adminApiKeyEnvVar: 'COMPANY_TOOLS_API_KEY',
|
|
57
|
+
},
|
|
58
|
+
// Streamable HTTP with user API key (each user provides their own)
|
|
59
|
+
{
|
|
60
|
+
id: 'openai-tools',
|
|
61
|
+
name: 'OpenAI Tools',
|
|
62
|
+
transport: 'streamable-http',
|
|
63
|
+
url: 'https://mcp.openai.com',
|
|
64
|
+
enabled: true,
|
|
65
|
+
authMode: 'user-apikey',
|
|
66
|
+
userInstructions: 'Enter your OpenAI API key from platform.openai.com',
|
|
67
|
+
},
|
|
68
|
+
// Streamable HTTP with user OAuth (each user authenticates via OAuth)
|
|
69
|
+
{
|
|
70
|
+
id: 'github-tools',
|
|
71
|
+
name: 'GitHub Tools',
|
|
72
|
+
transport: 'streamable-http',
|
|
73
|
+
url: 'https://github-mcp.example.com',
|
|
74
|
+
enabled: true,
|
|
75
|
+
authMode: 'user-oauth',
|
|
76
|
+
oauth: {
|
|
77
|
+
authorizationEndpoint: 'https://github.com/login/oauth/authorize',
|
|
78
|
+
tokenEndpoint: 'https://github.com/login/oauth/access_token',
|
|
79
|
+
clientId: '${GITHUB_MCP_CLIENT_ID}',
|
|
80
|
+
clientSecretEnvVar: 'GITHUB_MCP_CLIENT_SECRET',
|
|
81
|
+
scopes: ['repo', 'read:user'],
|
|
82
|
+
},
|
|
83
|
+
userInstructions: 'Connect your GitHub account to use repository tools',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
allowUserServers: true,
|
|
87
|
+
toolConfirmation: {
|
|
88
|
+
mode: 'all', // 'none' | 'all' | 'whitelist' | 'blacklist'
|
|
89
|
+
tools: [], // Tool patterns for whitelist/blacklist modes
|
|
90
|
+
},
|
|
91
|
+
toolTimeout: 30000,
|
|
92
|
+
showToolCalls: true, // Set to false to hide tool execution cards in chat
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Server Configuration Options
|
|
97
|
+
|
|
98
|
+
| Option | Type | Description |
|
|
99
|
+
|--------|------|-------------|
|
|
100
|
+
| `id` | string | Unique identifier |
|
|
101
|
+
| `name` | string | Display name |
|
|
102
|
+
| `transport` | `'stdio'` \| `'sse'` \| `'streamable-http'` | Connection type |
|
|
103
|
+
| `command` | string | Command to run (stdio only) |
|
|
104
|
+
| `args` | string[] | Command arguments (stdio only) |
|
|
105
|
+
| `url` | string | Server URL (sse/streamable-http) |
|
|
106
|
+
| `enabled` | boolean | Enable/disable server |
|
|
107
|
+
| `authMode` | `'none'` \| `'admin'` \| `'user-apikey'` \| `'user-oauth'` | Authentication mode |
|
|
108
|
+
| `adminApiKeyEnvVar` | string | Env var name for admin API key |
|
|
109
|
+
| `oauth` | object | OAuth configuration (see below) |
|
|
110
|
+
| `userInstructions` | string | Help text shown to users |
|
|
111
|
+
|
|
112
|
+
### OAuth Configuration
|
|
113
|
+
|
|
114
|
+
| Option | Type | Description |
|
|
115
|
+
|--------|------|-------------|
|
|
116
|
+
| `authorizationEndpoint` | string | OAuth authorization URL |
|
|
117
|
+
| `tokenEndpoint` | string | OAuth token URL |
|
|
118
|
+
| `clientId` | string | OAuth client ID (supports `${ENV_VAR}` syntax) |
|
|
119
|
+
| `clientSecretEnvVar` | string | Env var name for client secret |
|
|
120
|
+
| `scopes` | string[] | OAuth scopes to request |
|
|
121
|
+
|
|
122
|
+
### Global Options
|
|
123
|
+
|
|
124
|
+
| Option | Description |
|
|
125
|
+
|--------|-------------|
|
|
126
|
+
| `allowUserServers` | Allow users to add their own MCP servers |
|
|
127
|
+
| `toolConfirmation` | Tool confirmation settings (see below) |
|
|
128
|
+
| `toolTimeout` | Timeout for tool calls in milliseconds |
|
|
129
|
+
| `showToolCalls` | Show tool execution cards in chat (default: true) |
|
|
130
|
+
|
|
131
|
+
### Tool Confirmation Configuration
|
|
132
|
+
|
|
133
|
+
| Option | Type | Description |
|
|
134
|
+
|--------|------|-------------|
|
|
135
|
+
| `mode` | `'none'` \| `'all'` \| `'whitelist'` \| `'blacklist'` | Confirmation mode |
|
|
136
|
+
| `tools` | string[] | Tool patterns for whitelist/blacklist modes |
|
|
137
|
+
|
|
138
|
+
## Transport Types
|
|
139
|
+
|
|
140
|
+
### Stdio Transport
|
|
141
|
+
|
|
142
|
+
Spawns a child process and communicates via stdin/stdout. No authentication needed.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
{
|
|
146
|
+
id: 'my-server',
|
|
147
|
+
transport: 'stdio',
|
|
148
|
+
command: 'npx',
|
|
149
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/path'],
|
|
150
|
+
enabled: true,
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### SSE Transport
|
|
155
|
+
|
|
156
|
+
Connects to an HTTP server using Server-Sent Events.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
{
|
|
160
|
+
id: 'my-server',
|
|
161
|
+
transport: 'sse',
|
|
162
|
+
url: 'http://localhost:8080/sse',
|
|
163
|
+
enabled: true,
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Streamable HTTP Transport
|
|
168
|
+
|
|
169
|
+
Modern HTTP-based transport with support for authentication. Recommended for remote servers.
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
{
|
|
173
|
+
id: 'my-server',
|
|
174
|
+
transport: 'streamable-http',
|
|
175
|
+
url: 'https://api.example.com/mcp',
|
|
176
|
+
enabled: true,
|
|
177
|
+
authMode: 'user-apikey',
|
|
178
|
+
userInstructions: 'Enter your API key',
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Authentication Modes
|
|
183
|
+
|
|
184
|
+
### No Authentication (`none`)
|
|
185
|
+
|
|
186
|
+
Default for stdio servers. No credentials required.
|
|
187
|
+
|
|
188
|
+
### Admin API Key (`admin`)
|
|
189
|
+
|
|
190
|
+
A shared API key stored in environment variables. All users share the same credentials.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
{
|
|
194
|
+
authMode: 'admin',
|
|
195
|
+
adminApiKeyEnvVar: 'MY_SERVICE_API_KEY',
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### User API Key (`user-apikey`)
|
|
200
|
+
|
|
201
|
+
Each user provides their own API key via the Settings modal.
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
{
|
|
205
|
+
authMode: 'user-apikey',
|
|
206
|
+
userInstructions: 'Enter your API key from dashboard.example.com',
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### User OAuth (`user-oauth`)
|
|
211
|
+
|
|
212
|
+
Each user authenticates via OAuth 2.0. Supports:
|
|
213
|
+
- Manual OAuth configuration
|
|
214
|
+
- RFC 9728/8414 auto-discovery (if server supports it)
|
|
215
|
+
- PKCE for enhanced security
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
{
|
|
219
|
+
authMode: 'user-oauth',
|
|
220
|
+
oauth: {
|
|
221
|
+
authorizationEndpoint: 'https://provider.com/oauth/authorize',
|
|
222
|
+
tokenEndpoint: 'https://provider.com/oauth/token',
|
|
223
|
+
clientId: '${OAUTH_CLIENT_ID}',
|
|
224
|
+
clientSecretEnvVar: 'OAUTH_CLIENT_SECRET',
|
|
225
|
+
scopes: ['read', 'write'],
|
|
226
|
+
},
|
|
227
|
+
userInstructions: 'Connect your account to use these tools',
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## OAuth Auto-Discovery
|
|
232
|
+
|
|
233
|
+
For servers that support RFC 9728 or RFC 8414, OAuth configuration can be auto-discovered:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
{
|
|
237
|
+
id: 'modern-service',
|
|
238
|
+
transport: 'streamable-http',
|
|
239
|
+
url: 'https://api.modern-service.com/mcp',
|
|
240
|
+
enabled: true,
|
|
241
|
+
authMode: 'user-oauth',
|
|
242
|
+
// No oauth config needed - will be discovered automatically
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The system will check:
|
|
247
|
+
1. `/.well-known/oauth-protected-resource` (RFC 9728)
|
|
248
|
+
2. `/.well-known/oauth-authorization-server` (RFC 8414)
|
|
249
|
+
|
|
250
|
+
## User Credential Management
|
|
251
|
+
|
|
252
|
+
Users manage their MCP credentials in the Settings modal:
|
|
253
|
+
|
|
254
|
+
- **API Key servers**: Text input to enter/update key
|
|
255
|
+
- **OAuth servers**: "Connect" button to start OAuth flow
|
|
256
|
+
- **Disconnect**: Remove stored credentials
|
|
257
|
+
|
|
258
|
+
Credentials are encrypted at rest using AES-256-GCM.
|
|
259
|
+
|
|
260
|
+
### Environment Variables
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Credential encryption key (min 32 chars, falls back to SESSION_SECRET)
|
|
264
|
+
MCP_CREDENTIAL_KEY=your-32-char-secure-key-here
|
|
265
|
+
|
|
266
|
+
# Admin MCP server keys
|
|
267
|
+
COMPANY_TOOLS_API_KEY=sk-...
|
|
268
|
+
|
|
269
|
+
# OAuth client credentials
|
|
270
|
+
GITHUB_MCP_CLIENT_ID=...
|
|
271
|
+
GITHUB_MCP_CLIENT_SECRET=...
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## UI Resource Widgets
|
|
275
|
+
|
|
276
|
+
MCP tools can return rich UI content using the OpenAI Apps SDK format. When a tool response includes a `uiResource` with HTML content, it's rendered as an interactive widget.
|
|
277
|
+
|
|
278
|
+
### How It Works
|
|
279
|
+
|
|
280
|
+
1. Tool returns `uiResource` with `text` (HTML) and `mimeType: 'text/html'`
|
|
281
|
+
2. HTML is rendered in a sandboxed iframe
|
|
282
|
+
3. `window.openai` API is injected with tool input/output data
|
|
283
|
+
|
|
284
|
+
### OpenAI Apps SDK Integration
|
|
285
|
+
|
|
286
|
+
The iframe receives:
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
window.openai = {
|
|
290
|
+
theme: 'light', // or 'dark' - matches app theme
|
|
291
|
+
canvas: {
|
|
292
|
+
getContent: async () => ({
|
|
293
|
+
toolInput: { /* original tool arguments */ },
|
|
294
|
+
toolOutput: { /* tool response data */ }
|
|
295
|
+
})
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Structured Content
|
|
301
|
+
|
|
302
|
+
Tools can return `structuredContent` for rich data that's:
|
|
303
|
+
- Passed to UI widgets via `window.openai.canvas.getContent()`
|
|
304
|
+
- Included in agent context for follow-up questions
|
|
305
|
+
|
|
306
|
+
## Frontend Display
|
|
307
|
+
|
|
308
|
+
Tool calls are displayed inline in messages (when `showToolCalls: true`):
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
AI: I'll read that file for you.
|
|
312
|
+
|
|
313
|
+
[Tool: read_file] ▾
|
|
314
|
+
Server: filesystem
|
|
315
|
+
Arguments: { "path": "/tmp/data.json" }
|
|
316
|
+
Result: { "data": "..." }
|
|
317
|
+
|
|
318
|
+
[Interactive Widget] (if uiResource returned)
|
|
319
|
+
|
|
320
|
+
Here's what I found in the file...
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Tool Call States
|
|
324
|
+
|
|
325
|
+
- **Pending**: Tool is being executed (spinner)
|
|
326
|
+
- **Completed**: Tool finished successfully (checkmark)
|
|
327
|
+
- **Error**: Tool failed (error icon)
|
|
328
|
+
|
|
329
|
+
### Hiding Tool Calls
|
|
330
|
+
|
|
331
|
+
Set `showToolCalls: false` in config to hide tool execution cards while still showing UI widgets and responses.
|
|
332
|
+
|
|
333
|
+
## API Endpoints
|
|
334
|
+
|
|
335
|
+
### List Servers
|
|
336
|
+
|
|
337
|
+
```http
|
|
338
|
+
GET /api/mcp/servers
|
|
339
|
+
Authorization: Bearer <token>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### List Tools
|
|
343
|
+
|
|
344
|
+
```http
|
|
345
|
+
GET /api/mcp/tools
|
|
346
|
+
Authorization: Bearer <token>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Credential Status
|
|
350
|
+
|
|
351
|
+
```http
|
|
352
|
+
GET /api/mcp/credentials
|
|
353
|
+
Authorization: Bearer <token>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Set API Key
|
|
357
|
+
|
|
358
|
+
```http
|
|
359
|
+
POST /api/mcp/credentials/:serverId/apikey
|
|
360
|
+
Authorization: Bearer <token>
|
|
361
|
+
Content-Type: application/json
|
|
362
|
+
|
|
363
|
+
{
|
|
364
|
+
"apiKey": "sk-..."
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Start OAuth Flow
|
|
369
|
+
|
|
370
|
+
```http
|
|
371
|
+
GET /api/mcp/oauth/:serverId/authorize
|
|
372
|
+
Authorization: Bearer <token>
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Returns redirect URL for OAuth authorization.
|
|
376
|
+
|
|
377
|
+
### OAuth Callback
|
|
378
|
+
|
|
379
|
+
```http
|
|
380
|
+
GET /api/mcp/oauth/callback?code=...&state=...
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Exchanges code for tokens and stores credentials.
|
|
384
|
+
|
|
385
|
+
### Remove Credentials
|
|
386
|
+
|
|
387
|
+
```http
|
|
388
|
+
DELETE /api/mcp/credentials/:serverId
|
|
389
|
+
Authorization: Bearer <token>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Agentic Loop
|
|
393
|
+
|
|
394
|
+
The chat endpoint implements an agentic loop:
|
|
395
|
+
|
|
396
|
+
1. Send message with available tools to AI
|
|
397
|
+
2. If AI returns `tool_use`, execute the tool
|
|
398
|
+
3. Send tool result (including `structuredContent`) back to AI
|
|
399
|
+
4. Repeat until AI responds without tool calls
|
|
400
|
+
5. Return final response with any UI resources
|
|
401
|
+
|
|
402
|
+
### Maximum Iterations
|
|
403
|
+
|
|
404
|
+
Limited to 10 iterations to prevent infinite loops.
|
|
405
|
+
|
|
406
|
+
## Tool Confirmation
|
|
407
|
+
|
|
408
|
+
The tool confirmation system gives users control over which tools can execute automatically and which require explicit approval.
|
|
409
|
+
|
|
410
|
+
### Confirmation Modes
|
|
411
|
+
|
|
412
|
+
**`none`** - No confirmation required. All tools execute automatically.
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
toolConfirmation: {
|
|
416
|
+
mode: 'none',
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**`all`** - All tools require user confirmation before execution.
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
toolConfirmation: {
|
|
424
|
+
mode: 'all',
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**`whitelist`** - Listed tools skip confirmation; all others require it.
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
toolConfirmation: {
|
|
432
|
+
mode: 'whitelist',
|
|
433
|
+
tools: [
|
|
434
|
+
'weather:get_forecast', // Specific tool
|
|
435
|
+
'calculator:compute', // Safe read-only tools
|
|
436
|
+
],
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
**`blacklist`** - Listed tools require confirmation; all others execute automatically.
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
toolConfirmation: {
|
|
444
|
+
mode: 'blacklist',
|
|
445
|
+
tools: [
|
|
446
|
+
'filesystem:delete_file', // Destructive operations
|
|
447
|
+
'github:create_issue', // Actions with side effects
|
|
448
|
+
'email:send', // External communications
|
|
449
|
+
],
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Tool Patterns
|
|
454
|
+
|
|
455
|
+
Tool patterns can be specified as:
|
|
456
|
+
- `serverId:toolName` - Matches a specific tool on a specific server
|
|
457
|
+
- `toolName` - Matches the tool on any server
|
|
458
|
+
|
|
459
|
+
### User Runtime Options
|
|
460
|
+
|
|
461
|
+
When confirmation is required, users see a modal with these options:
|
|
462
|
+
|
|
463
|
+
1. **Allow once** - Execute the tool this time only
|
|
464
|
+
2. **Allow for this chat** - Auto-approve this tool for the current conversation
|
|
465
|
+
3. **Always allow** - Save to user settings, auto-approve in all future chats
|
|
466
|
+
4. **Deny** - Reject the tool call; AI receives denial message and continues
|
|
467
|
+
|
|
468
|
+
### Auto-Approved Indicators
|
|
469
|
+
|
|
470
|
+
Tools that are auto-approved show a visual indicator explaining why:
|
|
471
|
+
- "Admin config allows all tools" - Mode is `none`
|
|
472
|
+
- "Tool is in allowed list" - Whitelisted tool
|
|
473
|
+
- "You always allowed this tool" - User's saved preference
|
|
474
|
+
- "Allowed for this chat" - Thread-level approval
|
|
475
|
+
|
|
476
|
+
### User Settings
|
|
477
|
+
|
|
478
|
+
Users' "always allow" choices are stored in their settings:
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
{
|
|
482
|
+
allowedTools: [
|
|
483
|
+
'filesystem:read_file',
|
|
484
|
+
'calculator:compute',
|
|
485
|
+
]
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### Confirmation Flow
|
|
490
|
+
|
|
491
|
+
```
|
|
492
|
+
Tool Call Received
|
|
493
|
+
↓
|
|
494
|
+
Check Admin Config
|
|
495
|
+
↓
|
|
496
|
+
┌──────────────────┐
|
|
497
|
+
│ Mode = 'none'? │──Yes──→ Execute (auto-approved)
|
|
498
|
+
└────────┬─────────┘
|
|
499
|
+
No
|
|
500
|
+
↓
|
|
501
|
+
┌──────────────────┐
|
|
502
|
+
│ Whitelisted? │──Yes──→ Execute (auto-approved)
|
|
503
|
+
└────────┬─────────┘
|
|
504
|
+
No
|
|
505
|
+
↓
|
|
506
|
+
┌──────────────────┐
|
|
507
|
+
│ Blacklisted or │──No───→ Execute (auto-approved)
|
|
508
|
+
│ Mode = 'all'? │
|
|
509
|
+
└────────┬─────────┘
|
|
510
|
+
Yes
|
|
511
|
+
↓
|
|
512
|
+
┌──────────────────┐
|
|
513
|
+
│ User 'always'? │──Yes──→ Execute (auto-approved)
|
|
514
|
+
└────────┬─────────┘
|
|
515
|
+
No
|
|
516
|
+
↓
|
|
517
|
+
┌──────────────────┐
|
|
518
|
+
│ Thread allowed? │──Yes──→ Execute (auto-approved)
|
|
519
|
+
└────────┬─────────┘
|
|
520
|
+
No
|
|
521
|
+
↓
|
|
522
|
+
Show Modal
|
|
523
|
+
↓
|
|
524
|
+
User Decision
|
|
525
|
+
↓ ↓
|
|
526
|
+
Allow Deny
|
|
527
|
+
↓ ↓
|
|
528
|
+
Execute Return denial message
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### API Endpoint
|
|
532
|
+
|
|
533
|
+
```http
|
|
534
|
+
POST /api/chat/confirm-tool
|
|
535
|
+
Authorization: Bearer <token>
|
|
536
|
+
Content-Type: application/json
|
|
537
|
+
|
|
538
|
+
{
|
|
539
|
+
"confirmationId": "confirm_1234567890_abc123",
|
|
540
|
+
"approved": true,
|
|
541
|
+
"scope": "always" // "once" | "thread" | "always"
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### SSE Events
|
|
546
|
+
|
|
547
|
+
During streaming, tool confirmation uses these events:
|
|
548
|
+
|
|
549
|
+
- `tool_pending_confirmation` - Tool requires user approval
|
|
550
|
+
- `tool_confirmed` - User responded (approved or denied)
|
|
551
|
+
- `tool_auto_approved` - Tool was auto-approved with reason
|
|
552
|
+
|
|
553
|
+
## Security Considerations
|
|
554
|
+
|
|
555
|
+
1. **Credential Encryption**: All credentials encrypted at rest with AES-256-GCM
|
|
556
|
+
2. **Per-User Isolation**: User credentials never shared between users
|
|
557
|
+
3. **OAuth Security**: PKCE used for all OAuth flows
|
|
558
|
+
4. **Path Restrictions**: File system servers should be scoped to specific directories
|
|
559
|
+
5. **Tool Confirmation**: Use `toolConfirmation` with `mode: 'all'` or `blacklist` for sensitive operations
|
|
560
|
+
6. **Timeout**: Set appropriate `toolTimeout` to prevent hanging
|
|
561
|
+
7. **Confirmation Expiry**: Pending confirmations auto-deny after 5 minutes
|
|
562
|
+
|
|
563
|
+
## Available MCP Servers
|
|
564
|
+
|
|
565
|
+
### Official Servers
|
|
566
|
+
|
|
567
|
+
| Server | Description | Install |
|
|
568
|
+
|--------|-------------|---------|
|
|
569
|
+
| `@modelcontextprotocol/server-filesystem` | File system access | `npx -y @modelcontextprotocol/server-filesystem /path` |
|
|
570
|
+
| `@modelcontextprotocol/server-memory` | Key-value storage | `npx -y @modelcontextprotocol/server-memory` |
|
|
571
|
+
| `@modelcontextprotocol/server-brave-search` | Web search | Requires API key |
|
|
572
|
+
| `@modelcontextprotocol/server-puppeteer` | Browser automation | `npx -y @modelcontextprotocol/server-puppeteer` |
|
|
573
|
+
|
|
574
|
+
### Community Servers
|
|
575
|
+
|
|
576
|
+
Find more at [modelcontextprotocol.io](https://modelcontextprotocol.io)
|
|
577
|
+
|
|
578
|
+
## Creating Custom MCP Servers
|
|
579
|
+
|
|
580
|
+
### Basic Structure
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
import { Server } from '@modelcontextprotocol/sdk/server';
|
|
584
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio';
|
|
585
|
+
|
|
586
|
+
const server = new Server({
|
|
587
|
+
name: 'my-server',
|
|
588
|
+
version: '1.0.0',
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
server.setRequestHandler('tools/list', async () => ({
|
|
592
|
+
tools: [
|
|
593
|
+
{
|
|
594
|
+
name: 'my_tool',
|
|
595
|
+
description: 'Does something',
|
|
596
|
+
inputSchema: {
|
|
597
|
+
type: 'object',
|
|
598
|
+
properties: {
|
|
599
|
+
param: { type: 'string' }
|
|
600
|
+
},
|
|
601
|
+
required: ['param']
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
]
|
|
605
|
+
}));
|
|
606
|
+
|
|
607
|
+
server.setRequestHandler('tools/call', async (request) => {
|
|
608
|
+
const { name, arguments: args } = request.params;
|
|
609
|
+
|
|
610
|
+
// Return with optional structuredContent and uiResource
|
|
611
|
+
return {
|
|
612
|
+
content: [{ type: 'text', text: 'Result' }],
|
|
613
|
+
structuredContent: { data: 'structured data for widgets' },
|
|
614
|
+
};
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
const transport = new StdioServerTransport();
|
|
618
|
+
await server.connect(transport);
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### Returning UI Resources
|
|
622
|
+
|
|
623
|
+
```typescript
|
|
624
|
+
server.setRequestHandler('tools/call', async (request) => {
|
|
625
|
+
return {
|
|
626
|
+
content: [
|
|
627
|
+
{ type: 'text', text: 'Here is the visualization' },
|
|
628
|
+
{
|
|
629
|
+
type: 'resource',
|
|
630
|
+
resource: {
|
|
631
|
+
uri: 'ui://widget',
|
|
632
|
+
mimeType: 'text/html',
|
|
633
|
+
text: '<html>...</html>', // OpenAI Apps SDK compatible HTML
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
],
|
|
637
|
+
structuredContent: {
|
|
638
|
+
chartData: [1, 2, 3, 4, 5],
|
|
639
|
+
labels: ['A', 'B', 'C', 'D', 'E'],
|
|
640
|
+
},
|
|
641
|
+
};
|
|
642
|
+
});
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
## Troubleshooting
|
|
646
|
+
|
|
647
|
+
### Server not connecting
|
|
648
|
+
|
|
649
|
+
1. Check the command/URL is correct
|
|
650
|
+
2. Verify the server is installed/accessible
|
|
651
|
+
3. Look for errors in server logs
|
|
652
|
+
4. For auth servers, ensure credentials are configured
|
|
653
|
+
|
|
654
|
+
### Tools not appearing
|
|
655
|
+
|
|
656
|
+
1. Verify server is connected: `GET /api/mcp/servers`
|
|
657
|
+
2. Check server supports tools
|
|
658
|
+
3. Look for errors during `listTools`
|
|
659
|
+
|
|
660
|
+
### User credentials not working
|
|
661
|
+
|
|
662
|
+
1. Check credential status: `GET /api/mcp/credentials`
|
|
663
|
+
2. For OAuth, try disconnecting and reconnecting
|
|
664
|
+
3. Verify OAuth client ID/secret are correct
|
|
665
|
+
4. Check `MCP_CREDENTIAL_KEY` is set
|
|
666
|
+
|
|
667
|
+
### UI widgets not rendering
|
|
668
|
+
|
|
669
|
+
1. Verify tool returns `uiResource` with `text` and `mimeType`
|
|
670
|
+
2. Check browser console for iframe errors
|
|
671
|
+
3. Ensure HTML is valid and self-contained
|
|
672
|
+
|
|
673
|
+
---
|
|
674
|
+
|
|
675
|
+
## MCP Server Export
|
|
676
|
+
|
|
677
|
+
ChaasKit can act as an MCP server, allowing external MCP clients like Claude Desktop, MCP Inspector, or custom applications to access your app's tools. This enables integration with the broader MCP ecosystem.
|
|
678
|
+
|
|
679
|
+
### Overview
|
|
680
|
+
|
|
681
|
+
When enabled, the MCP server export feature:
|
|
682
|
+
|
|
683
|
+
- Exposes your app's native tools (and optionally MCP tools) via the MCP protocol
|
|
684
|
+
- Supports OAuth 2.1 with PKCE for secure authentication
|
|
685
|
+
- Implements dynamic client registration (RFC 7591)
|
|
686
|
+
- Works with any MCP-compatible client
|
|
687
|
+
|
|
688
|
+
### Configuration
|
|
689
|
+
|
|
690
|
+
Enable MCP server export in `config/app.config.ts`:
|
|
691
|
+
|
|
692
|
+
```typescript
|
|
693
|
+
mcp: {
|
|
694
|
+
// ... existing MCP client config ...
|
|
695
|
+
|
|
696
|
+
// NEW: Expose this app as an MCP server
|
|
697
|
+
server: {
|
|
698
|
+
enabled: true,
|
|
699
|
+
exposeTools: 'native', // 'all', 'native', or ['tool1', 'tool2']
|
|
700
|
+
oauth: {
|
|
701
|
+
enabled: true,
|
|
702
|
+
allowDynamicRegistration: true,
|
|
703
|
+
accessTokenTTLSeconds: 3600, // 1 hour
|
|
704
|
+
refreshTokenTTLSeconds: 2592000, // 30 days
|
|
705
|
+
},
|
|
706
|
+
},
|
|
707
|
+
}
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### Configuration Options
|
|
711
|
+
|
|
712
|
+
| Option | Type | Description |
|
|
713
|
+
|--------|------|-------------|
|
|
714
|
+
| `enabled` | boolean | Enable the MCP server endpoint |
|
|
715
|
+
| `exposeTools` | `'all'` \| `'native'` \| `string[]` | Which tools to expose |
|
|
716
|
+
| `oauth.enabled` | boolean | Enable OAuth authentication |
|
|
717
|
+
| `oauth.allowDynamicRegistration` | boolean | Allow RFC 7591 dynamic client registration |
|
|
718
|
+
| `oauth.accessTokenTTLSeconds` | number | Access token lifetime (default: 3600) |
|
|
719
|
+
| `oauth.refreshTokenTTLSeconds` | number | Refresh token lifetime (default: 2592000) |
|
|
720
|
+
|
|
721
|
+
### Tool Exposure Modes
|
|
722
|
+
|
|
723
|
+
- **`'native'`**: Only expose built-in native tools (web-scrape, get-plan-usage, etc.)
|
|
724
|
+
- **`'all'`**: Expose native tools plus any tools from connected MCP servers
|
|
725
|
+
- **`string[]`**: Explicit list of tool names to expose
|
|
726
|
+
|
|
727
|
+
### Authentication
|
|
728
|
+
|
|
729
|
+
The MCP server supports two authentication methods:
|
|
730
|
+
|
|
731
|
+
#### 1. OAuth 2.1 (Recommended)
|
|
732
|
+
|
|
733
|
+
Full OAuth 2.1 with PKCE support for MCP clients. Compliant with:
|
|
734
|
+
- RFC 8414 (OAuth Authorization Server Metadata)
|
|
735
|
+
- RFC 9728 (OAuth Protected Resource Metadata)
|
|
736
|
+
- RFC 7591 (Dynamic Client Registration)
|
|
737
|
+
|
|
738
|
+
#### 2. API Keys
|
|
739
|
+
|
|
740
|
+
Use existing ChaasKit API keys with the `/mcp/**` endpoint pattern allowed.
|
|
741
|
+
|
|
742
|
+
### Connecting MCP Clients
|
|
743
|
+
|
|
744
|
+
#### Claude Desktop
|
|
745
|
+
|
|
746
|
+
Add to your Claude Desktop config (`~/.claude/claude_desktop_config.json`):
|
|
747
|
+
|
|
748
|
+
```json
|
|
749
|
+
{
|
|
750
|
+
"mcpServers": {
|
|
751
|
+
"my-chat-app": {
|
|
752
|
+
"url": "https://your-app.com/mcp",
|
|
753
|
+
"transport": "streamable-http"
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
When Claude Desktop connects, it will:
|
|
760
|
+
1. Discover OAuth metadata automatically
|
|
761
|
+
2. Prompt you to authorize via the consent page
|
|
762
|
+
3. Store tokens for future sessions
|
|
763
|
+
|
|
764
|
+
#### MCP Inspector
|
|
765
|
+
|
|
766
|
+
1. Open MCP Inspector
|
|
767
|
+
2. Set URL to `http://localhost:3000/mcp`
|
|
768
|
+
3. Select "Streamable HTTP" transport
|
|
769
|
+
4. Click "Authentication" → "Guided OAuth Flow"
|
|
770
|
+
5. Complete the OAuth flow
|
|
771
|
+
6. Click "Connect"
|
|
772
|
+
|
|
773
|
+
#### Custom MCP Clients
|
|
774
|
+
|
|
775
|
+
Use the `@modelcontextprotocol/sdk` to connect:
|
|
776
|
+
|
|
777
|
+
```typescript
|
|
778
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
779
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
780
|
+
|
|
781
|
+
const transport = new StreamableHTTPClientTransport({
|
|
782
|
+
url: 'https://your-app.com/mcp',
|
|
783
|
+
// OAuth token is handled by the transport
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
const client = new Client({
|
|
787
|
+
name: 'my-client',
|
|
788
|
+
version: '1.0.0',
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
await client.connect(transport);
|
|
792
|
+
const tools = await client.listTools();
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
### OAuth Flow Details
|
|
796
|
+
|
|
797
|
+
#### Discovery Endpoints
|
|
798
|
+
|
|
799
|
+
| Endpoint | RFC | Purpose |
|
|
800
|
+
|----------|-----|---------|
|
|
801
|
+
| `/.well-known/oauth-authorization-server` | RFC 8414 | Authorization server metadata |
|
|
802
|
+
| `/.well-known/oauth-protected-resource` | RFC 9728 | Resource server metadata |
|
|
803
|
+
| `/.well-known/oauth-protected-resource/mcp` | RFC 9728 | MCP resource metadata |
|
|
804
|
+
|
|
805
|
+
#### OAuth Endpoints
|
|
806
|
+
|
|
807
|
+
| Endpoint | Method | Description |
|
|
808
|
+
|----------|--------|-------------|
|
|
809
|
+
| `/oauth/register` | POST | Dynamic client registration |
|
|
810
|
+
| `/oauth/authorize` | GET | Authorization endpoint |
|
|
811
|
+
| `/oauth/authorize` | POST | Process consent decision |
|
|
812
|
+
| `/oauth/token` | POST | Token exchange |
|
|
813
|
+
| `/oauth/revoke` | POST | Token revocation |
|
|
814
|
+
|
|
815
|
+
#### Authorization Flow
|
|
816
|
+
|
|
817
|
+
1. **Client Registration**: MCP client registers via `/oauth/register`
|
|
818
|
+
2. **Authorization Request**: Client redirects user to `/oauth/authorize`
|
|
819
|
+
3. **User Consent**: User sees consent page, approves or denies
|
|
820
|
+
4. **Authorization Code**: Server redirects back with code
|
|
821
|
+
5. **Token Exchange**: Client exchanges code for tokens at `/oauth/token`
|
|
822
|
+
6. **API Access**: Client uses access token to call `/mcp`
|
|
823
|
+
|
|
824
|
+
#### Consent Page
|
|
825
|
+
|
|
826
|
+
Users see a consent screen showing:
|
|
827
|
+
- Client name (from registration)
|
|
828
|
+
- Requested scopes (`mcp:tools`, `mcp:resources`)
|
|
829
|
+
- Current user email
|
|
830
|
+
- Approve/Deny buttons
|
|
831
|
+
|
|
832
|
+
### MCP Protocol Endpoints
|
|
833
|
+
|
|
834
|
+
The `/mcp` endpoint accepts JSON-RPC 2.0 requests:
|
|
835
|
+
|
|
836
|
+
#### Initialize
|
|
837
|
+
|
|
838
|
+
```json
|
|
839
|
+
{
|
|
840
|
+
"jsonrpc": "2.0",
|
|
841
|
+
"method": "initialize",
|
|
842
|
+
"params": {
|
|
843
|
+
"protocolVersion": "2024-11-05",
|
|
844
|
+
"capabilities": {},
|
|
845
|
+
"clientInfo": { "name": "my-client", "version": "1.0.0" }
|
|
846
|
+
},
|
|
847
|
+
"id": 1
|
|
848
|
+
}
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
#### List Tools
|
|
852
|
+
|
|
853
|
+
```json
|
|
854
|
+
{
|
|
855
|
+
"jsonrpc": "2.0",
|
|
856
|
+
"method": "tools/list",
|
|
857
|
+
"params": {},
|
|
858
|
+
"id": 2
|
|
859
|
+
}
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
#### Call Tool
|
|
863
|
+
|
|
864
|
+
```json
|
|
865
|
+
{
|
|
866
|
+
"jsonrpc": "2.0",
|
|
867
|
+
"method": "tools/call",
|
|
868
|
+
"params": {
|
|
869
|
+
"name": "web-scrape",
|
|
870
|
+
"arguments": { "url": "https://example.com" }
|
|
871
|
+
},
|
|
872
|
+
"id": 3
|
|
873
|
+
}
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
#### List Resources
|
|
877
|
+
|
|
878
|
+
```json
|
|
879
|
+
{
|
|
880
|
+
"jsonrpc": "2.0",
|
|
881
|
+
"method": "resources/list",
|
|
882
|
+
"params": {},
|
|
883
|
+
"id": 4
|
|
884
|
+
}
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
### Security Considerations
|
|
888
|
+
|
|
889
|
+
1. **OAuth PKCE**: All OAuth flows require PKCE (code_challenge)
|
|
890
|
+
2. **Token Hashing**: Tokens are hashed before storage
|
|
891
|
+
3. **Short-Lived Tokens**: Access tokens expire (default 1 hour)
|
|
892
|
+
4. **Scope Limitation**: Clients can only access approved scopes
|
|
893
|
+
5. **User Context**: Tools execute with the authenticated user's permissions
|
|
894
|
+
6. **Rate Limiting**: Standard rate limits apply to MCP endpoint
|
|
895
|
+
|
|
896
|
+
### Managing Connected Applications
|
|
897
|
+
|
|
898
|
+
Users can view and revoke OAuth app access in Settings:
|
|
899
|
+
|
|
900
|
+
1. Open Settings
|
|
901
|
+
2. Scroll to "Connected Applications"
|
|
902
|
+
3. View authorized MCP clients
|
|
903
|
+
4. Click "Revoke" to disconnect an app
|
|
904
|
+
|
|
905
|
+
### Database Schema
|
|
906
|
+
|
|
907
|
+
The MCP server uses these database tables:
|
|
908
|
+
|
|
909
|
+
- **OAuthClient**: Registered OAuth clients
|
|
910
|
+
- **OAuthAuthorizationCode**: Short-lived authorization codes
|
|
911
|
+
- **OAuthToken**: Access and refresh tokens
|
|
912
|
+
|
|
913
|
+
### Environment Variables
|
|
914
|
+
|
|
915
|
+
```bash
|
|
916
|
+
# Required
|
|
917
|
+
API_URL=https://your-api.com # Server URL for OAuth metadata
|
|
918
|
+
APP_URL=https://your-app.com # Frontend URL for consent page
|
|
919
|
+
|
|
920
|
+
# Optional
|
|
921
|
+
JWT_SECRET=... # Used for signing OAuth tokens
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
### Troubleshooting
|
|
925
|
+
|
|
926
|
+
#### OAuth flow fails at consent page
|
|
927
|
+
|
|
928
|
+
1. Ensure `APP_URL` and `API_URL` are correctly set
|
|
929
|
+
2. Check that the consent page route exists (`/oauth/consent`)
|
|
930
|
+
3. Verify `basePath` is configured correctly if used
|
|
931
|
+
|
|
932
|
+
#### Token exchange returns "invalid_grant"
|
|
933
|
+
|
|
934
|
+
1. Authorization codes expire after 10 minutes
|
|
935
|
+
2. Codes can only be used once
|
|
936
|
+
3. Verify `redirect_uri` matches exactly
|
|
937
|
+
|
|
938
|
+
#### MCP client can't discover OAuth
|
|
939
|
+
|
|
940
|
+
1. Check `/.well-known/oauth-authorization-server` returns metadata
|
|
941
|
+
2. Verify CORS allows the client origin
|
|
942
|
+
3. Ensure OAuth is enabled in config
|
|
943
|
+
|
|
944
|
+
#### Tools not appearing
|
|
945
|
+
|
|
946
|
+
1. Verify `exposeTools` includes desired tools
|
|
947
|
+
2. Check tool names match the `exposeTools` array
|
|
948
|
+
3. Ensure native tools are registered
|
|
949
|
+
|
|
950
|
+
### Custom MCP Resources
|
|
951
|
+
|
|
952
|
+
You can expose custom resources via the MCP server. See [Extensions > MCP Resources](./extensions.md#mcp-resources) for details on creating custom resources
|