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.
Files changed (122) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +25 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/add-infra.d.ts +6 -0
  6. package/dist/commands/add-infra.d.ts.map +1 -0
  7. package/dist/commands/add-infra.js +160 -0
  8. package/dist/commands/add-infra.js.map +1 -0
  9. package/dist/commands/build.d.ts +2 -0
  10. package/dist/commands/build.d.ts.map +1 -0
  11. package/dist/commands/build.js +63 -0
  12. package/dist/commands/build.js.map +1 -0
  13. package/dist/commands/db-sync.d.ts +13 -0
  14. package/dist/commands/db-sync.d.ts.map +1 -0
  15. package/dist/commands/db-sync.js +108 -0
  16. package/dist/commands/db-sync.js.map +1 -0
  17. package/dist/commands/dev.d.ts +7 -0
  18. package/dist/commands/dev.d.ts.map +1 -0
  19. package/dist/commands/dev.js +61 -0
  20. package/dist/commands/dev.js.map +1 -0
  21. package/dist/commands/init.d.ts +9 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +214 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +57 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/templates/.env.example +24 -0
  30. package/dist/templates/README.md +81 -0
  31. package/dist/templates/app/components/AcceptInviteClient.tsx +10 -0
  32. package/dist/templates/app/components/AdminDashboardClient.tsx +10 -0
  33. package/dist/templates/app/components/AdminTeamClient.tsx +10 -0
  34. package/dist/templates/app/components/AdminTeamsClient.tsx +10 -0
  35. package/dist/templates/app/components/AdminUsersClient.tsx +10 -0
  36. package/dist/templates/app/components/ApiKeysClient.tsx +10 -0
  37. package/dist/templates/app/components/AutomationsClient.tsx +10 -0
  38. package/dist/templates/app/components/ChatClient.tsx +13 -0
  39. package/dist/templates/app/components/ClientOnly.tsx +6 -0
  40. package/dist/templates/app/components/DocumentsClient.tsx +10 -0
  41. package/dist/templates/app/components/OAuthConsentClient.tsx +10 -0
  42. package/dist/templates/app/components/PricingClient.tsx +10 -0
  43. package/dist/templates/app/components/TeamSettingsClient.tsx +10 -0
  44. package/dist/templates/app/components/VerifyEmailClient.tsx +10 -0
  45. package/dist/templates/app/entry.client.tsx +12 -0
  46. package/dist/templates/app/entry.server.tsx +67 -0
  47. package/dist/templates/app/root.tsx +91 -0
  48. package/dist/templates/app/routes/_index.tsx +82 -0
  49. package/dist/templates/app/routes/admin._index.tsx +57 -0
  50. package/dist/templates/app/routes/admin.teams.$teamId.tsx +57 -0
  51. package/dist/templates/app/routes/admin.teams._index.tsx +57 -0
  52. package/dist/templates/app/routes/admin.users.tsx +57 -0
  53. package/dist/templates/app/routes/api-keys.tsx +57 -0
  54. package/dist/templates/app/routes/automations.tsx +57 -0
  55. package/dist/templates/app/routes/chat._index.tsx +11 -0
  56. package/dist/templates/app/routes/chat.admin._index.tsx +10 -0
  57. package/dist/templates/app/routes/chat.admin.teams.$teamId.tsx +10 -0
  58. package/dist/templates/app/routes/chat.admin.teams._index.tsx +10 -0
  59. package/dist/templates/app/routes/chat.admin.users.tsx +10 -0
  60. package/dist/templates/app/routes/chat.api-keys.tsx +10 -0
  61. package/dist/templates/app/routes/chat.automations.tsx +10 -0
  62. package/dist/templates/app/routes/chat.documents.tsx +10 -0
  63. package/dist/templates/app/routes/chat.team.$teamId.settings.tsx +10 -0
  64. package/dist/templates/app/routes/chat.thread.$threadId.tsx +11 -0
  65. package/dist/templates/app/routes/chat.tsx +39 -0
  66. package/dist/templates/app/routes/documents.tsx +57 -0
  67. package/dist/templates/app/routes/invite.$token.tsx +10 -0
  68. package/dist/templates/app/routes/login.tsx +334 -0
  69. package/dist/templates/app/routes/oauth.consent.tsx +10 -0
  70. package/dist/templates/app/routes/pricing.tsx +10 -0
  71. package/dist/templates/app/routes/privacy.tsx +197 -0
  72. package/dist/templates/app/routes/register.tsx +398 -0
  73. package/dist/templates/app/routes/shared.$shareId.tsx +226 -0
  74. package/dist/templates/app/routes/team.$teamId.settings.tsx +57 -0
  75. package/dist/templates/app/routes/terms.tsx +173 -0
  76. package/dist/templates/app/routes/thread.$threadId.tsx +102 -0
  77. package/dist/templates/app/routes/verify-email.tsx +10 -0
  78. package/dist/templates/app/routes.ts +47 -0
  79. package/dist/templates/config/app.config.ts +216 -0
  80. package/dist/templates/docs/admin.md +257 -0
  81. package/dist/templates/docs/api-keys.md +403 -0
  82. package/dist/templates/docs/authentication.md +247 -0
  83. package/dist/templates/docs/configuration.md +1212 -0
  84. package/dist/templates/docs/custom-pages.md +466 -0
  85. package/dist/templates/docs/deployment.md +362 -0
  86. package/dist/templates/docs/development.md +411 -0
  87. package/dist/templates/docs/documents.md +293 -0
  88. package/dist/templates/docs/extensions.md +639 -0
  89. package/dist/templates/docs/index.md +139 -0
  90. package/dist/templates/docs/installation.md +286 -0
  91. package/dist/templates/docs/mcp.md +952 -0
  92. package/dist/templates/docs/native-tools.md +688 -0
  93. package/dist/templates/docs/queue.md +514 -0
  94. package/dist/templates/docs/scheduled-prompts.md +279 -0
  95. package/dist/templates/docs/settings.md +415 -0
  96. package/dist/templates/docs/slack.md +318 -0
  97. package/dist/templates/docs/styling.md +288 -0
  98. package/dist/templates/extensions/agents/.gitkeep +0 -0
  99. package/dist/templates/extensions/pages/.gitkeep +0 -0
  100. package/dist/templates/extensions/payment-plans/.gitkeep +0 -0
  101. package/dist/templates/index.html +16 -0
  102. package/dist/templates/infra-aws/.github/workflows/deploy.yml +95 -0
  103. package/dist/templates/infra-aws/README.md +207 -0
  104. package/dist/templates/infra-aws/bin/cdk.ts +18 -0
  105. package/dist/templates/infra-aws/cdk.json +43 -0
  106. package/dist/templates/infra-aws/config/deployment.ts +156 -0
  107. package/dist/templates/infra-aws/lib/chaaskit-stack.ts +419 -0
  108. package/dist/templates/infra-aws/package.json +27 -0
  109. package/dist/templates/infra-aws/scripts/build-app.sh +63 -0
  110. package/dist/templates/infra-aws/tsconfig.json +25 -0
  111. package/dist/templates/package.json +46 -0
  112. package/dist/templates/prisma/schema/base.prisma +584 -0
  113. package/dist/templates/prisma/schema/custom.prisma +24 -0
  114. package/dist/templates/prisma/schema.prisma +271 -0
  115. package/dist/templates/public/favicon.svg +4 -0
  116. package/dist/templates/public/logo.svg +4 -0
  117. package/dist/templates/react-router.config.ts +11 -0
  118. package/dist/templates/server.js +52 -0
  119. package/dist/templates/src/main.tsx +8 -0
  120. package/dist/templates/tsconfig.json +26 -0
  121. package/dist/templates/vite.config.ts +26 -0
  122. 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