@objectstack/plugin-mcp-server 4.0.3 → 4.0.4

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @objectstack/plugin-mcp-server@4.0.3 build /home/runner/work/framework/framework/packages/plugins/plugin-mcp-server
2
+ > @objectstack/plugin-mcp-server@4.0.4 build /home/runner/work/framework/framework/packages/plugins/plugin-mcp-server
3
3
  > tsup --config ../../../tsup.config.ts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -12,11 +12,11 @@
12
12
  CJS Build start
13
13
  ESM dist/index.js 14.66 KB
14
14
  ESM dist/index.js.map 29.53 KB
15
- ESM ⚡️ Build success in 83ms
15
+ ESM ⚡️ Build success in 126ms
16
16
  CJS dist/index.cjs 15.79 KB
17
17
  CJS dist/index.cjs.map 30.18 KB
18
- CJS ⚡️ Build success in 84ms
18
+ CJS ⚡️ Build success in 127ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 15014ms
20
+ DTS ⚡️ Build success in 18206ms
21
21
  DTS dist/index.d.ts 6.28 KB
22
22
  DTS dist/index.d.cts 6.28 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @objectstack/plugin-mcp-server
2
2
 
3
+ ## 4.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [326b66b]
8
+ - @objectstack/spec@4.0.4
9
+ - @objectstack/core@4.0.4
10
+
3
11
  ## 4.0.3
4
12
 
5
13
  ### Patch Changes
package/README.md ADDED
@@ -0,0 +1,528 @@
1
+ # @objectstack/plugin-mcp-server
2
+
3
+ MCP Runtime Server Plugin for ObjectStack — exposes AI tools, data resources, and agent prompts via the Model Context Protocol.
4
+
5
+ ## Features
6
+
7
+ - **Model Context Protocol (MCP)**: Expose ObjectStack resources to AI models via MCP
8
+ - **AI Tools**: Auto-generate MCP tools from ObjectStack actions and flows
9
+ - **Data Resources**: Expose objects, records, and metadata as MCP resources
10
+ - **Agent Prompts**: Register prompt templates for AI agents
11
+ - **Type-Safe**: Full Zod schema validation for tool inputs/outputs
12
+ - **Auto-Discovery**: MCP clients automatically discover available tools and resources
13
+ - **Streaming Support**: Stream large datasets and real-time updates
14
+ - **Security**: Built-in permission checks for tool execution
15
+
16
+ ## What is MCP?
17
+
18
+ Model Context Protocol (MCP) is an open protocol that standardizes how AI applications provide context to Large Language Models (LLMs). It allows AI models to:
19
+
20
+ - **Access Tools**: Execute functions and operations
21
+ - **Read Resources**: Access data and content
22
+ - **Use Prompts**: Leverage pre-defined prompt templates
23
+
24
+ Read more: [MCP Specification](https://modelcontextprotocol.io/)
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pnpm add @objectstack/plugin-mcp-server
30
+ ```
31
+
32
+ ## Basic Usage
33
+
34
+ ```typescript
35
+ import { defineStack } from '@objectstack/spec';
36
+ import { PluginMCPServer } from '@objectstack/plugin-mcp-server';
37
+
38
+ const stack = defineStack({
39
+ plugins: [
40
+ PluginMCPServer.configure({
41
+ serverName: 'objectstack-server',
42
+ version: '1.0.0',
43
+ autoRegisterTools: true,
44
+ }),
45
+ ],
46
+ });
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ ```typescript
52
+ interface MCPServerConfig {
53
+ /** Server name (shown to AI clients) */
54
+ serverName?: string;
55
+
56
+ /** Server version */
57
+ version?: string;
58
+
59
+ /** Auto-register tools from actions and flows */
60
+ autoRegisterTools?: boolean;
61
+
62
+ /** Auto-expose objects as resources */
63
+ autoExposeObjects?: boolean;
64
+
65
+ /** Enable streaming for large responses */
66
+ enableStreaming?: boolean;
67
+
68
+ /** Transport mechanism ('stdio' | 'http') */
69
+ transport?: 'stdio' | 'http';
70
+
71
+ /** HTTP port (if transport is 'http') */
72
+ port?: number;
73
+ }
74
+ ```
75
+
76
+ ## MCP Tools
77
+
78
+ ### Auto-Generated Tools
79
+
80
+ ObjectStack automatically exposes these operations as MCP tools:
81
+
82
+ ```typescript
83
+ // CRUD operations (auto-registered)
84
+ 'objectstack_find' // Query records
85
+ 'objectstack_findOne' // Get single record
86
+ 'objectstack_create' // Create record
87
+ 'objectstack_update' // Update record
88
+ 'objectstack_delete' // Delete record
89
+
90
+ // Metadata operations
91
+ 'objectstack_describeObject' // Get object schema
92
+ 'objectstack_listObjects' // List all objects
93
+ 'objectstack_listFields' // List object fields
94
+ ```
95
+
96
+ ### Custom Tools
97
+
98
+ Register custom tools that AI models can call:
99
+
100
+ ```typescript
101
+ import { defineTool } from '@objectstack/spec';
102
+
103
+ const calculateRevenueTool = defineTool({
104
+ name: 'calculate_revenue',
105
+ description: 'Calculate total revenue for an account',
106
+ inputSchema: {
107
+ type: 'object',
108
+ properties: {
109
+ accountId: { type: 'string', description: 'Account ID' },
110
+ startDate: { type: 'string', description: 'Start date (ISO 8601)' },
111
+ endDate: { type: 'string', description: 'End date (ISO 8601)' },
112
+ },
113
+ required: ['accountId'],
114
+ },
115
+ async execute({ accountId, startDate, endDate }) {
116
+ const opportunities = await kernel.getDriver().find({
117
+ object: 'opportunity',
118
+ filters: [
119
+ { field: 'account_id', operator: 'eq', value: accountId },
120
+ { field: 'stage', operator: 'eq', value: 'closed_won' },
121
+ { field: 'close_date', operator: 'gte', value: startDate },
122
+ { field: 'close_date', operator: 'lte', value: endDate },
123
+ ],
124
+ });
125
+
126
+ const total = opportunities.reduce((sum, opp) => sum + opp.amount, 0);
127
+
128
+ return {
129
+ accountId,
130
+ totalRevenue: total,
131
+ opportunityCount: opportunities.length,
132
+ };
133
+ },
134
+ });
135
+
136
+ // Register with MCP server
137
+ kernel.getService('mcp').registerTool(calculateRevenueTool);
138
+ ```
139
+
140
+ ## MCP Resources
141
+
142
+ ### Auto-Exposed Objects
143
+
144
+ All ObjectStack objects are automatically exposed as MCP resources:
145
+
146
+ ```
147
+ objectstack://objects/opportunity # Opportunity object schema
148
+ objectstack://objects/opportunity/records # All opportunity records
149
+ objectstack://objects/opportunity/123 # Specific opportunity record
150
+ ```
151
+
152
+ ### Custom Resources
153
+
154
+ Expose custom resources to AI models:
155
+
156
+ ```typescript
157
+ kernel.getService('mcp').registerResource({
158
+ uri: 'objectstack://reports/sales-pipeline',
159
+ name: 'Sales Pipeline Report',
160
+ description: 'Current sales pipeline with stages and amounts',
161
+ mimeType: 'application/json',
162
+ async read() {
163
+ const opportunities = await kernel.getDriver().find({
164
+ object: 'opportunity',
165
+ filters: [
166
+ { field: 'stage', operator: 'neq', value: 'closed_won' },
167
+ { field: 'stage', operator: 'neq', value: 'closed_lost' },
168
+ ],
169
+ });
170
+
171
+ const pipeline = opportunities.reduce((acc, opp) => {
172
+ acc[opp.stage] = (acc[opp.stage] || 0) + opp.amount;
173
+ return acc;
174
+ }, {});
175
+
176
+ return {
177
+ content: [
178
+ {
179
+ type: 'text',
180
+ text: JSON.stringify(pipeline, null, 2),
181
+ },
182
+ ],
183
+ };
184
+ },
185
+ });
186
+ ```
187
+
188
+ ## MCP Prompts
189
+
190
+ Register prompt templates that AI models can use:
191
+
192
+ ```typescript
193
+ kernel.getService('mcp').registerPrompt({
194
+ name: 'analyze_account',
195
+ description: 'Analyze an account and its opportunities',
196
+ arguments: [
197
+ {
198
+ name: 'accountId',
199
+ description: 'Account ID to analyze',
200
+ required: true,
201
+ },
202
+ ],
203
+ async render({ accountId }) {
204
+ const account = await kernel.getDriver().findOne({
205
+ object: 'account',
206
+ filters: [{ field: 'id', operator: 'eq', value: accountId }],
207
+ });
208
+
209
+ const opportunities = await kernel.getDriver().find({
210
+ object: 'opportunity',
211
+ filters: [{ field: 'account_id', operator: 'eq', value: accountId }],
212
+ });
213
+
214
+ return {
215
+ messages: [
216
+ {
217
+ role: 'user',
218
+ content: {
219
+ type: 'text',
220
+ text: `Analyze this account and provide insights:
221
+
222
+ Account: ${account.name}
223
+ Industry: ${account.industry}
224
+ Total Opportunities: ${opportunities.length}
225
+ Total Value: $${opportunities.reduce((sum, o) => sum + o.amount, 0)}
226
+
227
+ Opportunities:
228
+ ${opportunities.map(o => `- ${o.name} (${o.stage}): $${o.amount}`).join('\n')}
229
+
230
+ Please provide:
231
+ 1. Key insights about this account
232
+ 2. Risk assessment
233
+ 3. Recommendations for next steps`,
234
+ },
235
+ },
236
+ ],
237
+ };
238
+ },
239
+ });
240
+ ```
241
+
242
+ ## Using with AI Clients
243
+
244
+ ### Claude Desktop
245
+
246
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
247
+
248
+ ```json
249
+ {
250
+ "mcpServers": {
251
+ "objectstack": {
252
+ "command": "node",
253
+ "args": ["/path/to/your/objectstack/server.js"],
254
+ "env": {
255
+ "DATABASE_URL": "your-database-url"
256
+ }
257
+ }
258
+ }
259
+ }
260
+ ```
261
+
262
+ ### Cursor IDE
263
+
264
+ Add to `.cursor/mcp.json`:
265
+
266
+ ```json
267
+ {
268
+ "mcpServers": {
269
+ "objectstack": {
270
+ "command": "node",
271
+ "args": ["./server.js"]
272
+ }
273
+ }
274
+ }
275
+ ```
276
+
277
+ ### Cline VS Code Extension
278
+
279
+ Configure in Cline settings:
280
+
281
+ ```json
282
+ {
283
+ "cline.mcpServers": {
284
+ "objectstack": {
285
+ "command": "node",
286
+ "args": ["./server.js"]
287
+ }
288
+ }
289
+ }
290
+ ```
291
+
292
+ ## Server Implementation
293
+
294
+ ### Stdio Transport (Default)
295
+
296
+ ```typescript
297
+ // server.ts
298
+ import { defineStack } from '@objectstack/spec';
299
+ import { PluginMCPServer } from '@objectstack/plugin-mcp-server';
300
+ import { DriverTurso } from '@objectstack/driver-turso';
301
+
302
+ const stack = defineStack({
303
+ driver: DriverTurso.configure({
304
+ url: process.env.DATABASE_URL!,
305
+ authToken: process.env.TURSO_AUTH_TOKEN!,
306
+ }),
307
+ plugins: [
308
+ PluginMCPServer.configure({
309
+ serverName: 'my-crm',
310
+ transport: 'stdio', // Claude Desktop, Cursor, Cline
311
+ }),
312
+ ],
313
+ });
314
+
315
+ await stack.boot();
316
+ ```
317
+
318
+ ### HTTP Transport
319
+
320
+ ```typescript
321
+ const stack = defineStack({
322
+ driver: DriverTurso.configure({ /* ... */ }),
323
+ plugins: [
324
+ PluginMCPServer.configure({
325
+ serverName: 'my-crm',
326
+ transport: 'http',
327
+ port: 3100,
328
+ }),
329
+ ],
330
+ });
331
+
332
+ await stack.boot();
333
+ // MCP server running on http://localhost:3100
334
+ ```
335
+
336
+ ## Advanced Features
337
+
338
+ ### Streaming Resources
339
+
340
+ ```typescript
341
+ kernel.getService('mcp').registerResource({
342
+ uri: 'objectstack://exports/opportunities-csv',
343
+ name: 'Opportunities Export (CSV)',
344
+ mimeType: 'text/csv',
345
+ async *stream() {
346
+ // Stream header
347
+ yield 'Name,Stage,Amount,Close Date\n';
348
+
349
+ // Stream records in batches
350
+ let offset = 0;
351
+ const batchSize = 100;
352
+
353
+ while (true) {
354
+ const batch = await kernel.getDriver().find({
355
+ object: 'opportunity',
356
+ limit: batchSize,
357
+ offset,
358
+ });
359
+
360
+ if (batch.length === 0) break;
361
+
362
+ for (const opp of batch) {
363
+ yield `${opp.name},${opp.stage},${opp.amount},${opp.close_date}\n`;
364
+ }
365
+
366
+ offset += batchSize;
367
+ }
368
+ },
369
+ });
370
+ ```
371
+
372
+ ### Tool Permissions
373
+
374
+ ```typescript
375
+ kernel.getService('mcp').registerTool({
376
+ name: 'delete_opportunity',
377
+ description: 'Delete an opportunity',
378
+ permissions: ['opportunity:delete'], // Require permission
379
+ inputSchema: {
380
+ type: 'object',
381
+ properties: {
382
+ id: { type: 'string' },
383
+ },
384
+ required: ['id'],
385
+ },
386
+ async execute({ id }, context) {
387
+ // context includes userId, permissions, etc.
388
+ if (!context.hasPermission('opportunity:delete')) {
389
+ throw new Error('Permission denied');
390
+ }
391
+
392
+ await kernel.getDriver().delete({
393
+ object: 'opportunity',
394
+ filters: [{ field: 'id', operator: 'eq', value: id }],
395
+ });
396
+
397
+ return { success: true, deleted: id };
398
+ },
399
+ });
400
+ ```
401
+
402
+ ### Dynamic Tool Registration
403
+
404
+ ```typescript
405
+ // Register tools from flow definitions
406
+ const flows = await kernel.getMetadata('flow');
407
+
408
+ for (const flow of flows) {
409
+ kernel.getService('mcp').registerTool({
410
+ name: `flow_${flow.name}`,
411
+ description: flow.description,
412
+ inputSchema: generateSchemaFromFlow(flow),
413
+ async execute(inputs) {
414
+ return await kernel.executeFlow(flow.name, inputs);
415
+ },
416
+ });
417
+ }
418
+ ```
419
+
420
+ ## Server Capabilities
421
+
422
+ The MCP server exposes these capabilities:
423
+
424
+ ```json
425
+ {
426
+ "capabilities": {
427
+ "tools": {
428
+ "listChanged": true
429
+ },
430
+ "resources": {
431
+ "subscribe": true,
432
+ "listChanged": true
433
+ },
434
+ "prompts": {
435
+ "listChanged": true
436
+ },
437
+ "logging": {},
438
+ "experimental": {
439
+ "streaming": true
440
+ }
441
+ }
442
+ }
443
+ ```
444
+
445
+ ## Best Practices
446
+
447
+ 1. **Tool Design**: Keep tools focused and well-documented
448
+ 2. **Resource Naming**: Use clear, hierarchical URI schemes
449
+ 3. **Prompt Templates**: Make prompts flexible with arguments
450
+ 4. **Error Handling**: Always return helpful error messages
451
+ 5. **Permissions**: Check permissions before tool execution
452
+ 6. **Performance**: Use streaming for large datasets
453
+ 7. **Versioning**: Version your server and tools
454
+
455
+ ## Debugging
456
+
457
+ Enable debug logging:
458
+
459
+ ```typescript
460
+ PluginMCPServer.configure({
461
+ serverName: 'my-crm',
462
+ debug: true, // Log all MCP messages
463
+ });
464
+ ```
465
+
466
+ View MCP messages in client:
467
+ - **Claude Desktop**: Check logs in `~/Library/Logs/Claude/mcp*.log`
468
+ - **Cursor**: Check Output panel → MCP Server
469
+ - **Cline**: Check extension logs
470
+
471
+ ## Example: Complete CRM Server
472
+
473
+ ```typescript
474
+ import { defineStack, defineTool } from '@objectstack/spec';
475
+ import { PluginMCPServer } from '@objectstack/plugin-mcp-server';
476
+
477
+ const stack = defineStack({
478
+ driver: /* ... */,
479
+ plugins: [
480
+ PluginMCPServer.configure({
481
+ serverName: 'crm-assistant',
482
+ autoRegisterTools: true,
483
+ }),
484
+ ],
485
+ });
486
+
487
+ await stack.boot();
488
+
489
+ const mcp = stack.kernel.getService('mcp');
490
+
491
+ // Register custom tools
492
+ mcp.registerTool(defineTool({
493
+ name: 'forecast_revenue',
494
+ description: 'Forecast revenue based on pipeline',
495
+ async execute() {
496
+ // Implementation
497
+ },
498
+ }));
499
+
500
+ // Register custom resources
501
+ mcp.registerResource({
502
+ uri: 'objectstack://dashboards/sales',
503
+ name: 'Sales Dashboard',
504
+ async read() {
505
+ // Implementation
506
+ },
507
+ });
508
+
509
+ // Register prompts
510
+ mcp.registerPrompt({
511
+ name: 'weekly_report',
512
+ description: 'Generate weekly sales report',
513
+ async render() {
514
+ // Implementation
515
+ },
516
+ });
517
+ ```
518
+
519
+ ## License
520
+
521
+ Apache-2.0
522
+
523
+ ## See Also
524
+
525
+ - [Model Context Protocol Specification](https://modelcontextprotocol.io/)
526
+ - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
527
+ - [@objectstack/spec/ai](../../spec/src/ai/)
528
+ - [Building MCP Servers Guide](/content/docs/guides/mcp/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectstack/plugin-mcp-server",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "license": "Apache-2.0",
5
5
  "description": "MCP Runtime Server Plugin for ObjectStack — exposes AI tools, data resources, and agent prompts via the Model Context Protocol",
6
6
  "type": "module",
@@ -16,8 +16,8 @@
16
16
  "dependencies": {
17
17
  "@modelcontextprotocol/sdk": "^1.29.0",
18
18
  "zod": "^4.3.6",
19
- "@objectstack/core": "4.0.3",
20
- "@objectstack/spec": "4.0.3"
19
+ "@objectstack/core": "4.0.4",
20
+ "@objectstack/spec": "4.0.4"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^25.6.0",