addai-drive-mcp 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.
@@ -0,0 +1,25 @@
1
+ export interface StorageError {
2
+ message: string;
3
+ code?: string;
4
+ }
5
+ export declare class DriveClient {
6
+ private baseUrl;
7
+ private apiKey;
8
+ constructor(apiKey: string, baseUrl?: string);
9
+ private headers;
10
+ get<T = unknown>(fn: string, params?: Record<string, string | undefined>): Promise<{
11
+ data?: T;
12
+ error?: StorageError;
13
+ }>;
14
+ post<T = unknown>(fn: string, body: unknown): Promise<{
15
+ data?: T;
16
+ error?: StorageError;
17
+ }>;
18
+ getBytes(fn: string, params?: Record<string, string | undefined>): Promise<{
19
+ bytes?: Uint8Array;
20
+ contentType?: string;
21
+ error?: StorageError;
22
+ }>;
23
+ private parse;
24
+ }
25
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAK5C,OAAO,CAAC,OAAO;IAQT,GAAG,CAAC,CAAC,GAAG,OAAO,EACnB,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC1C,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;IAexC,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;IAUxC,QAAQ,CACZ,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC1C,OAAO,CAAC;QAAE,KAAK,CAAC,EAAE,UAAU,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;YAmBhE,KAAK;CAkBpB"}
package/dist/client.js ADDED
@@ -0,0 +1,86 @@
1
+ // Thin client over the +Ai Drive (addai-storage) edge functions. Each storage
2
+ // operation is its own function under the project's functions base URL, so
3
+ // unlike a single REST API we address each function by name. Auth is the
4
+ // entity's API key in the x-api-key header (the same key the runtime mints).
5
+ const DEFAULT_BASE_URL = 'https://syhzpqqvrplaqdipcymw.supabase.co/functions/v1';
6
+ export class DriveClient {
7
+ baseUrl;
8
+ apiKey;
9
+ constructor(apiKey, baseUrl) {
10
+ this.apiKey = apiKey;
11
+ this.baseUrl = (baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
12
+ }
13
+ headers() {
14
+ return {
15
+ 'x-api-key': this.apiKey,
16
+ 'Content-Type': 'application/json',
17
+ };
18
+ }
19
+ // GET a storage function with query params, parsing JSON.
20
+ async get(fn, params) {
21
+ let url = `${this.baseUrl}/${fn}`;
22
+ if (params) {
23
+ const sp = new URLSearchParams();
24
+ for (const [k, v] of Object.entries(params)) {
25
+ if (v !== undefined && v !== '')
26
+ sp.set(k, v);
27
+ }
28
+ const qs = sp.toString();
29
+ if (qs)
30
+ url += `?${qs}`;
31
+ }
32
+ const res = await fetch(url, { method: 'GET', headers: this.headers() });
33
+ return this.parse(res);
34
+ }
35
+ // POST a storage function with a JSON body, parsing JSON.
36
+ async post(fn, body) {
37
+ const res = await fetch(`${this.baseUrl}/${fn}`, {
38
+ method: 'POST',
39
+ headers: this.headers(),
40
+ body: JSON.stringify(body),
41
+ });
42
+ return this.parse(res);
43
+ }
44
+ // GET raw bytes (used by read_file via storage-download?proxy=1).
45
+ async getBytes(fn, params) {
46
+ let url = `${this.baseUrl}/${fn}`;
47
+ if (params) {
48
+ const sp = new URLSearchParams();
49
+ for (const [k, v] of Object.entries(params)) {
50
+ if (v !== undefined && v !== '')
51
+ sp.set(k, v);
52
+ }
53
+ const qs = sp.toString();
54
+ if (qs)
55
+ url += `?${qs}`;
56
+ }
57
+ const res = await fetch(url, { method: 'GET', headers: { 'x-api-key': this.apiKey } });
58
+ if (!res.ok) {
59
+ const txt = await res.text().catch(() => '');
60
+ return { error: { message: txt || `Request failed (${res.status})`, code: String(res.status) } };
61
+ }
62
+ const buf = new Uint8Array(await res.arrayBuffer());
63
+ return { bytes: buf, contentType: res.headers.get('content-type') || undefined };
64
+ }
65
+ async parse(res) {
66
+ let json = {};
67
+ try {
68
+ json = (await res.json());
69
+ }
70
+ catch {
71
+ if (!res.ok)
72
+ return { error: { message: `Request failed (${res.status})`, code: String(res.status) } };
73
+ }
74
+ if (!res.ok || (json && json.error)) {
75
+ const err = json.error;
76
+ return {
77
+ error: {
78
+ message: err?.message || `Request failed (${res.status})`,
79
+ code: String(res.status),
80
+ },
81
+ };
82
+ }
83
+ return { data: json };
84
+ }
85
+ }
86
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAC3E,yEAAyE;AACzE,6EAA6E;AAE7E,MAAM,gBAAgB,GACpB,uDAAuD,CAAC;AAO1D,MAAM,OAAO,WAAW;IACd,OAAO,CAAS;IAChB,MAAM,CAAS;IAEvB,YAAY,MAAc,EAAE,OAAgB;QAC1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnE,CAAC;IAEO,OAAO;QACb,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,MAAM;YACxB,cAAc,EAAE,kBAAkB;SACnC,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,GAAG,CACP,EAAU,EACV,MAA2C;QAE3C,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;YACjC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;oBAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;YACzB,IAAI,EAAE;gBAAE,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QAC1B,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC,KAAK,CAAI,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,IAAI,CACR,EAAU,EACV,IAAa;QAEb,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,EAAE;YAC/C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;YACvB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAI,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,QAAQ,CACZ,EAAU,EACV,MAA2C;QAE3C,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;YACjC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;oBAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;YACzB,IAAI,EAAE;gBAAE,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QAC1B,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7C,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,IAAI,mBAAmB,GAAG,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACnG,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACpD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,EAAE,CAAC;IACnF,CAAC;IAEO,KAAK,CAAC,KAAK,CAAI,GAAa;QAClC,IAAI,IAAI,GAA4B,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,mBAAmB,GAAG,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACzG,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,IAAK,IAA4B,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,GAAG,GAAI,IAAyC,CAAC,KAAK,CAAC;YAC7D,OAAO;gBACL,KAAK,EAAE;oBACL,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,mBAAmB,GAAG,CAAC,MAAM,GAAG;oBACzD,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;iBACzB;aACF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAS,EAAE,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ export declare function mcpError(message: string): {
2
+ content: {
3
+ type: "text";
4
+ text: string;
5
+ }[];
6
+ isError: boolean;
7
+ };
8
+ export declare function mcpResult(data: unknown): {
9
+ content: {
10
+ type: "text";
11
+ text: string;
12
+ }[];
13
+ };
14
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM;;;;;;EAKvC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO;;;;;EAKtC"}
package/dist/errors.js ADDED
@@ -0,0 +1,15 @@
1
+ // MCP tool result helpers — mirror the aitables-mcp shapes so tool output is
2
+ // consistent across +Ai MCP servers.
3
+ export function mcpError(message) {
4
+ return {
5
+ content: [{ type: 'text', text: `Error: ${message}` }],
6
+ isError: true,
7
+ };
8
+ }
9
+ export function mcpResult(data) {
10
+ const text = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
11
+ return {
12
+ content: [{ type: 'text', text }],
13
+ };
14
+ }
15
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,qCAAqC;AAErC,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QAC/D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7E,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { createServer } from './server.js';
4
+ const apiKey = process.env.ADDAI_DRIVE_API_KEY;
5
+ const workspaceId = process.env.ADDAI_DRIVE_WORKSPACE_ID;
6
+ const rootFolderId = process.env.ADDAI_DRIVE_FOLDER_ID;
7
+ if (!apiKey || !workspaceId || !rootFolderId) {
8
+ console.error('Error: +Ai Drive MCP requires ADDAI_DRIVE_API_KEY, ADDAI_DRIVE_WORKSPACE_ID, and ADDAI_DRIVE_FOLDER_ID.\n\n' +
9
+ 'These are provisioned automatically when the +Ai Drive app is added to an entity. Example .mcp.json:\n' +
10
+ ' {\n' +
11
+ ' "mcpServers": {\n' +
12
+ ' "addai-drive": {\n' +
13
+ ' "command": "npx",\n' +
14
+ ' "args": ["-y", "addai-drive-mcp"],\n' +
15
+ ' "env": {\n' +
16
+ ' "ADDAI_DRIVE_API_KEY": "ait_ent_xxxx",\n' +
17
+ ' "ADDAI_DRIVE_WORKSPACE_ID": "<workspace uuid>",\n' +
18
+ ' "ADDAI_DRIVE_FOLDER_ID": "<your drive root folder uuid>"\n' +
19
+ ' }\n' +
20
+ ' }\n' +
21
+ ' }\n' +
22
+ ' }');
23
+ process.exit(1);
24
+ }
25
+ const baseUrl = process.env.ADDAI_DRIVE_API_URL || undefined;
26
+ const server = createServer({ apiKey, workspaceId, rootFolderId, baseUrl });
27
+ const transport = new StdioServerTransport();
28
+ await server.connect(transport);
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;AACzD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;AAEvD,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,EAAE,CAAC;IAC7C,OAAO,CAAC,KAAK,CACX,6GAA6G;QAC3G,wGAAwG;QACxG,OAAO;QACP,uBAAuB;QACvB,0BAA0B;QAC1B,6BAA6B;QAC7B,8CAA8C;QAC9C,oBAAoB;QACpB,oDAAoD;QACpD,6DAA6D;QAC7D,sEAAsE;QACtE,aAAa;QACb,WAAW;QACX,SAAS;QACT,KAAK,CACR,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,SAAS,CAAC;AAC7D,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;AAC5E,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export interface DriveConfig {
3
+ apiKey: string;
4
+ workspaceId: string;
5
+ rootFolderId: string;
6
+ baseUrl?: string;
7
+ }
8
+ export declare function createServer(config: DriveConfig): McpServer;
9
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAsBD,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CA0N3D"}
package/dist/server.js ADDED
@@ -0,0 +1,183 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+ import { DriveClient } from './client.js';
4
+ import { mcpError, mcpResult } from './errors.js';
5
+ const SERVER_INSTRUCTIONS = `You are connected to +Ai Drive — your own persistent file storage. Everything you save here lives in YOUR folder and is available every time you run, so use it as your long-term memory and working storage for documents, notes, data exports, and any files you produce.
6
+
7
+ ## Your folder
8
+ All your files live under one root folder (your "Drive"). list_files with no folder_id shows the root. Folders can nest — make_folder creates subfolders to stay organised (e.g. "reports", "drafts", "data").
9
+
10
+ ## Reading & writing
11
+ - **list_files** — see what you already have (subfolders + files). Do this first so you don't duplicate work.
12
+ - **read_file** — read a text file's contents by id.
13
+ - **write_file** — save text content as a file (markdown, notes, JSON, CSV, code). This is the main way you create files.
14
+ - **upload_file** — save binary content (base64) when you have non-text bytes.
15
+
16
+ ## Organising
17
+ - **make_folder** — create a subfolder. **rename_file / rename_folder** — rename. **move_files** — move files into a folder. **delete_files / delete_folder** — remove things (deletes are permanent).
18
+ - **search_files** — find a file by name across your Drive.
19
+
20
+ ## Habits
21
+ 1. At the start of a task, list_files to recall what you already have.
22
+ 2. Save anything worth keeping with write_file — don't lose work between runs.
23
+ 3. Keep a tidy structure with folders; put a file's id in your notes if you'll need it again.`;
24
+ export function createServer(config) {
25
+ const server = new McpServer({ name: 'addai-drive-mcp', version: '0.1.0' }, { instructions: SERVER_INSTRUCTIONS });
26
+ const client = new DriveClient(config.apiKey, config.baseUrl);
27
+ const { workspaceId, rootFolderId } = config;
28
+ // ── list_files ──
29
+ server.tool('list_files', "List the subfolders and files in one of your Drive folders. Omit folder_id to list your Drive root. Returns folders[] and files[] (each file has id, name, type, size, folderId).", {
30
+ folder_id: z
31
+ .string()
32
+ .uuid()
33
+ .optional()
34
+ .describe('Folder to list. Omit for your Drive root.'),
35
+ }, async ({ folder_id }) => {
36
+ const res = await client.get('storage-list', {
37
+ workspaceId,
38
+ folderId: folder_id || rootFolderId,
39
+ });
40
+ if (res.error)
41
+ return mcpError(res.error.message);
42
+ return mcpResult(res.data);
43
+ });
44
+ // ── read_file ──
45
+ server.tool('read_file', 'Read the contents of a text file in your Drive by its id. Returns the decoded text. For binary files this may be unreadable — use it for text/markdown/JSON/CSV/code.', {
46
+ file_id: z.string().uuid().describe('The id of the file to read'),
47
+ }, async ({ file_id }) => {
48
+ const res = await client.getBytes('storage-download', { fileId: file_id, proxy: '1' });
49
+ if (res.error)
50
+ return mcpError(res.error.message);
51
+ const text = Buffer.from(res.bytes ?? new Uint8Array()).toString('utf-8');
52
+ return mcpResult(text);
53
+ });
54
+ // ── write_file ──
55
+ server.tool('write_file', 'Save text content as a file in your Drive (markdown, notes, JSON, CSV, code, etc). Creates a new file. Omit folder_id to save in your Drive root.', {
56
+ file_name: z.string().min(1).describe('File name, e.g. "summary.md" or "data.json"'),
57
+ content: z.string().describe('The text content to write'),
58
+ folder_id: z
59
+ .string()
60
+ .uuid()
61
+ .optional()
62
+ .describe('Folder to save into. Omit for your Drive root.'),
63
+ content_type: z
64
+ .string()
65
+ .optional()
66
+ .describe('MIME type. Defaults to text/plain (use text/markdown, application/json, text/csv as appropriate).'),
67
+ }, async ({ file_name, content, folder_id, content_type }) => {
68
+ const base64Data = Buffer.from(content, 'utf-8').toString('base64');
69
+ const res = await client.post('storage-upload', {
70
+ base64Data,
71
+ fileName: file_name,
72
+ contentType: content_type || 'text/plain',
73
+ sourceApp: 'direct_upload',
74
+ sourceKind: 'entity_file',
75
+ folderId: folder_id || rootFolderId,
76
+ workspaceId,
77
+ });
78
+ if (res.error)
79
+ return mcpError(res.error.message);
80
+ return mcpResult(res.data);
81
+ });
82
+ // ── upload_file ──
83
+ server.tool('upload_file', 'Save binary content (provided as base64) as a file in your Drive — use for images, PDFs, or any non-text bytes. For text, prefer write_file.', {
84
+ file_name: z.string().min(1).describe('File name including extension'),
85
+ base64_data: z.string().min(1).describe('File bytes encoded as base64'),
86
+ content_type: z.string().min(1).describe('MIME type, e.g. image/png or application/pdf'),
87
+ folder_id: z
88
+ .string()
89
+ .uuid()
90
+ .optional()
91
+ .describe('Folder to save into. Omit for your Drive root.'),
92
+ }, async ({ file_name, base64_data, content_type, folder_id }) => {
93
+ const res = await client.post('storage-upload', {
94
+ base64Data: base64_data,
95
+ fileName: file_name,
96
+ contentType: content_type,
97
+ sourceApp: 'direct_upload',
98
+ sourceKind: 'entity_file',
99
+ folderId: folder_id || rootFolderId,
100
+ workspaceId,
101
+ });
102
+ if (res.error)
103
+ return mcpError(res.error.message);
104
+ return mcpResult(res.data);
105
+ });
106
+ // ── make_folder ──
107
+ server.tool('make_folder', 'Create a subfolder in your Drive to organise files. Omit parent_id to create it at your Drive root, or nest it under an existing folder.', {
108
+ name: z.string().min(1).describe('Folder name'),
109
+ parent_id: z
110
+ .string()
111
+ .uuid()
112
+ .optional()
113
+ .describe('Parent folder. Omit for your Drive root.'),
114
+ }, async ({ name, parent_id }) => {
115
+ const res = await client.post('storage-folder', {
116
+ op: 'create',
117
+ name,
118
+ parentId: parent_id || rootFolderId,
119
+ });
120
+ if (res.error)
121
+ return mcpError(res.error.message);
122
+ return mcpResult(res.data);
123
+ });
124
+ // ── rename_file ──
125
+ server.tool('rename_file', 'Rename a file in your Drive.', {
126
+ file_id: z.string().uuid().describe('The file to rename'),
127
+ name: z.string().min(1).describe('New file name'),
128
+ }, async ({ file_id, name }) => {
129
+ const res = await client.post('storage-rename', { fileId: file_id, name });
130
+ if (res.error)
131
+ return mcpError(res.error.message);
132
+ return mcpResult(res.data);
133
+ });
134
+ // ── rename_folder ──
135
+ server.tool('rename_folder', 'Rename a folder in your Drive.', {
136
+ folder_id: z.string().uuid().describe('The folder to rename'),
137
+ name: z.string().min(1).describe('New folder name'),
138
+ }, async ({ folder_id, name }) => {
139
+ const res = await client.post('storage-folder', { op: 'rename', folderId: folder_id, name });
140
+ if (res.error)
141
+ return mcpError(res.error.message);
142
+ return mcpResult(res.data);
143
+ });
144
+ // ── move_files ──
145
+ server.tool('move_files', 'Move one or more files into a folder in your Drive. Pass folder_id = your Drive root to move them back to the top level.', {
146
+ file_ids: z.array(z.string().uuid()).min(1).describe('The files to move'),
147
+ folder_id: z.string().uuid().describe('Destination folder id'),
148
+ }, async ({ file_ids, folder_id }) => {
149
+ const res = await client.post('storage-move', { fileIds: file_ids, folderId: folder_id });
150
+ if (res.error)
151
+ return mcpError(res.error.message);
152
+ return mcpResult(res.data);
153
+ });
154
+ // ── delete_files ──
155
+ server.tool('delete_files', 'Permanently delete one or more files from your Drive. This cannot be undone.', {
156
+ file_ids: z.array(z.string().uuid()).min(1).describe('The files to delete'),
157
+ }, async ({ file_ids }) => {
158
+ const res = await client.post('storage-delete', { fileIds: file_ids });
159
+ if (res.error)
160
+ return mcpError(res.error.message);
161
+ return mcpResult(res.data);
162
+ });
163
+ // ── delete_folder ──
164
+ server.tool('delete_folder', 'Delete an (empty) folder from your Drive. Move or delete its contents first.', {
165
+ folder_id: z.string().uuid().describe('The folder to delete'),
166
+ }, async ({ folder_id }) => {
167
+ const res = await client.post('storage-folder', { op: 'delete', folderId: folder_id });
168
+ if (res.error)
169
+ return mcpError(res.error.message);
170
+ return mcpResult({ message: 'Folder deleted' });
171
+ });
172
+ // ── search_files ──
173
+ server.tool('search_files', 'Search your Drive for files by name/text. Returns matching files across all your folders.', {
174
+ query: z.string().min(1).describe('Search term'),
175
+ }, async ({ query }) => {
176
+ const res = await client.get('storage-search', { workspaceId, query });
177
+ if (res.error)
178
+ return mcpError(res.error.message);
179
+ return mcpResult(res.data);
180
+ });
181
+ return server;
182
+ }
183
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AASlD,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;8FAkBkE,CAAC;AAE/F,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC7C,EAAE,YAAY,EAAE,mBAAmB,EAAE,CACtC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAE7C,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,mLAAmL,EACnL;QACE,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,IAAI,EAAE;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,2CAA2C,CAAC;KACzD,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE;YAC3C,WAAW;YACX,QAAQ,EAAE,SAAS,IAAI,YAAY;SACpC,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,kBAAkB;IAClB,MAAM,CAAC,IAAI,CACT,WAAW,EACX,uKAAuK,EACvK;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;KAClE,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1E,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,mJAAmJ,EACnJ;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QACpF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QACzD,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,IAAI,EAAE;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,gDAAgD,CAAC;QAC7D,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,mGAAmG,CAAC;KACjH,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE;QACxD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAC9C,UAAU;YACV,QAAQ,EAAE,SAAS;YACnB,WAAW,EAAE,YAAY,IAAI,YAAY;YACzC,SAAS,EAAE,eAAe;YAC1B,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,SAAS,IAAI,YAAY;YACnC,WAAW;SACZ,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,oBAAoB;IACpB,MAAM,CAAC,IAAI,CACT,aAAa,EACb,8IAA8I,EAC9I;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;QACtE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QACvE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QACxF,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,IAAI,EAAE;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,gDAAgD,CAAC;KAC9D,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAC9C,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,SAAS;YACnB,WAAW,EAAE,YAAY;YACzB,SAAS,EAAE,eAAe;YAC1B,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,SAAS,IAAI,YAAY;YACnC,WAAW;SACZ,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,oBAAoB;IACpB,MAAM,CAAC,IAAI,CACT,aAAa,EACb,0IAA0I,EAC1I;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC/C,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,IAAI,EAAE;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,0CAA0C,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAC9C,EAAE,EAAE,QAAQ;YACZ,IAAI;YACJ,QAAQ,EAAE,SAAS,IAAI,YAAY;SACpC,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,oBAAoB;IACpB,MAAM,CAAC,IAAI,CACT,aAAa,EACb,8BAA8B,EAC9B;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC;KAClD,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,sBAAsB;IACtB,MAAM,CAAC,IAAI,CACT,eAAe,EACf,gCAAgC,EAChC;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAC7D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KACpD,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7F,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,0HAA0H,EAC1H;QACE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACzE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;KAC/D,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;QAChC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1F,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,qBAAqB;IACrB,MAAM,CAAC,IAAI,CACT,cAAc,EACd,8EAA8E,EAC9E;QACE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;KAC5E,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvE,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,sBAAsB;IACtB,MAAM,CAAC,IAAI,CACT,eAAe,EACf,8EAA8E,EAC9E;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KAC9D,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAClD,CAAC,CACF,CAAC;IAEF,qBAAqB;IACrB,MAAM,CAAC,IAAI,CACT,cAAc,EACd,2FAA2F,EAC3F;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;KACjD,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;QACvE,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "addai-drive-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for +Ai Drive — lets an +Ai entity store, read, and manage files in its own Drive folder",
5
+ "type": "module",
6
+ "bin": {
7
+ "addai-drive-mcp": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "dev": "tsc --watch",
16
+ "start": "node dist/index.js"
17
+ },
18
+ "keywords": [
19
+ "mcp",
20
+ "claude",
21
+ "addai",
22
+ "drive",
23
+ "storage",
24
+ "files",
25
+ "model-context-protocol"
26
+ ],
27
+ "license": "MIT",
28
+ "dependencies": {
29
+ "@modelcontextprotocol/sdk": "^1.12.1",
30
+ "zod": "^3.24.4"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.15.3",
34
+ "typescript": "^5.8.3"
35
+ }
36
+ }