diff --git a/.claude/settings.local.json b/.claude/settings.local.json index c8f31a9..1dfbebb 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -2,7 +2,8 @@ "permissions": { "allow": [ "Bash(npm run:*)", - "Bash(npm help)" + "Bash(npm help)", + "Bash(git checkout:*)" ], "deny": [], "ask": [] diff --git a/src/index.ts b/src/index.ts index e690205..9a0afce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -609,14 +609,14 @@ class AppwriteMCPServer { const dbId = databaseId || ID.unique(); const database = await this.databases.create(dbId, name); return { - content: [{ type: "text", text: `Database created successfully:\\n- ID: ${database.$id}\\n- Name: ${database.name}\\n- Created: ${database.$createdAt}` }] + content: [{ type: "text", text: `Database created successfully:\n- ID: ${database.$id}\n- Name: ${database.name}\n- Created: ${database.$createdAt}` }] }; case "list": const databases = await this.databases.list(); - const dbList = databases.databases.map(db => `- ${db.name} (${db.$id})`).join('\\n'); + const dbList = databases.databases.map(db => `- ${db.name} (${db.$id})`).join('\n'); return { - content: [{ type: "text", text: `Databases (${databases.total}):\\n${dbList}` }] + content: [{ type: "text", text: `Databases (${databases.total}):\n${dbList}` }] }; case "delete": @@ -642,21 +642,21 @@ class AppwriteMCPServer { const colId = collectionId || ID.unique(); const collection = await this.databases.createCollection(databaseId, colId, name, permissions); return { - content: [{ type: "text", text: `Collection created successfully:\\n- ID: ${collection.$id}\\n- Name: ${collection.name}\\n- Database: ${collection.databaseId}` }] + content: [{ type: "text", text: `Collection created successfully:\n- ID: ${collection.$id}\n- Name: ${collection.name}\n- Database: ${collection.databaseId}` }] }; case "get": if (!collectionId) throw new Error("collectionId is required for get action"); const getCollection = await this.databases.getCollection(databaseId, collectionId); return { - content: [{ type: "text", text: `Collection Details:\\n- ID: ${getCollection.$id}\\n- Name: ${getCollection.name}\\n- Attributes: ${getCollection.attributes.length}\\n- Indexes: ${getCollection.indexes.length}` }] + content: [{ type: "text", text: `Collection Details:\n- ID: ${getCollection.$id}\n- Name: ${getCollection.name}\n- Attributes: ${getCollection.attributes.length}\n- Indexes: ${getCollection.indexes.length}` }] }; case "list": const collections = await this.databases.listCollections(databaseId); - const colList = collections.collections.map(col => `- ${col.name} (${col.$id})`).join('\\n'); + const colList = collections.collections.map(col => `- ${col.name} (${col.$id})`).join('\n'); return { - content: [{ type: "text", text: `Collections in database ${databaseId} (${collections.total}):\\n${colList}` }] + content: [{ type: "text", text: `Collections in database ${databaseId} (${collections.total}):\n${colList}` }] }; case "update": @@ -664,7 +664,7 @@ class AppwriteMCPServer { if (!name) throw new Error("Name is required for update action"); const updatedCollection = await this.databases.updateCollection(databaseId, collectionId, name, permissions); return { - content: [{ type: "text", text: `Collection updated successfully:\\n- ID: ${updatedCollection.$id}\\n- Name: ${updatedCollection.name}` }] + content: [{ type: "text", text: `Collection updated successfully:\n- ID: ${updatedCollection.$id}\n- Name: ${updatedCollection.name}` }] }; case "delete": @@ -729,21 +729,21 @@ class AppwriteMCPServer { throw new Error(`Unknown attribute type: ${type}`); } return { - content: [{ type: "text", text: `Attribute '${key}' created successfully:\\n- Type: ${type}\\n- Required: ${required}\\n- Key: ${result.key}` }] + content: [{ type: "text", text: `Attribute '${key}' created successfully:\n- Type: ${type}\n- Required: ${required}\n- Key: ${result.key}` }] }; case "get": if (!key) throw new Error("key is required for get action"); const attribute = await this.databases.getAttribute(databaseId, collectionId, key); return { - content: [{ type: "text", text: `Attribute Details:\\n- Key: ${(attribute as any).key}\\n- Type: ${(attribute as any).type}\\n- Required: ${(attribute as any).required}\\n- Status: ${(attribute as any).status}` }] + content: [{ type: "text", text: `Attribute Details:\n- Key: ${(attribute as any).key}\n- Type: ${(attribute as any).type}\n- Required: ${(attribute as any).required}\n- Status: ${(attribute as any).status}` }] }; case "list": const attributesList = await this.databases.listAttributes(databaseId, collectionId); - const attrList = attributesList.attributes.map((attr: any) => `- ${attr.key} (${attr.type})`).join('\\n'); + const attrList = attributesList.attributes.map((attr: any) => `- ${attr.key} (${attr.type})`).join('\n'); return { - content: [{ type: "text", text: `Attributes in collection ${collectionId} (${attributesList.total}):\\n${attrList}` }] + content: [{ type: "text", text: `Attributes in collection ${collectionId} (${attributesList.total}):\n${attrList}` }] }; case "update": @@ -784,7 +784,7 @@ class AppwriteMCPServer { throw new Error(`Attribute type ${type} cannot be updated or is not supported`); } return { - content: [{ type: "text", text: `Attribute '${key}' updated successfully:\\n- Type: ${type}\\n- Required: ${required}` }] + content: [{ type: "text", text: `Attribute '${key}' updated successfully:\n- Type: ${type}\n- Required: ${required}` }] }; case "delete": @@ -813,7 +813,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk attribute creation results:\\n${createResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk attribute creation results:\n${createResults.join('\n')}` }] }; case "bulk_delete": @@ -830,7 +830,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk attribute deletion results:\\n${deleteResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk attribute deletion results:\n${deleteResults.join('\n')}` }] }; default: @@ -850,21 +850,21 @@ class AppwriteMCPServer { } const index = await this.databases.createIndex(databaseId, collectionId, key, type as IndexType, attributes); return { - content: [{ type: "text", text: `Index '${key}' created successfully:\\n- Type: ${type}\\n- Attributes: ${attributes.join(', ')}\\n- Key: ${index.key}` }] + content: [{ type: "text", text: `Index '${key}' created successfully:\n- Type: ${type}\n- Attributes: ${attributes.join(', ')}\n- Key: ${index.key}` }] }; case "get": if (!key) throw new Error("key is required for get action"); const getIndex = await this.databases.getIndex(databaseId, collectionId, key); return { - content: [{ type: "text", text: `Index Details:\\n- Key: ${getIndex.key}\\n- Type: ${getIndex.type}\\n- Attributes: ${getIndex.attributes.join(', ')}\\n- Status: ${getIndex.status}` }] + content: [{ type: "text", text: `Index Details:\n- Key: ${getIndex.key}\n- Type: ${getIndex.type}\n- Attributes: ${getIndex.attributes.join(', ')}\n- Status: ${getIndex.status}` }] }; case "list": const indexes = await this.databases.listIndexes(databaseId, collectionId); - const indexList = indexes.indexes.map(idx => `- ${idx.key} (${idx.type}) - [${idx.attributes.join(', ')}]`).join('\\n'); + const indexList = indexes.indexes.map(idx => `- ${idx.key} (${idx.type}) - [${idx.attributes.join(', ')}]`).join('\n'); return { - content: [{ type: "text", text: `Indexes in collection ${collectionId} (${indexes.total}):\\n${indexList}` }] + content: [{ type: "text", text: `Indexes in collection ${collectionId} (${indexes.total}):\n${indexList}` }] }; case "delete": @@ -890,21 +890,21 @@ class AppwriteMCPServer { const docId = documentId || ID.unique(); const document = await this.databases.createDocument(databaseId, collectionId, docId, data, permissions); return { - content: [{ type: "text", text: `Document created successfully:\\n- ID: ${document.$id}\\n- Collection: ${document.$collectionId}\\n- Created: ${document.$createdAt}` }] + content: [{ type: "text", text: `Document created successfully:\n- ID: ${document.$id}\n- Collection: ${document.$collectionId}\n- Created: ${document.$createdAt}` }] }; case "get": if (!documentId) throw new Error("documentId is required for get action"); const getDocument = await this.databases.getDocument(databaseId, collectionId, documentId); return { - content: [{ type: "text", text: `Document Details:\\n- ID: ${getDocument.$id}\\n- Collection: ${getDocument.$collectionId}\\n- Updated: ${getDocument.$updatedAt}\\n- Data: ${JSON.stringify(getDocument, null, 2)}` }] + content: [{ type: "text", text: `Document Details:\n- ID: ${getDocument.$id}\n- Collection: ${getDocument.$collectionId}\n- Updated: ${getDocument.$updatedAt}\n- Data: ${JSON.stringify(getDocument, null, 2)}` }] }; case "update": if (!documentId || !data) throw new Error("documentId and data are required for update action"); const updatedDocument = await this.databases.updateDocument(databaseId, collectionId, documentId, data, permissions); return { - content: [{ type: "text", text: `Document updated successfully:\\n- ID: ${updatedDocument.$id}\\n- Updated: ${updatedDocument.$updatedAt}` }] + content: [{ type: "text", text: `Document updated successfully:\n- ID: ${updatedDocument.$id}\n- Updated: ${updatedDocument.$updatedAt}` }] }; case "delete": @@ -929,7 +929,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk document creation results:\\n${createResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk document creation results:\n${createResults.join('\n')}` }] }; case "bulk_update": @@ -946,7 +946,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk document update results:\\n${updateResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk document update results:\n${updateResults.join('\n')}` }] }; case "bulk_delete": @@ -963,7 +963,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk document deletion results:\\n${deleteResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk document deletion results:\n${deleteResults.join('\n')}` }] }; default: @@ -977,9 +977,9 @@ class AppwriteMCPServer { const { databaseId, collectionId, queries, limit, offset } = args; const documents = await this.databases.listDocuments(databaseId, collectionId, queries || []); - const docList = documents.documents.map(doc => `- ${doc.$id} (updated: ${doc.$updatedAt})`).join('\\n'); + const docList = documents.documents.map(doc => `- ${doc.$id} (updated: ${doc.$updatedAt})`).join('\n'); return { - content: [{ type: "text", text: `Documents in collection ${collectionId} (${documents.total}):\\n${docList}` }] + content: [{ type: "text", text: `Documents in collection ${collectionId} (${documents.total}):\n${docList}` }] }; } @@ -993,14 +993,14 @@ class AppwriteMCPServer { if (!email || !password) throw new Error("email and password are required for create action"); const user = await this.users.create(userId || ID.unique(), email, phone, password, name); return { - content: [{ type: "text", text: `User created successfully:\\n- ID: ${user.$id}\\n- Email: ${user.email}\\n- Name: ${user.name || 'N/A'}\\n- Status: ${user.status}` }] + content: [{ type: "text", text: `User created successfully:\n- ID: ${user.$id}\n- Email: ${user.email}\n- Name: ${user.name || 'N/A'}\n- Status: ${user.status}` }] }; case "get": if (!userId) throw new Error("userId is required for get action"); const getUser = await this.users.get(userId); return { - content: [{ type: "text", text: `User Details:\\n- ID: ${getUser.$id}\\n- Email: ${getUser.email}\\n- Name: ${getUser.name || 'N/A'}\\n- Status: ${getUser.status}\\n- Registration: ${getUser.registration}` }] + content: [{ type: "text", text: `User Details:\n- ID: ${getUser.$id}\n- Email: ${getUser.email}\n- Name: ${getUser.name || 'N/A'}\n- Status: ${getUser.status}\n- Registration: ${getUser.registration}` }] }; case "update": @@ -1023,13 +1023,13 @@ class AppwriteMCPServer { if (!userId || !prefs) throw new Error("userId and prefs are required for update_preferences action"); const updatedPrefs = await this.users.updatePrefs(userId, prefs); return { - content: [{ type: "text", text: `User preferences updated successfully:\\n${JSON.stringify(updatedPrefs.prefs, null, 2)}` }] + content: [{ type: "text", text: `User preferences updated successfully:\n${JSON.stringify(updatedPrefs.prefs, null, 2)}` }] }; case "update_labels": if (!userId || !labels) throw new Error("userId and labels are required for update_labels action"); const updatedUserLabels = await this.users.updateLabels(userId, labels); return { - content: [{ type: "text", text: `User labels updated successfully:\\n- User ID: ${updatedUserLabels.$id}\\n- Labels: ${updatedUserLabels.labels.join(', ')}` }] + content: [{ type: "text", text: `User labels updated successfully:\n- User ID: ${updatedUserLabels.$id}\n- Labels: ${updatedUserLabels.labels.join(', ')}` }] }; case "bulk_create": @@ -1052,7 +1052,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk user creation results:\\n${createResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk user creation results:\n${createResults.join('\n')}` }] }; case "bulk_update": @@ -1071,7 +1071,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk user update results:\\n${updateResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk user update results:\n${updateResults.join('\n')}` }] }; case "bulk_delete": @@ -1088,7 +1088,7 @@ class AppwriteMCPServer { } } return { - content: [{ type: "text", text: `Bulk user deletion results:\\n${deleteResults.join('\\n')}` }] + content: [{ type: "text", text: `Bulk user deletion results:\n${deleteResults.join('\n')}` }] }; default: @@ -1102,9 +1102,9 @@ class AppwriteMCPServer { const { queries, limit, offset } = args; const users = await this.users.list(); - const userList = users.users.map(user => `- ${user.email} (${user.$id}) - ${user.status}`).join('\\n'); + const userList = users.users.map(user => `- ${user.email} (${user.$id}) - ${user.status}`).join('\n'); return { - content: [{ type: "text", text: `Users (${users.total}):\\n${userList}` }] + content: [{ type: "text", text: `Users (${users.total}):\n${userList}` }] }; } @@ -1118,28 +1118,28 @@ class AppwriteMCPServer { if (!name) throw new Error("name is required for create action"); const bucket = await this.storage.createBucket(bucketId || ID.unique(), name, permissions, fileSecurity, enabled); return { - content: [{ type: "text", text: `Bucket created successfully:\\n- ID: ${bucket.$id}\\n- Name: ${bucket.name}\\n- Enabled: ${bucket.enabled}` }] + content: [{ type: "text", text: `Bucket created successfully:\n- ID: ${bucket.$id}\n- Name: ${bucket.name}\n- Enabled: ${bucket.enabled}` }] }; case "get": if (!bucketId) throw new Error("bucketId is required for get action"); const getBucket = await this.storage.getBucket(bucketId); return { - content: [{ type: "text", text: `Bucket Details:\\n- ID: ${getBucket.$id}\\n- Name: ${getBucket.name}\\n- Enabled: ${getBucket.enabled}\\n- File Security: ${getBucket.fileSecurity}` }] + content: [{ type: "text", text: `Bucket Details:\n- ID: ${getBucket.$id}\n- Name: ${getBucket.name}\n- Enabled: ${getBucket.enabled}\n- File Security: ${getBucket.fileSecurity}` }] }; case "list": const buckets = await this.storage.listBuckets(); - const bucketList = buckets.buckets.map(bucket => `- ${bucket.name} (${bucket.$id}) - ${bucket.enabled ? 'enabled' : 'disabled'}`).join('\\n'); + const bucketList = buckets.buckets.map(bucket => `- ${bucket.name} (${bucket.$id}) - ${bucket.enabled ? 'enabled' : 'disabled'}`).join('\n'); return { - content: [{ type: "text", text: `Storage Buckets (${buckets.total}):\\n${bucketList}` }] + content: [{ type: "text", text: `Storage Buckets (${buckets.total}):\n${bucketList}` }] }; case "update": if (!bucketId || !name) throw new Error("bucketId and name are required for update action"); const updatedBucket = await this.storage.updateBucket(bucketId, name, permissions, fileSecurity, enabled); return { - content: [{ type: "text", text: `Bucket updated successfully:\\n- ID: ${updatedBucket.$id}\\n- Name: ${updatedBucket.name}` }] + content: [{ type: "text", text: `Bucket updated successfully:\n- ID: ${updatedBucket.$id}\n- Name: ${updatedBucket.name}` }] }; case "delete": @@ -1164,7 +1164,7 @@ class AppwriteMCPServer { if (!fileId) throw new Error("fileId is required for get action"); const file = await this.storage.getFile(bucketId, fileId); return { - content: [{ type: "text", text: `File Details:\\n- ID: ${file.$id}\\n- Name: ${file.name}\\n- Size: ${file.sizeOriginal} bytes\\n- Type: ${file.mimeType}\\n- Created: ${file.$createdAt}` }] + content: [{ type: "text", text: `File Details:\n- ID: ${file.$id}\n- Name: ${file.name}\n- Size: ${file.sizeOriginal} bytes\n- Type: ${file.mimeType}\n- Created: ${file.$createdAt}` }] }; case "create": @@ -1175,14 +1175,14 @@ class AppwriteMCPServer { const inputFile = InputFile.fromBuffer(fileBuffer, filePath.split('/').pop() || 'file'); const createdFile = await this.storage.createFile(bucketId, fileId || ID.unique(), inputFile, permissions); return { - content: [{ type: "text", text: `File uploaded successfully:\\n- ID: ${createdFile.$id}\\n- Name: ${createdFile.name}\\n- Size: ${createdFile.sizeOriginal} bytes` }] + content: [{ type: "text", text: `File uploaded successfully:\n- ID: ${createdFile.$id}\n- Name: ${createdFile.name}\n- Size: ${createdFile.sizeOriginal} bytes` }] }; case "update": if (!fileId) throw new Error("fileId is required for update action"); const updatedFile = await this.storage.updateFile(bucketId, fileId, name, permissions); return { - content: [{ type: "text", text: `File updated successfully:\\n- ID: ${updatedFile.$id}\\n- Name: ${updatedFile.name}` }] + content: [{ type: "text", text: `File updated successfully:\n- ID: ${updatedFile.$id}\n- Name: ${updatedFile.name}` }] }; case "delete": @@ -1194,9 +1194,9 @@ class AppwriteMCPServer { case "list": const files = await this.storage.listFiles(bucketId); - const fileList = files.files.map(file => `- ${file.name} (${file.$id}) - ${file.sizeOriginal} bytes`).join('\\n'); + const fileList = files.files.map(file => `- ${file.name} (${file.$id}) - ${file.sizeOriginal} bytes`).join('\n'); return { - content: [{ type: "text", text: `Files in bucket ${bucketId} (${files.total}):\\n${fileList}` }] + content: [{ type: "text", text: `Files in bucket ${bucketId} (${files.total}):\n${fileList}` }] }; default: @@ -1229,7 +1229,7 @@ class AppwriteMCPServer { } return { - content: [{ type: "text", text: `File URL (${type}):\\n${url}` }] + content: [{ type: "text", text: `File URL (${type}):\n${url}` }] }; } @@ -1243,28 +1243,28 @@ class AppwriteMCPServer { if (!name) throw new Error("name is required for create action"); const team = await this.teams.create(teamId || ID.unique(), name, roles); return { - content: [{ type: "text", text: `Team created successfully:\\n- ID: ${team.$id}\\n- Name: ${team.name}\\n- Total Members: ${team.total}` }] + content: [{ type: "text", text: `Team created successfully:\n- ID: ${team.$id}\n- Name: ${team.name}\n- Total Members: ${team.total}` }] }; case "get": if (!teamId) throw new Error("teamId is required for get action"); const getTeam = await this.teams.get(teamId); return { - content: [{ type: "text", text: `Team Details:\\n- ID: ${getTeam.$id}\\n- Name: ${getTeam.name}\\n- Total Members: ${getTeam.total}\\n- Created: ${getTeam.$createdAt}` }] + content: [{ type: "text", text: `Team Details:\n- ID: ${getTeam.$id}\n- Name: ${getTeam.name}\n- Total Members: ${getTeam.total}\n- Created: ${getTeam.$createdAt}` }] }; case "list": const teams = await this.teams.list(); - const teamList = teams.teams.map(team => `- ${team.name} (${team.$id}) - ${team.total} members`).join('\\n'); + const teamList = teams.teams.map(team => `- ${team.name} (${team.$id}) - ${team.total} members`).join('\n'); return { - content: [{ type: "text", text: `Teams (${teams.total}):\\n${teamList}` }] + content: [{ type: "text", text: `Teams (${teams.total}):\n${teamList}` }] }; case "update": if (!teamId || !name) throw new Error("teamId and name are required for update action"); const updatedTeam = await this.teams.updateName(teamId, name); return { - content: [{ type: "text", text: `Team updated successfully:\\n- ID: ${updatedTeam.$id}\\n- Name: ${updatedTeam.name}` }] + content: [{ type: "text", text: `Team updated successfully:\n- ID: ${updatedTeam.$id}\n- Name: ${updatedTeam.name}` }] }; case "delete": @@ -1399,7 +1399,7 @@ class AppwriteMCPServer { const health = await this.health.get(); return { - content: [{ type: "text", text: `Appwrite Health Status:\\n- Status: ${(health as any).status || 'OK'}\\n- Service: Available` }] + content: [{ type: "text", text: `Appwrite Health Status:\n- Status: ${(health as any).status || 'OK'}\n- Service: Available` }] }; }