@instantdb/mcp 0.22.171 → 0.22.172

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/index.js CHANGED
@@ -15,9 +15,11 @@ import { pino } from 'pino';
15
15
  import { init } from '@instantdb/admin';
16
16
  import schema from "./db/instant.schema.js";
17
17
  import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';
18
- import { addOAuthRoutes, ServiceProvider, tokensOfBearerToken, } from "./oauth-service-provider.js";
18
+ import { addOAuthRoutes, makeApiAuth, ServiceProvider, tokensOfBearerToken, } from "./oauth-service-provider.js";
19
+ import { PlatformApi } from '@instantdb/platform';
19
20
  import indexHtml from "./index.html.js";
20
21
  import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
22
+ import { handleQuery, handleTransact } from "./tools.js";
21
23
  // Helpers
22
24
  // -----------
23
25
  function createMCPServer() {
@@ -60,7 +62,7 @@ function wrapServerWithTracing(server, tracer, attrs) {
60
62
  };
61
63
  return server;
62
64
  }
63
- function registerTools(server) {
65
+ function registerTools(server, api) {
64
66
  server.tool('learn', "If you don't have any context provided about InstantDB, use this tool to learn about it!", {}, async () => {
65
67
  const instructions = `
66
68
  You can learn about InstantDB by fetching our rules file for agents:
@@ -78,19 +80,15 @@ function registerTools(server) {
78
80
  });
79
81
  server.tool('get-schema', 'Fetch schema for an app by its ID!', {
80
82
  appId: z.string().uuid().describe('UUID of the app'),
81
- adminToken: z
82
- .string()
83
- .uuid()
84
- .describe('UUID of the admin token for the app'),
85
- }, async ({ appId, adminToken }) => {
83
+ }, async ({ appId }) => {
86
84
  const instructions = `
87
85
  You can fetch the schema for the app by using the instant-cli tool:
88
86
 
89
87
  \`\`\`
90
- npx instant-cli pull schema --app ${appId} --token ${adminToken} --yes
88
+ npx instant-cli pull schema --app ${appId} --yes
91
89
  \`\`\`
92
90
 
93
- We supply the --yes flag to skip confirmation prompts. Now 'instant.schema.ts' with contain the schema for the app.
91
+ We supply the --yes flag to skip confirmation prompts. Now 'instant.schema.ts' will contain the schema for the app.
94
92
  `;
95
93
  return {
96
94
  content: [
@@ -103,16 +101,12 @@ function registerTools(server) {
103
101
  });
104
102
  server.tool('get-perms', 'Fetch permissions for an app by its ID', {
105
103
  appId: z.string().uuid().describe('UUID of the app'),
106
- adminToken: z
107
- .string()
108
- .uuid()
109
- .describe('UUID of the admin token for the app'),
110
- }, async ({ appId, adminToken }) => {
104
+ }, async ({ appId }) => {
111
105
  const instructions = `
112
106
  You fetch the permissions for the app by using the instant-cli tool:
113
107
 
114
108
  \`\`\`
115
- npx instant-cli pull perms --app ${appId} --token ${adminToken} --yes
109
+ npx instant-cli pull perms --app ${appId} --yes
116
110
  \`\`\`
117
111
 
118
112
  We supply the --yes flag to skip confirmation prompts. Now 'instant.perms.ts' will contain the permissions for the app.
@@ -129,17 +123,12 @@ function registerTools(server) {
129
123
  server.tool('push-schema', `Push local schema changes for an app to the server. Do this after updating your local 'instant.schema.ts' file.
130
124
  If you don't have an instant.schema.ts file yet, use the get-schema tool to learn how to get this file.`, {
131
125
  appId: z.string().uuid().describe('UUID of the app'),
132
- adminToken: z
133
- .string()
134
- .uuid()
135
- .describe('UUID of the admin token for the app'),
136
- }, async ({ appId, adminToken }) => {
126
+ }, async ({ appId }) => {
137
127
  const instructions = `
138
128
  Push schema changes by using the instant-cli tool:
139
129
 
140
-
141
130
  \`\`\`
142
- npx instant-cli push schema --app ${appId} --token ${adminToken} --yes
131
+ npx instant-cli push schema --app ${appId} --yes
143
132
  \`\`\`
144
133
 
145
134
  We supply the --yes flag to skip confirmation prompts.
@@ -148,7 +137,7 @@ function registerTools(server) {
148
137
  If you want to rename fields as part of your schema changes you can use the --rename flag to specify renames.
149
138
 
150
139
  \`\`\`
151
- npx instant-cli push schema --app ${appId} --token ${adminToken} --rename 'posts.author:posts.creator stores.owner:stores.manager' --yes
140
+ npx instant-cli push schema --app ${appId} --rename 'posts.author:posts.creator stores.owner:stores.manager' --yes
152
141
  \`\`\`
153
142
  `;
154
143
  return {
@@ -163,16 +152,12 @@ function registerTools(server) {
163
152
  server.tool('push-perms', `Push local permissions changes for an app to the server. Do this after updating your local instant.perms.ts file.
164
153
  If you don't have an instant.perms.ts file yet, use the get-perms tool to learn how to get this file.`, {
165
154
  appId: z.string().uuid().describe('UUID of the app'),
166
- adminToken: z
167
- .string()
168
- .uuid()
169
- .describe('UUID of the admin token for the app'),
170
- }, async ({ appId, adminToken }) => {
155
+ }, async ({ appId }) => {
171
156
  const instructions = `
172
157
  Push permission changes by using the instant-cli tool:
173
158
 
174
159
  \`\`\`
175
- npx instant-cli push schema --app ${appId} --token ${adminToken} --yes
160
+ npx instant-cli push perms --app ${appId} --yes
176
161
  \`\`\`
177
162
 
178
163
  We supply the --yes flag to skip confirmation prompts.
@@ -186,142 +171,38 @@ function registerTools(server) {
186
171
  ],
187
172
  };
188
173
  });
189
- server.tool('query', 'Execute a query againt an app. Useful for inspecting data in the app.', {}, async () => {
190
- const instructions = `
191
- You can query data for an app by writing and executing a script using the
192
- Admin SDK. Here's an example script for fetching a habit and its completions:
193
-
194
- \`\`\`typescript
195
- import { init } from "@instantdb/admin";
196
- import "dotenv/config";
197
-
198
- const adminDb = init({
199
- appId: process.env.NEXT_PUBLIC_INSTANT_APP_ID!,
200
- adminToken: process.env.INSTANT_APP_ADMIN_TOKEN!,
201
- });
202
-
203
- async function fetchHabit(habitName: string) {
204
- const { habits } = await adminDb.query({
205
- habits: {
206
- $: { where: { name: habitName } },
207
- completions: {},
208
- },
209
- });
210
- console.log(habits);
211
- }
174
+ server.tool('query', `Execute an InstaQL query against an app. Returns the query results as JSON.
212
175
 
213
- fetchHabit("Read");
214
- \`\`\`
176
+ Example query to fetch all goals and their todos:
177
+ {"goals": {"todos": {}}}
215
178
 
216
- If you're unsure how to write queries, refer to the documentation:
179
+ Example query with a where clause:
180
+ {"goals": {"$": {"where": {"status": "active"}}, "todos": {}}}
217
181
 
218
- https://instantdb.com/docs/instaql.md
219
- `;
220
- return {
221
- content: [
222
- {
223
- type: 'text',
224
- text: instructions,
225
- },
226
- ],
227
- };
182
+ If you're unsure how to write queries, refer to the documentation:
183
+ https://instantdb.com/docs/instaql`, {
184
+ appId: z.string().uuid().describe('UUID of the app'),
185
+ query: z.record(z.string(), z.any()).describe('InstaQL query object'),
186
+ }, async ({ appId, query }) => {
187
+ return handleQuery(api, appId, query);
228
188
  });
229
- server.tool('transact', 'Execute a transaction against an app. Useful for seeding or modifying data in the app.', {}, async () => {
230
- const instructions = `
231
- You can transact data for an app by writing and executing a script using the
232
- Admin SDK. Here's an example script for seeding a microblog app with some posts:
233
-
234
- \`\`\`typescript
235
- import { init, id } from "@instantdb/admin";
236
- import "dotenv/config";
237
-
238
- const adminDb = init({
239
- appId: process.env.NEXT_PUBLIC_INSTANT_APP_ID!,
240
- adminToken: process.env.INSTANT_APP_ADMIN_TOKEN!,
241
- });
189
+ server.tool('transact', `Execute a transaction against an app. Useful for creating, updating, or deleting data.
242
190
 
243
- interface Post {
244
- id: number;
245
- author: string;
246
- handle: string;
247
- color: string;
248
- content: string;
249
- timestamp: string;
250
- likes: number;
251
- liked: boolean;
252
- }
191
+ Steps use the internal transaction format:
192
+ - Create/update: ["update", "namespace", "entity-id", {"attr": "value"}]
193
+ - Link: ["link", "namespace", "entity-id", {"linkAttr": "target-id"}]
194
+ - Unlink: ["unlink", "namespace", "entity-id", {"linkAttr": "target-id"}]
195
+ - Delete: ["delete", "namespace", "entity-id"]
253
196
 
254
- const mockPosts: Post[] = [
255
- {
256
- author: 'Sarah Chen',
257
- handle: 'sarahchen',
258
- color: 'bg-blue-100',
259
- content: 'Just launched my new project! Really excited to share it with everyone.',
260
- timestamp: '2h ago',
261
- likes: 12,
262
- liked: false,
263
- },
264
- {
265
- author: 'Alex Rivera',
266
- handle: 'alexrivera',
267
- color: 'bg-purple-100',
268
- content: 'Beautiful sunset today. Nature never stops amazing me.',
269
- timestamp: '4h ago',
270
- likes: 19,
271
- liked: true,
272
- },
273
- {
274
- author: 'Jordan Lee',
275
- handle: 'jordanlee',
276
- color: 'bg-pink-100',
277
- content: 'Working on something cool with Next.js and TypeScript. Updates coming soon!',
278
- timestamp: '6h ago',
279
- likes: 7,
280
- liked: false,
281
- },
282
- ];
283
-
284
- function friendlyTimeToTimestamp(friendlyTime: string) {
285
- const hours = parseInt(friendlyTime);
286
- const now = Date.now();
287
- return now - (hours * 60 * 60 * 1000);
288
- }
289
-
290
- function seed() {
291
- console.log("Seeding db...");
292
- mockPosts.forEach(post => {
293
- const userId = id();
294
- const postId = id();
295
- const user = adminDb.tx.$users[userId].create({});
296
- const profile = adminDb.tx.profiles[userId].create({
297
- displayName: post.author,
298
- handle: post.handle,
299
- }).link({ user: userId });
300
- const postEntity = adminDb.tx.posts[postId].create({
301
- color: post.color,
302
- content: post.content,
303
- timestamp: friendlyTimeToTimestamp(post.timestamp),
304
- }).link({ author: userId });
305
- const likes = Array.from({ length: post.likes }, () => adminDb.tx.likes[id()].create({ postId, userId }).link({ post: postId, user: userId }));
306
- adminDb.transact([user, profile, postEntity, ...likes]);
307
- })
308
- }
197
+ Example steps to create a todo:
198
+ [["update", "todos", "a-uuid", {"title": "Get fit", "done": false}]]
309
199
 
310
- seed();
311
- \`\`\`
312
-
313
- If you're unsure how to make transactions, refer to the documentation:
314
-
315
- https://instantdb.com/docs/instaml.md
316
- `;
317
- return {
318
- content: [
319
- {
320
- type: 'text',
321
- text: instructions,
322
- },
323
- ],
324
- };
200
+ If you're unsure how to make transactions, refer to the documentation:
201
+ https://instantdb.com/docs/instaml`, {
202
+ appId: z.string().uuid().describe('UUID of the app'),
203
+ steps: z.array(z.array(z.any())).describe('Array of transaction steps'),
204
+ }, async ({ appId, steps }) => {
205
+ return handleTransact(api, appId, steps);
325
206
  });
326
207
  }
327
208
  async function startStdio() {
@@ -340,8 +221,9 @@ async function startStdio() {
340
221
  console.error('Provide an access token using --token or set INSTANT_ACCESS_TOKEN environment variable');
341
222
  process.exit(1);
342
223
  }
224
+ const api = new PlatformApi({ auth: { token: accessToken } });
343
225
  const server = createMCPServer();
344
- registerTools(server);
226
+ registerTools(server, api);
345
227
  const transport = new StdioServerTransport();
346
228
  await server.connect(transport);
347
229
  console.error('Instant Platform MCP Server running on stdio');
@@ -443,6 +325,9 @@ async function startSse() {
443
325
  const server = createMCPServer();
444
326
  try {
445
327
  const tokens = await tokensOfBearerToken(db, req.auth.token);
328
+ const api = new PlatformApi({
329
+ auth: makeApiAuth(oauthConfig, keyConfig, db, tokens.instantToken),
330
+ });
446
331
  wrapServerWithTracing(server, tracer, {
447
332
  'client.client_id': tokens.mcpToken.client?.client_id,
448
333
  'client.name': tokens.mcpToken.client?.client_name,
@@ -451,7 +336,7 @@ async function startSse() {
451
336
  'client.uri': tokens.mcpToken.client?.client_uri,
452
337
  'client.redirect_urls': tokens.mcpToken.client?.redirect_uris,
453
338
  });
454
- registerTools(server);
339
+ registerTools(server, api);
455
340
  const transport = new StreamableHTTPServerTransport({
456
341
  sessionIdGenerator: undefined,
457
342
  });
@@ -501,6 +386,9 @@ async function startSse() {
501
386
  });
502
387
  try {
503
388
  const tokens = await tokensOfBearerToken(db, req.auth.token);
389
+ const api = new PlatformApi({
390
+ auth: makeApiAuth(oauthConfig, keyConfig, db, tokens.instantToken),
391
+ });
504
392
  wrapServerWithTracing(server, tracer, {
505
393
  'client.client_id': tokens.mcpToken.client?.client_id,
506
394
  'client.name': tokens.mcpToken.client?.client_name,
@@ -509,7 +397,7 @@ async function startSse() {
509
397
  'client.uri': tokens.mcpToken.client?.client_uri,
510
398
  'client.redirect_urls': tokens.mcpToken.client?.redirect_uris,
511
399
  });
512
- registerTools(server);
400
+ registerTools(server, api);
513
401
  transports.sse[transport.sessionId] = transport;
514
402
  }
515
403
  catch (e) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport 'dotenv/config';\nimport express, { Request, Response } from 'express';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { parseArgs } from 'node:util';\nimport version from './version.ts';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { HoneycombSDK } from '@honeycombio/opentelemetry-node';\nimport {\n trace,\n SpanKind,\n SpanStatusCode,\n Tracer,\n Attributes,\n} from '@opentelemetry/api';\n\nimport {\n createOAuthMetadata,\n mcpAuthRouter,\n} from '@modelcontextprotocol/sdk/server/auth/router.js';\nimport { pinoHttp } from 'pino-http';\nimport { pino } from 'pino';\nimport { init } from '@instantdb/admin';\n\nimport schema from './db/instant.schema.ts';\nimport { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';\nimport {\n addOAuthRoutes,\n OAuthConfig,\n ServiceProvider,\n tokensOfBearerToken,\n} from './oauth-service-provider.ts';\nimport { KeyConfig } from './crypto.ts';\nimport indexHtml from './index.html.ts';\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\n\n// Helpers\n// -----------\nfunction createMCPServer(): McpServer {\n return new McpServer({\n name: '@instantdb/mcp',\n version,\n });\n}\n\n// Tool Registration\n// -----------\n\n// Adds tracing to server.tool\nfunction wrapServerWithTracing(\n server: McpServer,\n tracer: Tracer,\n attrs: Attributes,\n): McpServer {\n const originalTool = server.tool.bind(server);\n\n server.tool = function (name: string, ...args: any[]): any {\n // Find the callback (it's always the last argument)\n const callback = args[args.length - 1];\n const otherArgs = args.slice(0, -1);\n\n // Wrap the callback with tracing\n const wrappedCallback = async (...callbackArgs: any[]) => {\n const span = tracer.startSpan(`tool.${name}`, {\n attributes: attrs,\n });\n try {\n const result = await callback(...callbackArgs);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error as Error);\n throw error;\n } finally {\n span.end();\n }\n };\n\n return originalTool(\n name,\n // @ts-expect-error: not sure how to type this\n ...otherArgs,\n wrappedCallback,\n );\n } as any;\n\n return server;\n}\n\nfunction registerTools(server: McpServer) {\n server.tool(\n 'learn',\n \"If you don't have any context provided about InstantDB, use this tool to learn about it!\",\n {},\n async () => {\n const instructions = `\n You can learn about InstantDB by fetching our rules file for agents:\n\n https://www.instantdb.com/llm-rules/AGENTS.md\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'get-schema',\n 'Fetch schema for an app by its ID!',\n {\n appId: z.string().uuid().describe('UUID of the app'),\n adminToken: z\n .string()\n .uuid()\n .describe('UUID of the admin token for the app'),\n },\n async ({ appId, adminToken }) => {\n const instructions = `\n You can fetch the schema for the app by using the instant-cli tool:\n\n \\`\\`\\`\n npx instant-cli pull schema --app ${appId} --token ${adminToken} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts. Now 'instant.schema.ts' with contain the schema for the app.\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'get-perms',\n 'Fetch permissions for an app by its ID',\n {\n appId: z.string().uuid().describe('UUID of the app'),\n adminToken: z\n .string()\n .uuid()\n .describe('UUID of the admin token for the app'),\n },\n async ({ appId, adminToken }) => {\n const instructions = `\n You fetch the permissions for the app by using the instant-cli tool:\n\n \\`\\`\\`\n npx instant-cli pull perms --app ${appId} --token ${adminToken} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts. Now 'instant.perms.ts' will contain the permissions for the app.\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'push-schema',\n `Push local schema changes for an app to the server. Do this after updating your local 'instant.schema.ts' file.\n If you don't have an instant.schema.ts file yet, use the get-schema tool to learn how to get this file.`,\n {\n appId: z.string().uuid().describe('UUID of the app'),\n adminToken: z\n .string()\n .uuid()\n .describe('UUID of the admin token for the app'),\n },\n async ({ appId, adminToken }) => {\n const instructions = `\n Push schema changes by using the instant-cli tool:\n\n\n \\`\\`\\`\n npx instant-cli push schema --app ${appId} --token ${adminToken} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts.\n\n By default the instant-cli tool will assume new fields from the previous schema are additions and missing fields are deletions.\n If you want to rename fields as part of your schema changes you can use the --rename flag to specify renames.\n\n \\`\\`\\`\n npx instant-cli push schema --app ${appId} --token ${adminToken} --rename 'posts.author:posts.creator stores.owner:stores.manager' --yes\n \\`\\`\\`\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'push-perms',\n `Push local permissions changes for an app to the server. Do this after updating your local instant.perms.ts file.\n If you don't have an instant.perms.ts file yet, use the get-perms tool to learn how to get this file.`,\n {\n appId: z.string().uuid().describe('UUID of the app'),\n adminToken: z\n .string()\n .uuid()\n .describe('UUID of the admin token for the app'),\n },\n async ({ appId, adminToken }) => {\n const instructions = `\n Push permission changes by using the instant-cli tool:\n\n \\`\\`\\`\n npx instant-cli push schema --app ${appId} --token ${adminToken} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts.\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'query',\n 'Execute a query againt an app. Useful for inspecting data in the app.',\n {},\n async () => {\n const instructions = `\n You can query data for an app by writing and executing a script using the\n Admin SDK. Here's an example script for fetching a habit and its completions:\n\n \\`\\`\\`typescript\n import { init } from \"@instantdb/admin\";\n import \"dotenv/config\";\n\n const adminDb = init({\n appId: process.env.NEXT_PUBLIC_INSTANT_APP_ID!,\n adminToken: process.env.INSTANT_APP_ADMIN_TOKEN!,\n });\n\n async function fetchHabit(habitName: string) {\n const { habits } = await adminDb.query({\n habits: {\n $: { where: { name: habitName } },\n completions: {},\n },\n });\n console.log(habits);\n }\n\n fetchHabit(\"Read\");\n \\`\\`\\`\n\n If you're unsure how to write queries, refer to the documentation:\n\n https://instantdb.com/docs/instaql.md\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'transact',\n 'Execute a transaction against an app. Useful for seeding or modifying data in the app.',\n {},\n async () => {\n const instructions = `\n You can transact data for an app by writing and executing a script using the\n Admin SDK. Here's an example script for seeding a microblog app with some posts:\n\n \\`\\`\\`typescript\n import { init, id } from \"@instantdb/admin\";\n import \"dotenv/config\";\n\n const adminDb = init({\n appId: process.env.NEXT_PUBLIC_INSTANT_APP_ID!,\n adminToken: process.env.INSTANT_APP_ADMIN_TOKEN!,\n });\n\n interface Post {\n id: number;\n author: string;\n handle: string;\n color: string;\n content: string;\n timestamp: string;\n likes: number;\n liked: boolean;\n }\n\n const mockPosts: Post[] = [\n {\n author: 'Sarah Chen',\n handle: 'sarahchen',\n color: 'bg-blue-100',\n content: 'Just launched my new project! Really excited to share it with everyone.',\n timestamp: '2h ago',\n likes: 12,\n liked: false,\n },\n {\n author: 'Alex Rivera',\n handle: 'alexrivera',\n color: 'bg-purple-100',\n content: 'Beautiful sunset today. Nature never stops amazing me.',\n timestamp: '4h ago',\n likes: 19,\n liked: true,\n },\n {\n author: 'Jordan Lee',\n handle: 'jordanlee',\n color: 'bg-pink-100',\n content: 'Working on something cool with Next.js and TypeScript. Updates coming soon!',\n timestamp: '6h ago',\n likes: 7,\n liked: false,\n },\n ];\n\n function friendlyTimeToTimestamp(friendlyTime: string) {\n const hours = parseInt(friendlyTime);\n const now = Date.now();\n return now - (hours * 60 * 60 * 1000);\n }\n\n function seed() {\n console.log(\"Seeding db...\");\n mockPosts.forEach(post => {\n const userId = id();\n const postId = id();\n const user = adminDb.tx.$users[userId].create({});\n const profile = adminDb.tx.profiles[userId].create({\n displayName: post.author,\n handle: post.handle,\n }).link({ user: userId });\n const postEntity = adminDb.tx.posts[postId].create({\n color: post.color,\n content: post.content,\n timestamp: friendlyTimeToTimestamp(post.timestamp),\n }).link({ author: userId });\n const likes = Array.from({ length: post.likes }, () => adminDb.tx.likes[id()].create({ postId, userId }).link({ post: postId, user: userId }));\n adminDb.transact([user, profile, postEntity, ...likes]);\n })\n }\n\n seed();\n \\`\\`\\`\n\n If you're unsure how to make transactions, refer to the documentation:\n\n https://instantdb.com/docs/instaml.md\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n}\n\nasync function startStdio() {\n const {\n values: { token, ['api-url']: apiUrl },\n } = parseArgs({\n options: {\n token: {\n type: 'string',\n },\n ['api-url']: {\n type: 'string',\n },\n },\n });\n\n const accessToken = token || process.env.INSTANT_ACCESS_TOKEN;\n if (!accessToken) {\n console.error(\n 'Provide an access token using --token or set INSTANT_ACCESS_TOKEN environment variable',\n );\n process.exit(1);\n }\n\n const server = createMCPServer();\n registerTools(server);\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('Instant Platform MCP Server running on stdio');\n}\n\nfunction ensureEnv(key: string): string {\n const v = process.env[key];\n if (!v) {\n throw new Error(`Missing environment variable ${key}`);\n }\n return v;\n}\n\nasync function startSse() {\n const honeycomb = new HoneycombSDK({\n apiKey: process.env.HONEYCOMB_API_KEY,\n serviceName: 'mcp-server',\n });\n\n if (process.env.HONEYCOMB_API_KEY) {\n honeycomb.start();\n }\n\n const tracer = trace.getTracer('mcp-server');\n\n const db = init({\n adminToken: ensureEnv('INSTANT_ADMIN_TOKEN'),\n appId: ensureEnv('INSTANT_APP_ID'),\n schema,\n disableValidation: true,\n });\n\n const oauthConfig: OAuthConfig = {\n clientId: ensureEnv('INSTANT_OAUTH_CLIENT_ID'),\n clientSecret: ensureEnv('INSTANT_OAUTH_CLIENT_SECRET'),\n serverOrigin: ensureEnv('SERVER_ORIGIN'),\n };\n\n const keyConfig: KeyConfig = JSON.parse(ensureEnv('INSTANT_AES_KEY'));\n\n const app = express();\n const logger = pino({ level: 'info' });\n\n app.use((req, res, next) => {\n const span = tracer.startSpan('http-req', {\n kind: SpanKind.SERVER,\n attributes: {\n 'http.method': req.method,\n 'http.url': req.url,\n 'http.target': req.path,\n 'http.host': req.get('host'),\n 'http.scheme': req.protocol,\n },\n });\n\n const originalEnd = res.end.bind(res);\n res.end = function (this: typeof res, ...args: any[]): typeof res {\n span.setAttribute('http.status_code', res.statusCode);\n span.setStatus({\n code: res.statusCode >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK,\n });\n span.end();\n return originalEnd(...args);\n };\n\n next();\n });\n\n app.use(\n pinoHttp({\n logger,\n autoLogging: {\n ignore(req) {\n return req.url === '/health';\n },\n },\n }),\n );\n app.use(express.json());\n\n const proxyProvider = new ServiceProvider(db, oauthConfig, keyConfig);\n\n const authRouterOptions = {\n scopesSupported: ['apps-read', 'apps-write'],\n provider: proxyProvider,\n issuerUrl: new URL(oauthConfig.serverOrigin),\n baseUrl: new URL(oauthConfig.serverOrigin),\n serviceDocumentationUrl: new URL('https://instantdb.com/docs'),\n };\n\n const oauthMetadata = createOAuthMetadata(authRouterOptions);\n\n app.use(mcpAuthRouter(authRouterOptions));\n\n addOAuthRoutes(app, db, oauthConfig);\n\n app.get('/.well-known/oauth-protected-resource/mcp', (_req, res) => {\n res.json({\n resource: `${oauthConfig.serverOrigin}/mcp`,\n authorization_servers: [oauthMetadata.issuer],\n scopes_supported: oauthMetadata.scopes_supported,\n resource_documentation: 'https://instantdb.com/docs',\n });\n });\n\n app.get('/.well-known/oauth-protected-resource/sse', (_req, res) => {\n res.json({\n resource: `${oauthConfig.serverOrigin}/mcp`,\n authorization_servers: [oauthMetadata.issuer],\n scopes_supported: oauthMetadata.scopes_supported,\n resource_documentation: 'https://instantdb.com/docs',\n });\n });\n\n const requireTokenMiddleware = (path: string) =>\n requireBearerAuth({\n verifier: proxyProvider,\n resourceMetadataUrl: `${oauthConfig.serverOrigin}/.well-known/oauth-protected-resource/${path}`,\n });\n\n // Handle POST requests for client-to-server communication\n app.post(\n '/mcp',\n requireTokenMiddleware('mcp'),\n async (req: Request, res: Response) => {\n const server = createMCPServer();\n try {\n const tokens = await tokensOfBearerToken(db, req.auth!.token);\n\n wrapServerWithTracing(server, tracer, {\n 'client.client_id': tokens.mcpToken.client?.client_id,\n 'client.name': tokens.mcpToken.client?.client_name,\n 'client.id': tokens.mcpToken.client?.id,\n 'client.scope': tokens.mcpToken.client?.scope,\n 'client.uri': tokens.mcpToken.client?.client_uri,\n 'client.redirect_urls': tokens.mcpToken.client?.redirect_uris,\n });\n registerTools(server);\n const transport: StreamableHTTPServerTransport =\n new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n\n req.on('close', () => {\n transport.close();\n server.close();\n });\n await server.connect(transport);\n await transport.handleRequest(req, res, req.body);\n } catch (e) {\n console.error('Error handling MCP request:', e);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n },\n );\n\n // We're a stateless server, so disallow these\n const handleSessionRequest = async (\n _req: express.Request,\n res: express.Response,\n ) => {\n res.writeHead(405).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed.',\n },\n id: null,\n }),\n );\n };\n\n app.get('/mcp', handleSessionRequest);\n app.delete('/mcp', handleSessionRequest);\n\n // SSE for older clients\n const transports = {\n sse: {} as Record<string, SSEServerTransport>,\n };\n\n app.get(\n '/sse',\n requireTokenMiddleware('sse'),\n async (req: Request, res: Response) => {\n const server = createMCPServer();\n const transport = new SSEServerTransport('/messages', res);\n res.on('close', () => {\n delete transports.sse[transport.sessionId];\n });\n\n try {\n const tokens = await tokensOfBearerToken(db, req.auth!.token);\n\n wrapServerWithTracing(server, tracer, {\n 'client.client_id': tokens.mcpToken.client?.client_id,\n 'client.name': tokens.mcpToken.client?.client_name,\n 'client.id': tokens.mcpToken.client?.id,\n 'client.scope': tokens.mcpToken.client?.scope,\n 'client.uri': tokens.mcpToken.client?.client_uri,\n 'client.redirect_urls': tokens.mcpToken.client?.redirect_uris,\n });\n\n registerTools(server);\n transports.sse[transport.sessionId] = transport;\n } catch (e) {\n console.error('Error handling MCP SSE request:', e);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n return;\n }\n\n await server.connect(transport);\n },\n );\n\n // Legacy message endpoint for older clients\n app.post('/messages', async (req, res) => {\n const sessionId = req.query.sessionId as string;\n const transport = transports.sse[sessionId];\n if (transport) {\n await transport.handlePostMessage(req, res, req.body);\n } else {\n res.status(400).send('No transport found for sessionId');\n }\n });\n\n app.get('/', (_req, res: Response) => {\n res\n .status(200)\n .set('Content-Type', 'text/html; charset=UTF-8')\n .send(indexHtml(oauthConfig.serverOrigin));\n });\n\n app.get('/health', (_req, res: Response) => {\n res.status(200).send('Tip top!');\n });\n\n const port = parseInt(process.env.PORT || '3123');\n const host = process.env.IN_FLY ? '0.0.0.0' : 'localhost';\n\n if (process.env.IN_FLY) {\n app.set('trust proxy', 2);\n }\n\n app.listen(port, host, () => console.log(`listening on port ${port}`));\n}\n\nasync function main() {\n if (process.env.SERVER_TYPE === 'http') {\n return startSse();\n }\n return startStdio();\n}\n\nmain().catch((error) => {\n console.error('Fatal error in main():', error);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport 'dotenv/config';\nimport express, { Request, Response } from 'express';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { parseArgs } from 'node:util';\nimport version from './version.ts';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { HoneycombSDK } from '@honeycombio/opentelemetry-node';\nimport {\n trace,\n SpanKind,\n SpanStatusCode,\n Tracer,\n Attributes,\n} from '@opentelemetry/api';\n\nimport {\n createOAuthMetadata,\n mcpAuthRouter,\n} from '@modelcontextprotocol/sdk/server/auth/router.js';\nimport { pinoHttp } from 'pino-http';\nimport { pino } from 'pino';\nimport { init } from '@instantdb/admin';\n\nimport schema from './db/instant.schema.ts';\nimport { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';\nimport {\n addOAuthRoutes,\n makeApiAuth,\n OAuthConfig,\n ServiceProvider,\n tokensOfBearerToken,\n} from './oauth-service-provider.ts';\nimport { KeyConfig } from './crypto.ts';\nimport { PlatformApi } from '@instantdb/platform';\nimport indexHtml from './index.html.ts';\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport { handleQuery, handleTransact } from './tools.ts';\n\n// Helpers\n// -----------\nfunction createMCPServer(): McpServer {\n return new McpServer({\n name: '@instantdb/mcp',\n version,\n });\n}\n\n// Tool Registration\n// -----------\n\n// Adds tracing to server.tool\nfunction wrapServerWithTracing(\n server: McpServer,\n tracer: Tracer,\n attrs: Attributes,\n): McpServer {\n const originalTool = server.tool.bind(server);\n\n server.tool = function (name: string, ...args: any[]): any {\n // Find the callback (it's always the last argument)\n const callback = args[args.length - 1];\n const otherArgs = args.slice(0, -1);\n\n // Wrap the callback with tracing\n const wrappedCallback = async (...callbackArgs: any[]) => {\n const span = tracer.startSpan(`tool.${name}`, {\n attributes: attrs,\n });\n try {\n const result = await callback(...callbackArgs);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error as Error);\n throw error;\n } finally {\n span.end();\n }\n };\n\n return originalTool(\n name,\n // @ts-expect-error: not sure how to type this\n ...otherArgs,\n wrappedCallback,\n );\n } as any;\n\n return server;\n}\n\nfunction registerTools(server: McpServer, api: PlatformApi) {\n server.tool(\n 'learn',\n \"If you don't have any context provided about InstantDB, use this tool to learn about it!\",\n {},\n async () => {\n const instructions = `\n You can learn about InstantDB by fetching our rules file for agents:\n\n https://www.instantdb.com/llm-rules/AGENTS.md\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'get-schema',\n 'Fetch schema for an app by its ID!',\n {\n appId: z.string().uuid().describe('UUID of the app'),\n },\n async ({ appId }) => {\n const instructions = `\n You can fetch the schema for the app by using the instant-cli tool:\n\n \\`\\`\\`\n npx instant-cli pull schema --app ${appId} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts. Now 'instant.schema.ts' will contain the schema for the app.\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'get-perms',\n 'Fetch permissions for an app by its ID',\n {\n appId: z.string().uuid().describe('UUID of the app'),\n },\n async ({ appId }) => {\n const instructions = `\n You fetch the permissions for the app by using the instant-cli tool:\n\n \\`\\`\\`\n npx instant-cli pull perms --app ${appId} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts. Now 'instant.perms.ts' will contain the permissions for the app.\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'push-schema',\n `Push local schema changes for an app to the server. Do this after updating your local 'instant.schema.ts' file.\n If you don't have an instant.schema.ts file yet, use the get-schema tool to learn how to get this file.`,\n {\n appId: z.string().uuid().describe('UUID of the app'),\n },\n async ({ appId }) => {\n const instructions = `\n Push schema changes by using the instant-cli tool:\n\n \\`\\`\\`\n npx instant-cli push schema --app ${appId} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts.\n\n By default the instant-cli tool will assume new fields from the previous schema are additions and missing fields are deletions.\n If you want to rename fields as part of your schema changes you can use the --rename flag to specify renames.\n\n \\`\\`\\`\n npx instant-cli push schema --app ${appId} --rename 'posts.author:posts.creator stores.owner:stores.manager' --yes\n \\`\\`\\`\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'push-perms',\n `Push local permissions changes for an app to the server. Do this after updating your local instant.perms.ts file.\n If you don't have an instant.perms.ts file yet, use the get-perms tool to learn how to get this file.`,\n {\n appId: z.string().uuid().describe('UUID of the app'),\n },\n async ({ appId }) => {\n const instructions = `\n Push permission changes by using the instant-cli tool:\n\n \\`\\`\\`\n npx instant-cli push perms --app ${appId} --yes\n \\`\\`\\`\n\n We supply the --yes flag to skip confirmation prompts.\n `;\n\n return {\n content: [\n {\n type: 'text',\n text: instructions,\n },\n ],\n };\n },\n );\n\n server.tool(\n 'query',\n `Execute an InstaQL query against an app. Returns the query results as JSON.\n\n Example query to fetch all goals and their todos:\n {\"goals\": {\"todos\": {}}}\n\n Example query with a where clause:\n {\"goals\": {\"$\": {\"where\": {\"status\": \"active\"}}, \"todos\": {}}}\n\n If you're unsure how to write queries, refer to the documentation:\n https://instantdb.com/docs/instaql`,\n {\n appId: z.string().uuid().describe('UUID of the app'),\n query: z.record(z.string(), z.any()).describe('InstaQL query object'),\n },\n async ({ appId, query }) => {\n return handleQuery(api, appId, query);\n },\n );\n\n server.tool(\n 'transact',\n `Execute a transaction against an app. Useful for creating, updating, or deleting data.\n\n Steps use the internal transaction format:\n - Create/update: [\"update\", \"namespace\", \"entity-id\", {\"attr\": \"value\"}]\n - Link: [\"link\", \"namespace\", \"entity-id\", {\"linkAttr\": \"target-id\"}]\n - Unlink: [\"unlink\", \"namespace\", \"entity-id\", {\"linkAttr\": \"target-id\"}]\n - Delete: [\"delete\", \"namespace\", \"entity-id\"]\n\n Example steps to create a todo:\n [[\"update\", \"todos\", \"a-uuid\", {\"title\": \"Get fit\", \"done\": false}]]\n\n If you're unsure how to make transactions, refer to the documentation:\n https://instantdb.com/docs/instaml`,\n {\n appId: z.string().uuid().describe('UUID of the app'),\n steps: z.array(z.array(z.any())).describe('Array of transaction steps'),\n },\n async ({ appId, steps }) => {\n return handleTransact(api, appId, steps);\n },\n );\n}\n\nasync function startStdio() {\n const {\n values: { token, ['api-url']: apiUrl },\n } = parseArgs({\n options: {\n token: {\n type: 'string',\n },\n ['api-url']: {\n type: 'string',\n },\n },\n });\n\n const accessToken = token || process.env.INSTANT_ACCESS_TOKEN;\n if (!accessToken) {\n console.error(\n 'Provide an access token using --token or set INSTANT_ACCESS_TOKEN environment variable',\n );\n process.exit(1);\n }\n\n const api = new PlatformApi({ auth: { token: accessToken } });\n\n const server = createMCPServer();\n registerTools(server, api);\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('Instant Platform MCP Server running on stdio');\n}\n\nfunction ensureEnv(key: string): string {\n const v = process.env[key];\n if (!v) {\n throw new Error(`Missing environment variable ${key}`);\n }\n return v;\n}\n\nasync function startSse() {\n const honeycomb = new HoneycombSDK({\n apiKey: process.env.HONEYCOMB_API_KEY,\n serviceName: 'mcp-server',\n });\n\n if (process.env.HONEYCOMB_API_KEY) {\n honeycomb.start();\n }\n\n const tracer = trace.getTracer('mcp-server');\n\n const db = init({\n adminToken: ensureEnv('INSTANT_ADMIN_TOKEN'),\n appId: ensureEnv('INSTANT_APP_ID'),\n schema,\n disableValidation: true,\n });\n\n const oauthConfig: OAuthConfig = {\n clientId: ensureEnv('INSTANT_OAUTH_CLIENT_ID'),\n clientSecret: ensureEnv('INSTANT_OAUTH_CLIENT_SECRET'),\n serverOrigin: ensureEnv('SERVER_ORIGIN'),\n };\n\n const keyConfig: KeyConfig = JSON.parse(ensureEnv('INSTANT_AES_KEY'));\n\n const app = express();\n const logger = pino({ level: 'info' });\n\n app.use((req, res, next) => {\n const span = tracer.startSpan('http-req', {\n kind: SpanKind.SERVER,\n attributes: {\n 'http.method': req.method,\n 'http.url': req.url,\n 'http.target': req.path,\n 'http.host': req.get('host'),\n 'http.scheme': req.protocol,\n },\n });\n\n const originalEnd = res.end.bind(res);\n res.end = function (this: typeof res, ...args: any[]): typeof res {\n span.setAttribute('http.status_code', res.statusCode);\n span.setStatus({\n code: res.statusCode >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK,\n });\n span.end();\n return originalEnd(...args);\n };\n\n next();\n });\n\n app.use(\n pinoHttp({\n logger,\n autoLogging: {\n ignore(req) {\n return req.url === '/health';\n },\n },\n }),\n );\n app.use(express.json());\n\n const proxyProvider = new ServiceProvider(db, oauthConfig, keyConfig);\n\n const authRouterOptions = {\n scopesSupported: ['apps-read', 'apps-write'],\n provider: proxyProvider,\n issuerUrl: new URL(oauthConfig.serverOrigin),\n baseUrl: new URL(oauthConfig.serverOrigin),\n serviceDocumentationUrl: new URL('https://instantdb.com/docs'),\n };\n\n const oauthMetadata = createOAuthMetadata(authRouterOptions);\n\n app.use(mcpAuthRouter(authRouterOptions));\n\n addOAuthRoutes(app, db, oauthConfig);\n\n app.get('/.well-known/oauth-protected-resource/mcp', (_req, res) => {\n res.json({\n resource: `${oauthConfig.serverOrigin}/mcp`,\n authorization_servers: [oauthMetadata.issuer],\n scopes_supported: oauthMetadata.scopes_supported,\n resource_documentation: 'https://instantdb.com/docs',\n });\n });\n\n app.get('/.well-known/oauth-protected-resource/sse', (_req, res) => {\n res.json({\n resource: `${oauthConfig.serverOrigin}/mcp`,\n authorization_servers: [oauthMetadata.issuer],\n scopes_supported: oauthMetadata.scopes_supported,\n resource_documentation: 'https://instantdb.com/docs',\n });\n });\n\n const requireTokenMiddleware = (path: string) =>\n requireBearerAuth({\n verifier: proxyProvider,\n resourceMetadataUrl: `${oauthConfig.serverOrigin}/.well-known/oauth-protected-resource/${path}`,\n });\n\n // Handle POST requests for client-to-server communication\n app.post(\n '/mcp',\n requireTokenMiddleware('mcp'),\n async (req: Request, res: Response) => {\n const server = createMCPServer();\n try {\n const tokens = await tokensOfBearerToken(db, req.auth!.token);\n\n const api = new PlatformApi({\n auth: makeApiAuth(oauthConfig, keyConfig, db, tokens.instantToken),\n });\n\n wrapServerWithTracing(server, tracer, {\n 'client.client_id': tokens.mcpToken.client?.client_id,\n 'client.name': tokens.mcpToken.client?.client_name,\n 'client.id': tokens.mcpToken.client?.id,\n 'client.scope': tokens.mcpToken.client?.scope,\n 'client.uri': tokens.mcpToken.client?.client_uri,\n 'client.redirect_urls': tokens.mcpToken.client?.redirect_uris,\n });\n registerTools(server, api);\n const transport: StreamableHTTPServerTransport =\n new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n\n req.on('close', () => {\n transport.close();\n server.close();\n });\n await server.connect(transport);\n await transport.handleRequest(req, res, req.body);\n } catch (e) {\n console.error('Error handling MCP request:', e);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n },\n );\n\n // We're a stateless server, so disallow these\n const handleSessionRequest = async (\n _req: express.Request,\n res: express.Response,\n ) => {\n res.writeHead(405).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed.',\n },\n id: null,\n }),\n );\n };\n\n app.get('/mcp', handleSessionRequest);\n app.delete('/mcp', handleSessionRequest);\n\n // SSE for older clients\n const transports = {\n sse: {} as Record<string, SSEServerTransport>,\n };\n\n app.get(\n '/sse',\n requireTokenMiddleware('sse'),\n async (req: Request, res: Response) => {\n const server = createMCPServer();\n const transport = new SSEServerTransport('/messages', res);\n res.on('close', () => {\n delete transports.sse[transport.sessionId];\n });\n\n try {\n const tokens = await tokensOfBearerToken(db, req.auth!.token);\n\n const api = new PlatformApi({\n auth: makeApiAuth(oauthConfig, keyConfig, db, tokens.instantToken),\n });\n\n wrapServerWithTracing(server, tracer, {\n 'client.client_id': tokens.mcpToken.client?.client_id,\n 'client.name': tokens.mcpToken.client?.client_name,\n 'client.id': tokens.mcpToken.client?.id,\n 'client.scope': tokens.mcpToken.client?.scope,\n 'client.uri': tokens.mcpToken.client?.client_uri,\n 'client.redirect_urls': tokens.mcpToken.client?.redirect_uris,\n });\n\n registerTools(server, api);\n transports.sse[transport.sessionId] = transport;\n } catch (e) {\n console.error('Error handling MCP SSE request:', e);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n return;\n }\n\n await server.connect(transport);\n },\n );\n\n // Legacy message endpoint for older clients\n app.post('/messages', async (req, res) => {\n const sessionId = req.query.sessionId as string;\n const transport = transports.sse[sessionId];\n if (transport) {\n await transport.handlePostMessage(req, res, req.body);\n } else {\n res.status(400).send('No transport found for sessionId');\n }\n });\n\n app.get('/', (_req, res: Response) => {\n res\n .status(200)\n .set('Content-Type', 'text/html; charset=UTF-8')\n .send(indexHtml(oauthConfig.serverOrigin));\n });\n\n app.get('/health', (_req, res: Response) => {\n res.status(200).send('Tip top!');\n });\n\n const port = parseInt(process.env.PORT || '3123');\n const host = process.env.IN_FLY ? '0.0.0.0' : 'localhost';\n\n if (process.env.IN_FLY) {\n app.set('trust proxy', 2);\n }\n\n app.listen(port, host, () => console.log(`listening on port ${port}`));\n}\n\nasync function main() {\n if (process.env.SERVER_TYPE === 'http') {\n return startSse();\n }\n return startStdio();\n}\n\nmain().catch((error) => {\n console.error('Fatal error in main():', error);\n process.exit(1);\n});\n"]}
@@ -0,0 +1,12 @@
1
+ import { PlatformApi } from '@instantdb/platform';
2
+ type ToolResult = {
3
+ isError?: boolean;
4
+ content: {
5
+ type: 'text';
6
+ text: string;
7
+ }[];
8
+ };
9
+ export declare function handleQuery(api: PlatformApi, appId: string, query: Record<string, any>): Promise<ToolResult>;
10
+ export declare function handleTransact(api: PlatformApi, appId: string, steps: any[][]): Promise<ToolResult>;
11
+ export {};
12
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIlD,KAAK,UAAU,GAAG;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3C,CAAC;AA8CF,wBAAsB,WAAW,CAC/B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC,UAAU,CAAC,CAiBrB;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,GAAG,EAAE,EAAE,GACb,OAAO,CAAC,UAAU,CAAC,CAiBrB"}
package/dist/tools.js ADDED
@@ -0,0 +1,72 @@
1
+ const API_URL = process.env.INSTANT_API_URL || 'https://api.instantdb.com';
2
+ async function adminQuery(apiURI, token, appId, query) {
3
+ const res = await fetch(`${apiURI}/admin/query`, {
4
+ method: 'POST',
5
+ headers: {
6
+ 'Content-Type': 'application/json',
7
+ Authorization: `Bearer ${token}`,
8
+ 'App-Id': appId,
9
+ },
10
+ body: JSON.stringify({ query }),
11
+ });
12
+ const data = await res.json();
13
+ if (!res.ok) {
14
+ throw new Error(JSON.stringify(data));
15
+ }
16
+ return data;
17
+ }
18
+ async function adminTransact(apiURI, token, appId, steps) {
19
+ const res = await fetch(`${apiURI}/admin/transact`, {
20
+ method: 'POST',
21
+ headers: {
22
+ 'Content-Type': 'application/json',
23
+ Authorization: `Bearer ${token}`,
24
+ 'App-Id': appId,
25
+ },
26
+ body: JSON.stringify({ steps }),
27
+ });
28
+ const data = await res.json();
29
+ if (!res.ok) {
30
+ throw new Error(JSON.stringify(data));
31
+ }
32
+ return data;
33
+ }
34
+ export async function handleQuery(api, appId, query) {
35
+ try {
36
+ const data = await api.withRetry(adminQuery, [
37
+ API_URL,
38
+ api.token(),
39
+ appId,
40
+ query,
41
+ ]);
42
+ return {
43
+ content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
44
+ };
45
+ }
46
+ catch (e) {
47
+ return {
48
+ isError: true,
49
+ content: [{ type: 'text', text: `Error querying app: ${e.message}` }],
50
+ };
51
+ }
52
+ }
53
+ export async function handleTransact(api, appId, steps) {
54
+ try {
55
+ const data = await api.withRetry(adminTransact, [
56
+ API_URL,
57
+ api.token(),
58
+ appId,
59
+ steps,
60
+ ]);
61
+ return {
62
+ content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
63
+ };
64
+ }
65
+ catch (e) {
66
+ return {
67
+ isError: true,
68
+ content: [{ type: 'text', text: `Error transacting: ${e.message}` }],
69
+ };
70
+ }
71
+ }
72
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { PlatformApi } from '@instantdb/platform';\n\nconst API_URL = process.env.INSTANT_API_URL || 'https://api.instantdb.com';\n\ntype ToolResult = {\n isError?: boolean;\n content: { type: 'text'; text: string }[];\n};\n\nasync function adminQuery(\n apiURI: string,\n token: string,\n appId: string,\n query: Record<string, any>,\n) {\n const res = await fetch(`${apiURI}/admin/query`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n 'App-Id': appId,\n },\n body: JSON.stringify({ query }),\n });\n const data = await res.json();\n if (!res.ok) {\n throw new Error(JSON.stringify(data));\n }\n return data;\n}\n\nasync function adminTransact(\n apiURI: string,\n token: string,\n appId: string,\n steps: any[][],\n) {\n const res = await fetch(`${apiURI}/admin/transact`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n 'App-Id': appId,\n },\n body: JSON.stringify({ steps }),\n });\n const data = await res.json();\n if (!res.ok) {\n throw new Error(JSON.stringify(data));\n }\n return data;\n}\n\nexport async function handleQuery(\n api: PlatformApi,\n appId: string,\n query: Record<string, any>,\n): Promise<ToolResult> {\n try {\n const data = await api.withRetry(adminQuery, [\n API_URL,\n api.token(),\n appId,\n query,\n ]);\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n } catch (e: any) {\n return {\n isError: true,\n content: [{ type: 'text', text: `Error querying app: ${e.message}` }],\n };\n }\n}\n\nexport async function handleTransact(\n api: PlatformApi,\n appId: string,\n steps: any[][],\n): Promise<ToolResult> {\n try {\n const data = await api.withRetry(adminTransact, [\n API_URL,\n api.token(),\n appId,\n steps,\n ]);\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n } catch (e: any) {\n return {\n isError: true,\n content: [{ type: 'text', text: `Error transacting: ${e.message}` }],\n };\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instantdb/mcp",
3
- "version": "0.22.171",
3
+ "version": "0.22.172",
4
4
  "description": "Model Context Protocol (MCP) server for managing Instant apps, schemas, and permissions!",
5
5
  "homepage": "https://github.com/instantdb/instant/tree/main/client/packages/mcp",
6
6
  "repository": {
@@ -23,7 +23,7 @@
23
23
  "pino-pretty": "^13.0.0",
24
24
  "tsx": "^4.7.0",
25
25
  "typescript": "^5.9.3",
26
- "vitest": "^1.6.0"
26
+ "vitest": "^3.2.4"
27
27
  },
28
28
  "dependencies": {
29
29
  "@honeycombio/opentelemetry-node": "^0.7.2",
@@ -36,16 +36,18 @@
36
36
  "pino": "^9.7.0",
37
37
  "pino-http": "^10.5.0",
38
38
  "zod": "^3.25.39",
39
- "@instantdb/admin": "0.22.171",
40
- "@instantdb/core": "0.22.171",
41
- "@instantdb/platform": "0.22.171",
42
- "@instantdb/version": "0.22.171"
39
+ "@instantdb/core": "0.22.172",
40
+ "@instantdb/version": "0.22.172",
41
+ "@instantdb/platform": "0.22.172",
42
+ "@instantdb/admin": "0.22.172"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=18"
46
46
  },
47
47
  "scripts": {
48
- "test": "vitest",
48
+ "test": "vitest --project unit",
49
+ "test:e2e": "vitest --project e2e",
50
+ "test:ci": "vitest run",
49
51
  "dev": "tsc --watch --preserveWatchOutput -p tsconfig.dev.json",
50
52
  "clean": "rm -rf dist",
51
53
  "build": "rm -rf dist && tsc",