@mtcsistemas/appflowy-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +324 -0
  3. package/dist/config.d.ts +25 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +56 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/index.d.ts +15 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +53 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/prompts/appflowy-prompts.d.ts +7 -0
  12. package/dist/prompts/appflowy-prompts.d.ts.map +1 -0
  13. package/dist/prompts/appflowy-prompts.js +115 -0
  14. package/dist/prompts/appflowy-prompts.js.map +1 -0
  15. package/dist/resources/workspace-resources.d.ts +7 -0
  16. package/dist/resources/workspace-resources.d.ts.map +1 -0
  17. package/dist/resources/workspace-resources.js +86 -0
  18. package/dist/resources/workspace-resources.js.map +1 -0
  19. package/dist/server.d.ts +7 -0
  20. package/dist/server.d.ts.map +1 -0
  21. package/dist/server.js +31 -0
  22. package/dist/server.js.map +1 -0
  23. package/dist/services/appflowy-client.d.ts +65 -0
  24. package/dist/services/appflowy-client.d.ts.map +1 -0
  25. package/dist/services/appflowy-client.js +303 -0
  26. package/dist/services/appflowy-client.js.map +1 -0
  27. package/dist/services/auth.d.ts +26 -0
  28. package/dist/services/auth.d.ts.map +1 -0
  29. package/dist/services/auth.js +89 -0
  30. package/dist/services/auth.js.map +1 -0
  31. package/dist/tools/databases.d.ts +7 -0
  32. package/dist/tools/databases.d.ts.map +1 -0
  33. package/dist/tools/databases.js +199 -0
  34. package/dist/tools/databases.js.map +1 -0
  35. package/dist/tools/documents.d.ts +7 -0
  36. package/dist/tools/documents.d.ts.map +1 -0
  37. package/dist/tools/documents.js +197 -0
  38. package/dist/tools/documents.js.map +1 -0
  39. package/dist/tools/files.d.ts +7 -0
  40. package/dist/tools/files.d.ts.map +1 -0
  41. package/dist/tools/files.js +196 -0
  42. package/dist/tools/files.js.map +1 -0
  43. package/dist/tools/search.d.ts +7 -0
  44. package/dist/tools/search.d.ts.map +1 -0
  45. package/dist/tools/search.js +60 -0
  46. package/dist/tools/search.js.map +1 -0
  47. package/dist/tools/workspaces.d.ts +7 -0
  48. package/dist/tools/workspaces.d.ts.map +1 -0
  49. package/dist/tools/workspaces.js +66 -0
  50. package/dist/tools/workspaces.js.map +1 -0
  51. package/dist/types.d.ts +140 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +6 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +64 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AppFlowy MCP Server - Database Tools
3
+ * MCP tools for database/table operations
4
+ */
5
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
+ export declare function registerDatabaseTools(server: McpServer): void;
7
+ //# sourceMappingURL=databases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"databases.d.ts","sourceRoot":"","sources":["../../src/tools/databases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAmMtD"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * AppFlowy MCP Server - Database Tools
3
+ * MCP tools for database/table operations
4
+ */
5
+ import { z } from 'zod';
6
+ import { appflowyClient } from '../services/appflowy-client.js';
7
+ export function registerDatabaseTools(server) {
8
+ // Tool: List databases
9
+ server.tool('appflowy_list_databases', `List all databases (Grid, Board, Calendar, Gallery) in a workspace.
10
+
11
+ Args:
12
+ - workspace_id: The workspace ID`, {
13
+ workspace_id: z.string().describe('The workspace ID'),
14
+ }, async ({ workspace_id }) => {
15
+ try {
16
+ const databases = await appflowyClient.listDatabases(workspace_id);
17
+ if (databases.length === 0) {
18
+ return {
19
+ content: [{ type: 'text', text: 'No databases found in this workspace.' }],
20
+ };
21
+ }
22
+ const lines = ['# Databases\n'];
23
+ for (const db of databases) {
24
+ const icon = getLayoutIcon(db.layout);
25
+ lines.push(`${icon} **${db.name}** (${db.layout})`);
26
+ lines.push(` ID: ${db.view_id}`);
27
+ if (db.last_edited_time)
28
+ lines.push(` Last edited: ${db.last_edited_time}`);
29
+ lines.push('');
30
+ }
31
+ return {
32
+ content: [{ type: 'text', text: lines.join('\n') }],
33
+ };
34
+ }
35
+ catch (error) {
36
+ return {
37
+ content: [{ type: 'text', text: `āŒ Error listing databases: ${error.message}` }],
38
+ isError: true,
39
+ };
40
+ }
41
+ });
42
+ // Tool: Read database
43
+ server.tool('appflowy_read_database', `Read all rows from a database (table/kanban/calendar).
44
+
45
+ Returns a markdown table with all data.
46
+
47
+ Args:
48
+ - workspace_id: The workspace ID
49
+ - database_id: The database/view ID`, {
50
+ workspace_id: z.string().describe('The workspace ID'),
51
+ database_id: z.string().describe('The database/view ID'),
52
+ }, async ({ workspace_id, database_id }) => {
53
+ try {
54
+ const [dbInfo, rows] = await Promise.all([
55
+ appflowyClient.getDatabase(workspace_id, database_id),
56
+ appflowyClient.getDatabaseRows(workspace_id, database_id),
57
+ ]);
58
+ const lines = [`# ${dbInfo.name}\n`];
59
+ lines.push(`**Type**: ${dbInfo.views?.[0]?.layout || 'Grid'}\n`);
60
+ // Headers
61
+ const headers = dbInfo.fields.map((f) => f.name).join(' | ');
62
+ lines.push(`| ${headers} |`);
63
+ lines.push(`|${dbInfo.fields.map(() => '---').join('|')}|`);
64
+ // Rows
65
+ for (const row of rows) {
66
+ const cells = dbInfo.fields.map((f) => {
67
+ const cell = row.cells[f.id];
68
+ return formatCellValue(cell);
69
+ });
70
+ lines.push(`| ${cells.join(' | ')} |`);
71
+ }
72
+ lines.push(`\n*Total rows: ${rows.length}*`);
73
+ return {
74
+ content: [{ type: 'text', text: lines.join('\n') }],
75
+ };
76
+ }
77
+ catch (error) {
78
+ return {
79
+ content: [{ type: 'text', text: `āŒ Error reading database: ${error.message}` }],
80
+ isError: true,
81
+ };
82
+ }
83
+ });
84
+ // Tool: Create database row
85
+ server.tool('appflowy_create_database_row', `Create a new row/entry in a database.
86
+
87
+ Args:
88
+ - workspace_id: The workspace ID
89
+ - database_id: The database/view ID
90
+ - cells: Object with field IDs as keys and values
91
+
92
+ Example cells:
93
+ {\"field_abc123\": \"Task name\", \"field_def456\": \"In Progress\"}`, {
94
+ workspace_id: z.string().describe('The workspace ID'),
95
+ database_id: z.string().describe('The database/view ID'),
96
+ cells: z.record(z.any()).describe('Cell values { field_id: value }'),
97
+ }, async ({ workspace_id, database_id, cells }) => {
98
+ try {
99
+ const row = await appflowyClient.createDatabaseRow(workspace_id, database_id, cells);
100
+ return {
101
+ content: [
102
+ {
103
+ type: 'text',
104
+ text: `āœ… Row created successfully.\n\n- Row ID: ${row.id}\n- Created: ${row.created_at}`,
105
+ },
106
+ ],
107
+ };
108
+ }
109
+ catch (error) {
110
+ return {
111
+ content: [{ type: 'text', text: `āŒ Error creating row: ${error.message}` }],
112
+ isError: true,
113
+ };
114
+ }
115
+ });
116
+ // Tool: Update database row
117
+ server.tool('appflowy_update_database_row', `Update an existing row in a database.
118
+
119
+ Args:
120
+ - workspace_id: The workspace ID
121
+ - database_id: The database/view ID
122
+ - row_id: The row ID to update
123
+ - cells: Object with field IDs and new values`, {
124
+ workspace_id: z.string().describe('The workspace ID'),
125
+ database_id: z.string().describe('The database/view ID'),
126
+ row_id: z.string().describe('The row ID to update'),
127
+ cells: z.record(z.any()).describe('Cell values to update { field_id: value }'),
128
+ }, async ({ workspace_id, database_id, row_id, cells }) => {
129
+ try {
130
+ const row = await appflowyClient.updateDatabaseRow(workspace_id, database_id, row_id, cells);
131
+ return {
132
+ content: [
133
+ {
134
+ type: 'text',
135
+ text: `āœ… Row updated successfully.\n\n- Row ID: ${row.id}\n- Last modified: ${row.last_modified}`,
136
+ },
137
+ ],
138
+ };
139
+ }
140
+ catch (error) {
141
+ return {
142
+ content: [{ type: 'text', text: `āŒ Error updating row: ${error.message}` }],
143
+ isError: true,
144
+ };
145
+ }
146
+ });
147
+ // Tool: Delete database row
148
+ server.tool('appflowy_delete_database_row', `āš ļø Delete a row from a database. This action cannot be undone!
149
+
150
+ Args:
151
+ - workspace_id: The workspace ID
152
+ - database_id: The database/view ID
153
+ - row_id: The row ID to delete`, {
154
+ workspace_id: z.string().describe('The workspace ID'),
155
+ database_id: z.string().describe('The database/view ID'),
156
+ row_id: z.string().describe('The row ID to delete'),
157
+ }, async ({ workspace_id, database_id, row_id }) => {
158
+ try {
159
+ await appflowyClient.deleteDatabaseRow(workspace_id, database_id, row_id);
160
+ return {
161
+ content: [{ type: 'text', text: 'šŸ—‘ļø Row deleted successfully.' }],
162
+ };
163
+ }
164
+ catch (error) {
165
+ return {
166
+ content: [{ type: 'text', text: `āŒ Error deleting row: ${error.message}` }],
167
+ isError: true,
168
+ };
169
+ }
170
+ });
171
+ }
172
+ // Helper: Get icon for layout
173
+ function getLayoutIcon(layout) {
174
+ const icons = {
175
+ Grid: 'šŸ“Š',
176
+ Board: 'šŸ“‹',
177
+ Calendar: 'šŸ“…',
178
+ Gallery: 'šŸ–¼ļø',
179
+ };
180
+ return icons[layout] || 'šŸ“Š';
181
+ }
182
+ // Helper: Format cell value for display
183
+ function formatCellValue(cell) {
184
+ if (!cell)
185
+ return '-';
186
+ if (cell.text)
187
+ return cell.text;
188
+ if (cell.value !== undefined) {
189
+ if (Array.isArray(cell.value))
190
+ return cell.value.join(', ');
191
+ if (typeof cell.value === 'boolean')
192
+ return cell.value ? 'āœ…' : 'āŒ';
193
+ if (cell.value === null || cell.value === '')
194
+ return '-';
195
+ return String(cell.value);
196
+ }
197
+ return '-';
198
+ }
199
+ //# sourceMappingURL=databases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"databases.js","sourceRoot":"","sources":["../../src/tools/databases.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AppFlowy MCP Server - Document Tools
3
+ * MCP tools for document/page management
4
+ */
5
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
+ export declare function registerDocumentTools(server: McpServer): void;
7
+ //# sourceMappingURL=documents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/tools/documents.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QA4LtD"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * AppFlowy MCP Server - Document Tools
3
+ * MCP tools for document/page management
4
+ */
5
+ import { z } from 'zod';
6
+ import { appflowyClient } from '../services/appflowy-client.js';
7
+ export function registerDocumentTools(server) {
8
+ // Tool: List documents
9
+ server.tool('appflowy_list_documents', `List all documents/pages in a workspace or folder.
10
+
11
+ Can list root-level documents or documents inside a specific folder (parent_view_id).
12
+
13
+ Args:
14
+ - workspace_id: The workspace ID
15
+ - parent_view_id (optional): Folder ID to list contents inside`, {
16
+ workspace_id: z.string().describe('The workspace ID'),
17
+ parent_view_id: z.string().optional().describe('Parent folder/view ID (optional)'),
18
+ }, async ({ workspace_id, parent_view_id }) => {
19
+ try {
20
+ const docs = await appflowyClient.listDocuments(workspace_id, parent_view_id);
21
+ if (docs.length === 0) {
22
+ return {
23
+ content: [{ type: 'text', text: 'No documents found.' }],
24
+ };
25
+ }
26
+ const lines = [`# Documents${parent_view_id ? ' in folder' : ''}\n`];
27
+ for (const doc of docs) {
28
+ const icon = doc.icon || getLayoutIcon(doc.layout);
29
+ lines.push(`${icon} **${doc.name}**`);
30
+ lines.push(` ID: ${doc.view_id} | Type: ${doc.layout}`);
31
+ if (doc.last_edited_time) {
32
+ lines.push(` Last edited: ${doc.last_edited_time}`);
33
+ }
34
+ lines.push('');
35
+ }
36
+ return {
37
+ content: [{ type: 'text', text: lines.join('\n') }],
38
+ };
39
+ }
40
+ catch (error) {
41
+ return {
42
+ content: [{ type: 'text', text: `āŒ Error listing documents: ${error.message}` }],
43
+ isError: true,
44
+ };
45
+ }
46
+ });
47
+ // Tool: Read document
48
+ server.tool('appflowy_read_document', `Read the full content of a document/page from AppFlowy.
49
+
50
+ Returns the document metadata and text content extracted from blocks.
51
+
52
+ Args:
53
+ - workspace_id: The workspace ID
54
+ - document_id: The document/view ID`, {
55
+ workspace_id: z.string().describe('The workspace ID'),
56
+ document_id: z.string().describe('The document/view ID'),
57
+ }, async ({ workspace_id, document_id }) => {
58
+ try {
59
+ const [docMeta, content] = await Promise.all([
60
+ appflowyClient.getDocument(workspace_id, document_id),
61
+ appflowyClient.getDocumentContent(workspace_id, document_id),
62
+ ]);
63
+ let textContent = '';
64
+ if (content?.blocks) {
65
+ textContent = extractTextFromBlocks(content.blocks);
66
+ }
67
+ const lines = [`# ${docMeta.name}\n`];
68
+ lines.push(`**ID**: ${docMeta.view_id}`);
69
+ lines.push(`**Type**: ${docMeta.layout}`);
70
+ lines.push(`**Created**: ${docMeta.created_at}`);
71
+ if (docMeta.last_edited_time)
72
+ lines.push(`**Last edited**: ${docMeta.last_edited_time}`);
73
+ lines.push('');
74
+ lines.push('---');
75
+ lines.push('');
76
+ lines.push(textContent || '*Document is empty or contains unsupported content.*');
77
+ return {
78
+ content: [{ type: 'text', text: lines.join('\n') }],
79
+ };
80
+ }
81
+ catch (error) {
82
+ return {
83
+ content: [{ type: 'text', text: `āŒ Error reading document: ${error.message}` }],
84
+ isError: true,
85
+ };
86
+ }
87
+ });
88
+ // Tool: Create document
89
+ server.tool('appflowy_create_document', `Create a new document/page in AppFlowy.
90
+
91
+ Args:
92
+ - workspace_id: The workspace ID
93
+ - name: Document name/title
94
+ - parent_view_id (optional): Folder ID to place document inside`, {
95
+ workspace_id: z.string().describe('The workspace ID'),
96
+ name: z.string().min(1).max(200).describe('Document name/title'),
97
+ parent_view_id: z.string().optional().describe('Parent folder ID (optional)'),
98
+ }, async ({ workspace_id, name, parent_view_id }) => {
99
+ try {
100
+ const doc = await appflowyClient.createDocument(workspace_id, name, parent_view_id);
101
+ return {
102
+ content: [
103
+ {
104
+ type: 'text',
105
+ text: `āœ… Document created: **${doc.name}**\n\n- ID: ${doc.view_id}\n- Type: ${doc.layout}\n- Created: ${doc.created_at}`,
106
+ },
107
+ ],
108
+ };
109
+ }
110
+ catch (error) {
111
+ return {
112
+ content: [{ type: 'text', text: `āŒ Error creating document: ${error.message}` }],
113
+ isError: true,
114
+ };
115
+ }
116
+ });
117
+ // Tool: Delete document
118
+ server.tool('appflowy_delete_document', `āš ļø Delete a document/page from AppFlowy. This action cannot be undone!
119
+
120
+ Args:
121
+ - workspace_id: The workspace ID
122
+ - document_id: The document/view ID to delete`, {
123
+ workspace_id: z.string().describe('The workspace ID'),
124
+ document_id: z.string().describe('The document/view ID to delete'),
125
+ }, async ({ workspace_id, document_id }) => {
126
+ try {
127
+ await appflowyClient.deleteDocument(workspace_id, document_id);
128
+ return {
129
+ content: [{ type: 'text', text: 'šŸ—‘ļø Document deleted successfully.' }],
130
+ };
131
+ }
132
+ catch (error) {
133
+ return {
134
+ content: [{ type: 'text', text: `āŒ Error deleting document: ${error.message}` }],
135
+ isError: true,
136
+ };
137
+ }
138
+ });
139
+ // Tool: Duplicate document
140
+ server.tool('appflowy_duplicate_document', `Duplicate/clone an existing document/page.
141
+
142
+ Args:
143
+ - workspace_id: The workspace ID
144
+ - document_id: The document/view ID to duplicate`, {
145
+ workspace_id: z.string().describe('The workspace ID'),
146
+ document_id: z.string().describe('The document/view ID to duplicate'),
147
+ }, async ({ workspace_id, document_id }) => {
148
+ try {
149
+ const doc = await appflowyClient.duplicateDocument(workspace_id, document_id);
150
+ return {
151
+ content: [
152
+ {
153
+ type: 'text',
154
+ text: `šŸ“„ Document duplicated: **${doc.name}**\n\n- New ID: ${doc.view_id}\n- Original ID: ${document_id}`,
155
+ },
156
+ ],
157
+ };
158
+ }
159
+ catch (error) {
160
+ return {
161
+ content: [{ type: 'text', text: `āŒ Error duplicating document: ${error.message}` }],
162
+ isError: true,
163
+ };
164
+ }
165
+ });
166
+ }
167
+ // Helper: Get icon for document layout
168
+ function getLayoutIcon(layout) {
169
+ const icons = {
170
+ Document: 'šŸ“„',
171
+ Grid: 'šŸ“Š',
172
+ Board: 'šŸ“‹',
173
+ Calendar: 'šŸ“…',
174
+ Gallery: 'šŸ–¼ļø',
175
+ Chat: 'šŸ’¬',
176
+ };
177
+ return icons[layout] || 'šŸ“„';
178
+ }
179
+ // Helper: Extract text from document blocks recursively
180
+ function extractTextFromBlocks(blocks) {
181
+ const texts = [];
182
+ for (const block of blocks) {
183
+ if (block.data?.text) {
184
+ texts.push(block.data.text);
185
+ }
186
+ if (block.data?.url && block.type === 'file') {
187
+ texts.push(`[File: ${block.data.name || 'attachment'} (${block.data.file_type || 'unknown'})]`);
188
+ }
189
+ if (block.children?.length) {
190
+ const childTexts = extractTextFromBlocks(block.children);
191
+ if (childTexts)
192
+ texts.push(childTexts);
193
+ }
194
+ }
195
+ return texts.join('\n');
196
+ }
197
+ //# sourceMappingURL=documents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.js","sourceRoot":"","sources":["../../src/tools/documents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AppFlowy MCP Server - File/Attachment Tools
3
+ * MCP tools for uploading, downloading, and managing file attachments
4
+ */
5
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
+ export declare function registerFileTools(server: McpServer): void;
7
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/tools/files.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,QAmNlD"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * AppFlowy MCP Server - File/Attachment Tools
3
+ * MCP tools for uploading, downloading, and managing file attachments
4
+ */
5
+ import { z } from 'zod';
6
+ import { appflowyClient } from '../services/appflowy-client.js';
7
+ import { existsSync } from 'fs';
8
+ import { writeFileSync } from 'fs';
9
+ import { resolve } from 'path';
10
+ export function registerFileTools(server) {
11
+ // Tool: Upload file
12
+ server.tool('appflowy_upload_file', `Upload a file from your local machine to AppFlowy Cloud storage.
13
+
14
+ The file will be stored in your workspace and can be attached to documents.
15
+
16
+ Args:
17
+ - workspace_id: The workspace ID
18
+ - file_path: Absolute path to the local file
19
+ - parent_dir (optional): Storage directory (default: 'attachments')
20
+
21
+ Supported file types: images, documents, PDFs, code files, etc.
22
+ Max file size: configurable via APPFLOWY_MAX_FILE_SIZE_MB env var (default: 50MB)`, {
23
+ workspace_id: z.string().describe('The workspace ID'),
24
+ file_path: z.string().describe('Absolute path to the local file'),
25
+ parent_dir: z.string().default('attachments').describe('Storage directory name'),
26
+ }, async ({ workspace_id, file_path, parent_dir }) => {
27
+ try {
28
+ const resolvedPath = resolve(file_path);
29
+ if (!existsSync(resolvedPath)) {
30
+ return {
31
+ content: [{ type: 'text', text: `āŒ File not found: ${resolvedPath}` }],
32
+ isError: true,
33
+ };
34
+ }
35
+ const result = await appflowyClient.uploadFile(workspace_id, resolvedPath, parent_dir);
36
+ return {
37
+ content: [
38
+ {
39
+ type: 'text',
40
+ text: `āœ… File uploaded successfully!\n\nšŸ“Ž **${result.name}**\n- File ID: ${result.file_id}\n- Size: ${formatFileSize(result.size)}\n- Type: ${result.mime_type}\n- URL: ${result.url}\n- Storage: ${parent_dir}/`,
41
+ },
42
+ ],
43
+ };
44
+ }
45
+ catch (error) {
46
+ return {
47
+ content: [{ type: 'text', text: `āŒ Upload error: ${error.message}` }],
48
+ isError: true,
49
+ };
50
+ }
51
+ });
52
+ // Tool: Download file
53
+ server.tool('appflowy_download_file', `Download a file from AppFlowy Cloud storage to your local machine.
54
+
55
+ Args:
56
+ - workspace_id: The workspace ID
57
+ - file_id: The file ID (from upload or list_files)
58
+ - output_path: Absolute path where to save the file
59
+ - parent_dir (optional): Storage directory (default: 'attachments')`, {
60
+ workspace_id: z.string().describe('The workspace ID'),
61
+ file_id: z.string().describe('The file ID'),
62
+ output_path: z.string().describe('Absolute path to save the file'),
63
+ parent_dir: z.string().default('attachments').describe('Storage directory name'),
64
+ }, async ({ workspace_id, file_id, output_path, parent_dir }) => {
65
+ try {
66
+ const buffer = await appflowyClient.downloadFile(workspace_id, file_id, parent_dir);
67
+ const resolvedPath = resolve(output_path);
68
+ writeFileSync(resolvedPath, buffer);
69
+ return {
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: `āœ… File downloaded successfully!\n\nšŸ“„ Saved to: ${resolvedPath}\n- Size: ${formatFileSize(buffer.length)}`,
74
+ },
75
+ ],
76
+ };
77
+ }
78
+ catch (error) {
79
+ return {
80
+ content: [{ type: 'text', text: `āŒ Download error: ${error.message}` }],
81
+ isError: true,
82
+ };
83
+ }
84
+ });
85
+ // Tool: List files
86
+ server.tool('appflowy_list_files', `List all files in a workspace storage directory.
87
+
88
+ Args:
89
+ - workspace_id: The workspace ID
90
+ - parent_dir (optional): Storage directory (default: 'attachments')`, {
91
+ workspace_id: z.string().describe('The workspace ID'),
92
+ parent_dir: z.string().default('attachments').describe('Storage directory name'),
93
+ }, async ({ workspace_id, parent_dir }) => {
94
+ try {
95
+ const files = await appflowyClient.listFiles(workspace_id, parent_dir);
96
+ if (files.length === 0) {
97
+ return {
98
+ content: [{ type: 'text', text: `No files found in ${parent_dir}/` }],
99
+ };
100
+ }
101
+ const lines = [`# Files in ${parent_dir}/\n`];
102
+ for (const file of files) {
103
+ lines.push(`šŸ“Ž **${file.file_id}**`);
104
+ lines.push(` URL: ${file.url}`);
105
+ lines.push('');
106
+ }
107
+ return {
108
+ content: [{ type: 'text', text: lines.join('\n') }],
109
+ };
110
+ }
111
+ catch (error) {
112
+ return {
113
+ content: [{ type: 'text', text: `āŒ Error listing files: ${error.message}` }],
114
+ isError: true,
115
+ };
116
+ }
117
+ });
118
+ // Tool: Delete file
119
+ server.tool('appflowy_delete_file', `āš ļø Delete a file from AppFlowy Cloud storage. This action cannot be undone!
120
+
121
+ Args:
122
+ - workspace_id: The workspace ID
123
+ - file_id: The file ID to delete
124
+ - parent_dir (optional): Storage directory (default: 'attachments')`, {
125
+ workspace_id: z.string().describe('The workspace ID'),
126
+ file_id: z.string().describe('The file ID to delete'),
127
+ parent_dir: z.string().default('attachments').describe('Storage directory name'),
128
+ }, async ({ workspace_id, file_id, parent_dir }) => {
129
+ try {
130
+ await appflowyClient.deleteFile(workspace_id, file_id, parent_dir);
131
+ return {
132
+ content: [{ type: 'text', text: `šŸ—‘ļø File ${file_id} deleted successfully.` }],
133
+ };
134
+ }
135
+ catch (error) {
136
+ return {
137
+ content: [{ type: 'text', text: `āŒ Error deleting file: ${error.message}` }],
138
+ isError: true,
139
+ };
140
+ }
141
+ });
142
+ // Tool: Attach file to document
143
+ server.tool('appflowy_attach_file_to_document', `Attach an uploaded file to a specific document/page in AppFlowy.
144
+
145
+ This inserts a file block into the document so the file appears inline.
146
+
147
+ Args:
148
+ - workspace_id: The workspace ID
149
+ - document_id: The document/view ID
150
+ - file_id: The uploaded file ID
151
+ - parent_dir (optional): Storage directory (default: 'attachments')`, {
152
+ workspace_id: z.string().describe('The workspace ID'),
153
+ document_id: z.string().describe('The document/view ID'),
154
+ file_id: z.string().describe('The uploaded file ID'),
155
+ parent_dir: z.string().default('attachments').describe('Storage directory name'),
156
+ }, async ({ workspace_id, document_id, file_id, parent_dir }) => {
157
+ try {
158
+ // Get file metadata
159
+ const metadata = await appflowyClient.getFileMetadata(workspace_id, file_id, parent_dir);
160
+ // Create upload result object
161
+ const uploadResult = {
162
+ file_id,
163
+ url: metadata.url || '',
164
+ name: metadata.file_name,
165
+ size: metadata.file_size,
166
+ mime_type: metadata.mime_type,
167
+ created_at: metadata.created_at,
168
+ };
169
+ await appflowyClient.attachFileToDocument(workspace_id, document_id, uploadResult, parent_dir);
170
+ return {
171
+ content: [
172
+ {
173
+ type: 'text',
174
+ text: `āœ… File attached to document!\n\nšŸ“Ž **${metadata.file_name}**\n- Document ID: ${document_id}\n- File ID: ${file_id}\n- Size: ${formatFileSize(metadata.file_size)}`,
175
+ },
176
+ ],
177
+ };
178
+ }
179
+ catch (error) {
180
+ return {
181
+ content: [{ type: 'text', text: `āŒ Error attaching file: ${error.message}` }],
182
+ isError: true,
183
+ };
184
+ }
185
+ });
186
+ }
187
+ // Helper: Format file size
188
+ function formatFileSize(bytes) {
189
+ if (bytes === 0)
190
+ return '0 B';
191
+ const k = 1024;
192
+ const sizes = ['B', 'KB', 'MB', 'GB'];
193
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
194
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
195
+ }
196
+ //# sourceMappingURL=files.js.map