bulk and auth functions

This commit is contained in:
2025-07-25 16:43:30 +03:00
parent cc50c64423
commit 62f7f125d3
2 changed files with 612 additions and 0 deletions

View File

@@ -19,6 +19,16 @@ A comprehensive Model Context Protocol (MCP) server that transforms Claude Code
- **Index optimization** suggestions
- **Schema migrations** with safety checks
**🔐 Advanced Authentication & Sessions:**
- **Session management** (create, delete, list user sessions)
- **Function execution** with logging and monitoring
- **Health monitoring** for all Appwrite services
**⚡ Bulk Operations:**
- **Bulk user management** (create, update, delete multiple users)
- **Bulk document operations** (create, update, delete multiple documents)
- **Efficient batch processing** with detailed success/error reporting
## Installation
1. Clone this repository:

View File

@@ -15,6 +15,8 @@ import {
Storage,
Functions,
Teams,
Account,
Health,
ID,
Query,
Permission,
@@ -39,6 +41,8 @@ class AppwriteMCPServer {
private storage: Storage | null = null;
private functions: Functions | null = null;
private teams: Teams | null = null;
private account: Account | null = null;
private health: Health | null = null;
private config: AppwriteConfig | null = null;
constructor() {
@@ -93,6 +97,8 @@ class AppwriteMCPServer {
this.storage = new Storage(this.client);
this.functions = new Functions(this.client);
this.teams = new Teams(this.client);
this.account = new Account(this.client);
this.health = new Health(this.client);
}
private setupToolHandlers(): void {
@@ -767,6 +773,239 @@ class AppwriteMCPServer {
},
required: ["databaseId"]
}
},
// Session Management
{
name: "create_session",
description: "Create a new user session with email and password",
inputSchema: {
type: "object",
properties: {
email: { type: "string", description: "User email" },
password: { type: "string", description: "User password" }
},
required: ["email", "password"]
}
},
{
name: "delete_session",
description: "Delete a user session",
inputSchema: {
type: "object",
properties: {
sessionId: { type: "string", description: "Session ID to delete" }
},
required: ["sessionId"]
}
},
{
name: "list_sessions",
description: "List all sessions for a user",
inputSchema: {
type: "object",
properties: {
userId: { type: "string", description: "User ID" }
},
required: ["userId"]
}
},
// Function Execution
{
name: "execute_function",
description: "Execute a function with optional data",
inputSchema: {
type: "object",
properties: {
functionId: { type: "string", description: "Function ID" },
data: { type: "string", description: "Data to pass to function (optional)" },
async: { type: "boolean", description: "Execute asynchronously (optional)", default: false }
},
required: ["functionId"]
}
},
{
name: "list_executions",
description: "List function executions with logs",
inputSchema: {
type: "object",
properties: {
functionId: { type: "string", description: "Function ID" },
limit: { type: "number", description: "Number of executions to return (optional, max 100)", default: 25 }
},
required: ["functionId"]
}
},
{
name: "get_execution",
description: "Get details of a specific function execution",
inputSchema: {
type: "object",
properties: {
functionId: { type: "string", description: "Function ID" },
executionId: { type: "string", description: "Execution ID" }
},
required: ["functionId", "executionId"]
}
},
// Health Monitoring
{
name: "get_health",
description: "Get overall health status of Appwrite services",
inputSchema: {
type: "object",
properties: {}
}
},
{
name: "get_health_db",
description: "Get database health status",
inputSchema: {
type: "object",
properties: {}
}
},
{
name: "get_health_storage",
description: "Get storage health status",
inputSchema: {
type: "object",
properties: {}
}
},
// Bulk Operations
{
name: "bulk_create_users",
description: "Create multiple users at once",
inputSchema: {
type: "object",
properties: {
users: {
type: "array",
description: "Array of user objects to create",
items: {
type: "object",
properties: {
userId: { type: "string", description: "User ID (optional)" },
email: { type: "string", description: "User email" },
password: { type: "string", description: "User password" },
name: { type: "string", description: "User name (optional)" }
},
required: ["email", "password"]
}
}
},
required: ["users"]
}
},
{
name: "bulk_update_users",
description: "Update multiple users at once",
inputSchema: {
type: "object",
properties: {
updates: {
type: "array",
description: "Array of user updates",
items: {
type: "object",
properties: {
userId: { type: "string", description: "User ID" },
email: { type: "string", description: "New email (optional)" },
name: { type: "string", description: "New name (optional)" },
password: { type: "string", description: "New password (optional)" }
},
required: ["userId"]
}
}
},
required: ["updates"]
}
},
{
name: "bulk_delete_users",
description: "Delete multiple users at once",
inputSchema: {
type: "object",
properties: {
userIds: {
type: "array",
description: "Array of user IDs to delete",
items: { type: "string" }
}
},
required: ["userIds"]
}
},
{
name: "bulk_create_documents",
description: "Create multiple documents at once",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
documents: {
type: "array",
description: "Array of documents to create",
items: {
type: "object",
properties: {
documentId: { type: "string", description: "Document ID (optional)" },
data: { type: "object", description: "Document data" },
permissions: { type: "array", description: "Document permissions (optional)", items: { type: "string" } }
},
required: ["data"]
}
}
},
required: ["databaseId", "collectionId", "documents"]
}
},
{
name: "bulk_update_documents",
description: "Update multiple documents at once",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
updates: {
type: "array",
description: "Array of document updates",
items: {
type: "object",
properties: {
documentId: { type: "string", description: "Document ID" },
data: { type: "object", description: "Updated document data" },
permissions: { type: "array", description: "Document permissions (optional)", items: { type: "string" } }
},
required: ["documentId", "data"]
}
}
},
required: ["databaseId", "collectionId", "updates"]
}
},
{
name: "bulk_delete_documents",
description: "Delete multiple documents at once",
inputSchema: {
type: "object",
properties: {
databaseId: { type: "string", description: "ID of the database" },
collectionId: { type: "string", description: "ID of the collection" },
documentIds: {
type: "array",
description: "Array of document IDs to delete",
items: { type: "string" }
}
},
required: ["databaseId", "collectionId", "documentIds"]
}
}
]
};
@@ -909,6 +1148,44 @@ class AppwriteMCPServer {
case "usage_stats":
return await this.usageStats(request.params.arguments);
// Session Management
case "create_session":
return await this.createSession(request.params.arguments);
case "delete_session":
return await this.deleteSession(request.params.arguments);
case "list_sessions":
return await this.listSessions(request.params.arguments);
// Function Execution
case "execute_function":
return await this.executeFunction(request.params.arguments);
case "list_executions":
return await this.listExecutions(request.params.arguments);
case "get_execution":
return await this.getExecution(request.params.arguments);
// Health Monitoring
case "get_health":
return await this.getHealth();
case "get_health_db":
return await this.getHealthDb();
case "get_health_storage":
return await this.getHealthStorage();
// Bulk Operations
case "bulk_create_users":
return await this.bulkCreateUsers(request.params.arguments);
case "bulk_update_users":
return await this.bulkUpdateUsers(request.params.arguments);
case "bulk_delete_users":
return await this.bulkDeleteUsers(request.params.arguments);
case "bulk_create_documents":
return await this.bulkCreateDocuments(request.params.arguments);
case "bulk_update_documents":
return await this.bulkUpdateDocuments(request.params.arguments);
case "bulk_delete_documents":
return await this.bulkDeleteDocuments(request.params.arguments);
default:
throw new McpError(
ErrorCode.MethodNotFound,
@@ -3163,6 +3440,331 @@ For accurate usage tracking, consider:
(avgSize / 1024).toFixed(1) + ' KB';
}
// Session Management
private async createSession(args: any) {
if (!this.account) throw new Error("Account service not initialized");
const { email, password } = args;
const session = await this.account.createEmailPasswordSession(email, password);
return {
content: [
{
type: "text",
text: `Session created successfully:\n- Session ID: ${session.$id}\n- User ID: ${session.userId}\n- Created: ${session.$createdAt}\n- Expires: ${session.expire}`
}
]
};
}
private async deleteSession(args: any) {
if (!this.account) throw new Error("Account service not initialized");
const { sessionId } = args;
await this.account.deleteSession(sessionId);
return {
content: [
{
type: "text",
text: `Session ${sessionId} deleted successfully`
}
]
};
}
private async listSessions(args: any) {
if (!this.users) throw new Error("Users service not initialized");
const { userId } = args;
const sessions = await this.users.listSessions(userId);
const sessionList = sessions.sessions.map((session: any) =>
`- ${session.$id} - Created: ${session.$createdAt} - Expires: ${session.expire}`
).join('\n');
return {
content: [
{
type: "text",
text: `Sessions for user ${userId} (${sessions.total}):\n${sessionList}`
}
]
};
}
// Function Execution
private async executeFunction(args: any) {
if (!this.functions) throw new Error("Functions service not initialized");
const { functionId, data, async } = args;
const execution = await this.functions.createExecution(functionId, data, async);
return {
content: [
{
type: "text",
text: `Function execution ${async ? 'started' : 'completed'}:\n- Execution ID: ${execution.$id}\n- Function ID: ${execution.functionId}\n- Status: ${execution.status}\n- Response: ${execution.responseBody || 'No response'}\n- Duration: ${execution.duration}ms`
}
]
};
}
private async listExecutions(args: any) {
if (!this.functions) throw new Error("Functions service not initialized");
const { functionId, limit = 25 } = args;
const executions = await this.functions.listExecutions(functionId, [Query.limit(limit)]);
const executionList = executions.executions.map((exec: any) =>
`- ${exec.$id} - Status: ${exec.status} - Duration: ${exec.duration}ms - Created: ${exec.$createdAt}`
).join('\n');
return {
content: [
{
type: "text",
text: `Function executions for ${functionId} (${executions.total}):\n${executionList}`
}
]
};
}
private async getExecution(args: any) {
if (!this.functions) throw new Error("Functions service not initialized");
const { functionId, executionId } = args;
const execution = await this.functions.getExecution(functionId, executionId);
return {
content: [
{
type: "text",
text: `Execution Details:\n${JSON.stringify(execution, null, 2)}`
}
]
};
}
// Health Monitoring
private async getHealth() {
if (!this.health) throw new Error("Health service not initialized");
const health = await this.health.get();
return {
content: [
{
type: "text",
text: `Health Status: ${health.status}\n- Ping: ${health.ping}ms`
}
]
};
}
private async getHealthDb() {
if (!this.health) throw new Error("Health service not initialized");
const health = await this.health.getDB();
return {
content: [
{
type: "text",
text: `Database Health: ${health.status}\n- Ping: ${health.ping}ms`
}
]
};
}
private async getHealthStorage() {
if (!this.health) throw new Error("Health service not initialized");
const health = await this.health.getStorage();
return {
content: [
{
type: "text",
text: `Storage Health: ${health.status}\n- Ping: ${health.ping}ms`
}
]
};
}
// Bulk Operations
private async bulkCreateUsers(args: any) {
if (!this.users) throw new Error("Users service not initialized");
const { users } = args;
const results = [];
const errors = [];
for (const user of users) {
try {
const { userId, email, password, name } = user;
const uid = userId || ID.unique();
const createdUser = await this.users.create(uid, email, password, name);
results.push(`${createdUser.email} (${createdUser.$id})`);
} catch (error) {
errors.push(`${user.email}: ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Bulk User Creation Results:\n\nSuccessful (${results.length}):\n${results.join('\n')}\n\nFailed (${errors.length}):\n${errors.join('\n')}`
}
]
};
}
private async bulkUpdateUsers(args: any) {
if (!this.users) throw new Error("Users service not initialized");
const { updates } = args;
const results = [];
const errors = [];
for (const update of updates) {
try {
const { userId, email, name, password } = update;
if (email) await this.users.updateEmail(userId, email);
if (name) await this.users.updateName(userId, name);
if (password) await this.users.updatePassword(userId, password);
results.push(`✅ User ${userId} updated`);
} catch (error) {
errors.push(`❌ User ${update.userId}: ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Bulk User Update Results:\n\nSuccessful (${results.length}):\n${results.join('\n')}\n\nFailed (${errors.length}):\n${errors.join('\n')}`
}
]
};
}
private async bulkDeleteUsers(args: any) {
if (!this.users) throw new Error("Users service not initialized");
const { userIds } = args;
const results = [];
const errors = [];
for (const userId of userIds) {
try {
await this.users.delete(userId);
results.push(`✅ User ${userId} deleted`);
} catch (error) {
errors.push(`❌ User ${userId}: ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Bulk User Deletion Results:\n\nSuccessful (${results.length}):\n${results.join('\n')}\n\nFailed (${errors.length}):\n${errors.join('\n')}`
}
]
};
}
private async bulkCreateDocuments(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, documents } = args;
const results = [];
const errors = [];
for (const doc of documents) {
try {
const { documentId, data, permissions } = doc;
const docId = documentId || ID.unique();
const createdDoc = await this.databases.createDocument(databaseId, collectionId, docId, data, permissions);
results.push(`✅ Document ${createdDoc.$id} created`);
} catch (error) {
errors.push(`❌ Document: ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Bulk Document Creation Results:\n\nSuccessful (${results.length}):\n${results.join('\n')}\n\nFailed (${errors.length}):\n${errors.join('\n')}`
}
]
};
}
private async bulkUpdateDocuments(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, updates } = args;
const results = [];
const errors = [];
for (const update of updates) {
try {
const { documentId, data, permissions } = update;
await this.databases.updateDocument(databaseId, collectionId, documentId, data, permissions);
results.push(`✅ Document ${documentId} updated`);
} catch (error) {
errors.push(`❌ Document ${update.documentId}: ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Bulk Document Update Results:\n\nSuccessful (${results.length}):\n${results.join('\n')}\n\nFailed (${errors.length}):\n${errors.join('\n')}`
}
]
};
}
private async bulkDeleteDocuments(args: any) {
if (!this.databases) throw new Error("Databases not initialized");
const { databaseId, collectionId, documentIds } = args;
const results = [];
const errors = [];
for (const documentId of documentIds) {
try {
await this.databases.deleteDocument(databaseId, collectionId, documentId);
results.push(`✅ Document ${documentId} deleted`);
} catch (error) {
errors.push(`❌ Document ${documentId}: ${error}`);
}
}
return {
content: [
{
type: "text",
text: `Bulk Document Deletion Results:\n\nSuccessful (${results.length}):\n${results.join('\n')}\n\nFailed (${errors.length}):\n${errors.join('\n')}`
}
]
};
}
async run(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);