From 5ea6b1d46e57f37ef5edc2162076e3223ba03c1e Mon Sep 17 00:00:00 2001 From: Amaan Ahmad <20dpee018ct@manuu.edu.in> Date: Thu, 5 Feb 2026 23:06:11 +0530 Subject: [PATCH 1/2] Add Appwrite power for Kiro IDE - Add comprehensive Appwrite power with dual MCP servers (API + Docs) - Include modular API access with command-line flags - Add best practices steering file - Support for databases, auth, storage, functions, messaging, and sites - Update README with Appwrite entry --- README.md | 8 + appwrite/POWER.md | 775 ++++++++++++++++++++++++++++++++++ appwrite/mcp.json | 19 + appwrite/steering/steering.md | 724 +++++++++++++++++++++++++++++++ 4 files changed, 1526 insertions(+) create mode 100644 appwrite/POWER.md create mode 100644 appwrite/mcp.json create mode 100644 appwrite/steering/steering.md diff --git a/README.md b/README.md index 03c7d25..41d97d5 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Documentation is available at https://kiro.dev/docs/powers/ ## Available powers + ### aws-agentcore **Build an agent with Amazon Bedrock AgentCore** - Build, test, and deploy AI agents using AWS Bedrock AgentCore with local development workflow. Amazon Bedrock AgentCore is an agentic platform for building, deploying, and operating effective agents. @@ -104,6 +105,13 @@ Documentation is available at https://kiro.dev/docs/powers/ --- +### appwrite +**Appwrite Backend Platform** - Build backend services with Appwrite - databases, authentication, storage, functions, and messaging for web and mobile apps. + +**MCP Servers:** appwrite-api, appwrite-docs + +--- + ## Security diff --git a/appwrite/POWER.md b/appwrite/POWER.md new file mode 100644 index 0000000..d15cbad --- /dev/null +++ b/appwrite/POWER.md @@ -0,0 +1,775 @@ +--- +name: "appwrite" +displayName: "Appwrite Backend Platform" +description: "Build backend services with Appwrite - databases, authentication, storage, functions, and messaging for web and mobile apps" +keywords: ["appwrite", "backend", "database", "auth", "authentication", "storage", "functions", "serverless", "baas", "api", "users", "teams", "messaging"] +author: "Appwrite" +--- + +# Onboarding + +Before using Appwrite MCP, ensure you have completed the following steps. + +## Step 1: Validate Prerequisites + +Check that the required tools are installed: + +**For API Server:** +- **uv**: Required to run the Appwrite API MCP server + - Verify with: `uv --version` + - Install if missing: Follow instructions at https://docs.astral.sh/uv/getting-started/installation/ + - **CRITICAL**: If uv is not installed, DO NOT proceed with API server setup + +**For Docs Server:** +- **Node.js and npm**: Required for the documentation MCP server + - Verify with: `node --version` and `npm --version` + - Install if missing: Download from https://nodejs.org/ + +## Step 2: Configure Appwrite Credentials + +You need an Appwrite project with API credentials: + +1. **Create or access your Appwrite project** at https://cloud.appwrite.io +2. **Get your Project ID** from the Settings page +3. **Create an API Key** with necessary scopes: + - Navigate to Settings → API Keys + - Click "Create API Key" + - Enable required scopes (databases, users, storage, functions, etc.) + - Copy the generated API key +4. **Note your region and endpoint**: + - Format: `https://.cloud.appwrite.io/v1` + - Common regions: `nyc`, `fra`, `sfo`, `blr`, `sgp`, `syd` + +**Environment Variables:** + +Set these environment variables on your system or add them to your MCP configuration: + +- `APPWRITE_PROJECT_ID` - Your project ID +- `APPWRITE_API_KEY` - Your API key (keep secure!) +- `APPWRITE_ENDPOINT` - Your endpoint URL (e.g., `https://nyc.cloud.appwrite.io/v1`) + +## Step 3: Choose MCP Servers + +This power provides two MCP servers: + +- **appwrite-api**: Interact with Appwrite services (databases, users, storage, functions, etc.) +- **appwrite-docs**: Query Appwrite documentation for guidance and examples + +You can enable one or both depending on your needs. The API server is essential for building applications, while the docs server helps with learning and troubleshooting. + +## Step 4: Add Development Hooks (Optional) + +Create a hook to validate database operations. Save to `.kiro/hooks/appwrite-db-check.kiro.hook`: + +```json +{ + "enabled": true, + "name": "Appwrite Database Validation", + "description": "Validates database schema and queries when database files are modified", + "version": "1", + "when": { + "type": "fileEdited", + "patterns": [ + "**/appwrite/**/*.ts", + "**/appwrite/**/*.js", + "**/lib/appwrite/**", + "**/src/appwrite/**" + ] + }, + "then": { + "type": "askAgent", + "prompt": "Review the Appwrite database code for best practices: proper error handling, type safety, query optimization, and security permissions" + } +} +``` + +# Overview + +Appwrite is an open-source backend-as-a-service platform that provides authentication, databases, storage, functions, and messaging. This power gives you access to both the Appwrite API and comprehensive documentation through MCP servers. + +**Key capabilities:** + +- **Databases**: Create collections, manage documents, query data with powerful filters +- **Authentication**: User management, OAuth providers, sessions, teams +- **Storage**: File uploads, downloads, image transformations, permissions +- **Functions**: Serverless functions with multiple runtimes +- **Messaging**: Email, SMS, and push notifications +- **Real-time**: WebSocket subscriptions for live data updates +- **Sites**: Deploy static sites and SSR applications + +**Perfect for:** +- Building full-stack web and mobile applications +- Creating serverless backends +- Managing user authentication and authorization +- Storing and serving files with CDN +- Implementing real-time features +- Deploying static sites and server-side rendered apps + +## Available MCP Servers + +### appwrite-api + +**Package:** `mcp-server-appwrite` (via uvx) +**Connection:** Python-based MCP server +**Authentication:** API key with project ID and endpoint + +**Command-line Arguments:** + +By default, only Database tools are enabled. Use these flags to enable additional APIs: + +- `--tables-db` - TablesDB API (relational database operations) +- `--users` - Users API (user management and authentication) +- `--teams` - Teams API (team and membership management) +- `--storage` - Storage API (file upload, download, management) +- `--functions` - Functions API (serverless function deployment) +- `--messaging` - Messaging API (email, SMS, push notifications) +- `--locale` - Locale API (country, language, currency data) +- `--avatars` - Avatars API (generate avatars and QR codes) +- `--sites` - Sites API (deploy static sites and SSR apps) +- `--databases` - Legacy Databases API +- `--all` - Enable all Appwrite APIs + +**Important:** Only enable the APIs you need. Each enabled API adds tools to the LLM context, reducing available context window. Start with databases and add others as needed. + +**Available Tools (varies by enabled APIs):** + +**Databases API** (enabled by default): +- `mcp_appwrite_api_databases_create` - Create a new database +- `mcp_appwrite_api_databases_list` - List all databases +- `mcp_appwrite_api_databases_get` - Get database details +- `mcp_appwrite_api_databases_update` - Update database properties +- `mcp_appwrite_api_databases_delete` - Delete a database +- `mcp_appwrite_api_databases_create_collection` - Create a collection +- `mcp_appwrite_api_databases_list_collections` - List collections +- `mcp_appwrite_api_databases_get_collection` - Get collection details +- `mcp_appwrite_api_databases_update_collection` - Update collection +- `mcp_appwrite_api_databases_delete_collection` - Delete collection +- `mcp_appwrite_api_databases_create_document` - Create a document +- `mcp_appwrite_api_databases_list_documents` - Query documents +- `mcp_appwrite_api_databases_get_document` - Get document by ID +- `mcp_appwrite_api_databases_update_document` - Update document +- `mcp_appwrite_api_databases_delete_document` - Delete document +- Plus attribute, index, and transaction management tools + +**Users API** (with `--users` flag): +- `mcp_appwrite_api_users_create` - Create a new user +- `mcp_appwrite_api_users_list` - List all users +- `mcp_appwrite_api_users_get` - Get user details +- `mcp_appwrite_api_users_update_email` - Update user email +- `mcp_appwrite_api_users_update_password` - Update user password +- `mcp_appwrite_api_users_delete` - Delete a user +- Plus session, preferences, and MFA management tools + +**Storage API** (with `--storage` flag): +- `mcp_appwrite_api_storage_create_bucket` - Create storage bucket +- `mcp_appwrite_api_storage_list_buckets` - List all buckets +- `mcp_appwrite_api_storage_create_file` - Upload a file +- `mcp_appwrite_api_storage_list_files` - List files in bucket +- `mcp_appwrite_api_storage_get_file` - Get file metadata +- `mcp_appwrite_api_storage_get_file_download` - Download file +- `mcp_appwrite_api_storage_get_file_preview` - Get image preview +- `mcp_appwrite_api_storage_delete_file` - Delete a file + +**Functions API** (with `--functions` flag): +- `mcp_appwrite_api_functions_create` - Create a function +- `mcp_appwrite_api_functions_list` - List all functions +- `mcp_appwrite_api_functions_create_deployment` - Deploy function code +- `mcp_appwrite_api_functions_create_execution` - Execute a function +- `mcp_appwrite_api_functions_list_executions` - List function executions +- Plus variable and runtime management tools + +**Messaging API** (with `--messaging` flag): +- `mcp_appwrite_api_messaging_create_email` - Send email message +- `mcp_appwrite_api_messaging_create_sms` - Send SMS message +- `mcp_appwrite_api_messaging_create_push` - Send push notification +- `mcp_appwrite_api_messaging_create_topic` - Create messaging topic +- `mcp_appwrite_api_messaging_create_subscriber` - Add subscriber +- Plus provider and target management tools + +**Sites API** (with `--sites` flag): +- `mcp_appwrite_api_sites_create` - Create a new site +- `mcp_appwrite_api_sites_list` - List all sites +- `mcp_appwrite_api_sites_create_deployment` - Deploy site code +- `mcp_appwrite_api_sites_list_deployments` - List deployments +- `mcp_appwrite_api_sites_update_site_deployment` - Activate deployment +- Plus variable and framework management tools + +### appwrite-docs + +**Connection:** HTTPS API endpoint at `https://mcp-for-docs.appwrite.io` +**Authentication:** None required +**Type:** HTTP-based MCP server + +**Available Tools:** + +- `search_documentation` - Search Appwrite documentation +- `get_documentation_page` - Get specific documentation page +- `list_documentation_sections` - List available doc sections +- `get_api_reference` - Get API reference for specific endpoint +- `get_code_examples` - Get code examples for specific feature + +## Tool Usage Examples + +### Database Operations + +**Create a database:** +```javascript +mcp_appwrite_api_databases_create({ + "database_id": "main", + "name": "Main Database", + "enabled": true +}) +``` + +**Create a collection:** +```javascript +mcp_appwrite_api_databases_create_collection({ + "database_id": "main", + "collection_id": "users", + "name": "Users", + "permissions": ["read(\"any\")"], + "document_security": true +}) +``` + +**Add attributes to collection:** +```javascript +// String attribute +mcp_appwrite_api_databases_create_string_attribute({ + "database_id": "main", + "collection_id": "users", + "key": "name", + "size": 255, + "required": true +}) + +// Email attribute +mcp_appwrite_api_databases_create_email_attribute({ + "database_id": "main", + "collection_id": "users", + "key": "email", + "required": true +}) + +// Boolean attribute +mcp_appwrite_api_databases_create_boolean_attribute({ + "database_id": "main", + "collection_id": "users", + "key": "is_active", + "required": true, + "default": true +}) +``` + +**Create a document:** +```javascript +mcp_appwrite_api_databases_create_document({ + "database_id": "main", + "collection_id": "users", + "document_id": "unique()", + "data": { + "name": "John Doe", + "email": "john@example.com", + "is_active": true + }, + "permissions": ["read(\"user:USER_ID\")"] +}) +``` + +**Query documents:** +```javascript +mcp_appwrite_api_databases_list_documents({ + "database_id": "main", + "collection_id": "users", + "queries": [ + "equal(\"is_active\", true)", + "orderDesc(\"$createdAt\")", + "limit(10)" + ] +}) +``` + +### User Management + +**Create a user:** +```javascript +mcp_appwrite_api_users_create({ + "user_id": "unique()", + "email": "user@example.com", + "password": "SecurePass123!", + "name": "Jane Smith" +}) +``` + +**List users:** +```javascript +mcp_appwrite_api_users_list({ + "queries": ["limit(25)"], + "search": "john" +}) +``` + +**Update user email:** +```javascript +mcp_appwrite_api_users_update_email({ + "user_id": "USER_ID", + "email": "newemail@example.com" +}) +``` + +### Storage Operations + +**Create a storage bucket:** +```javascript +mcp_appwrite_api_storage_create_bucket({ + "bucket_id": "avatars", + "name": "User Avatars", + "permissions": ["read(\"any\")"], + "file_security": true, + "enabled": true, + "maximum_file_size": 5000000, // 5MB + "allowed_file_extensions": ["jpg", "jpeg", "png", "gif"] +}) +``` + +**Upload a file:** +```javascript +mcp_appwrite_api_storage_create_file({ + "bucket_id": "avatars", + "file_id": "unique()", + "file": "/path/to/avatar.jpg", + "permissions": ["read(\"any\")"] +}) +``` + +### Documentation Queries + +**Search documentation:** +```javascript +search_documentation({ + "query": "real-time subscriptions", + "limit": 5 +}) +``` + +**Get API reference:** +```javascript +get_api_reference({ + "endpoint": "/databases/{databaseId}/collections/{collectionId}/documents", + "method": "POST" +}) +``` + +## Common Workflows + +### Workflow 1: Complete Database Setup + +```javascript +// Step 1: Create database +const db = await mcp_appwrite_api_databases_create({ + "database_id": "main", + "name": "Main Database", + "enabled": true +}) + +// Step 2: Create collection +const collection = await mcp_appwrite_api_databases_create_collection({ + "database_id": "main", + "collection_id": "posts", + "name": "Blog Posts", + "permissions": ["read(\"any\")"], + "document_security": true +}) + +// Step 3: Add attributes +await mcp_appwrite_api_databases_create_string_attribute({ + "database_id": "main", + "collection_id": "posts", + "key": "title", + "size": 255, + "required": true +}) + +await mcp_appwrite_api_databases_create_string_attribute({ + "database_id": "main", + "collection_id": "posts", + "key": "content", + "size": 10000, + "required": true +}) + +await mcp_appwrite_api_databases_create_datetime_attribute({ + "database_id": "main", + "collection_id": "posts", + "key": "published_at", + "required": false +}) + +// Step 4: Create index for queries +await mcp_appwrite_api_databases_create_index({ + "database_id": "main", + "collection_id": "posts", + "key": "title_index", + "type": "key", + "attributes": ["title"] +}) + +// Step 5: Create first document +await mcp_appwrite_api_databases_create_document({ + "database_id": "main", + "collection_id": "posts", + "document_id": "unique()", + "data": { + "title": "Getting Started with Appwrite", + "content": "Appwrite is an amazing backend platform...", + "published_at": "2024-02-05T10:00:00.000Z" + } +}) +``` + +### Workflow 2: User Authentication Setup + +```javascript +// Step 1: Create admin user +const admin = await mcp_appwrite_api_users_create({ + "user_id": "unique()", + "email": "admin@example.com", + "password": "SecureAdminPass123!", + "name": "Admin User" +}) + +// Step 2: Create team for organization +const team = await mcp_appwrite_api_teams_create({ + "team_id": "unique()", + "name": "Engineering Team" +}) + +// Step 3: Add user to team +await mcp_appwrite_api_teams_create_membership({ + "team_id": team.id, + "email": "admin@example.com", + "roles": ["owner"], + "url": "https://example.com/join-team" +}) + +// Step 4: Set user preferences +await mcp_appwrite_api_users_update_prefs({ + "user_id": admin.id, + "prefs": { + "theme": "dark", + "notifications": true + } +}) +``` + +### Workflow 3: File Upload and Management + +```javascript +// Step 1: Create storage bucket +const bucket = await mcp_appwrite_api_storage_create_bucket({ + "bucket_id": "documents", + "name": "User Documents", + "permissions": ["read(\"any\")"], + "file_security": true, + "enabled": true, + "maximum_file_size": 10000000, // 10MB + "allowed_file_extensions": ["pdf", "doc", "docx", "txt"] +}) + +// Step 2: Upload file +const file = await mcp_appwrite_api_storage_create_file({ + "bucket_id": "documents", + "file_id": "unique()", + "file": "/path/to/document.pdf", + "permissions": ["read(\"user:USER_ID\")"] +}) + +// Step 3: Get file download URL +const download = await mcp_appwrite_api_storage_get_file_download({ + "bucket_id": "documents", + "file_id": file.id +}) + +// Step 4: List all files +const files = await mcp_appwrite_api_storage_list_files({ + "bucket_id": "documents", + "queries": ["limit(25)"] +}) +``` + +### Workflow 4: Serverless Function Deployment + +```javascript +// Step 1: Create function +const func = await mcp_appwrite_api_functions_create({ + "function_id": "unique()", + "name": "Process Payment", + "runtime": "node-18.0", + "execute": ["any"], + "events": [], + "schedule": "", + "timeout": 15 +}) + +// Step 2: Create deployment +const deployment = await mcp_appwrite_api_functions_create_deployment({ + "function_id": func.id, + "code": "/path/to/function.tar.gz", + "activate": true, + "entrypoint": "index.js" +}) + +// Step 3: Set environment variables +await mcp_appwrite_api_functions_create_variable({ + "function_id": func.id, + "key": "STRIPE_API_KEY", + "value": "sk_test_...", + "secret": true +}) + +// Step 4: Execute function +const execution = await mcp_appwrite_api_functions_create_execution({ + "function_id": func.id, + "body": JSON.stringify({ amount: 1000, currency: "usd" }), + "xasync": false +}) +``` + +## Best Practices + +### ✅ Do: + +- **Use document-level permissions** for fine-grained access control +- **Enable document security** on collections with sensitive data +- **Create indexes** for frequently queried attributes +- **Use `unique()` for IDs** to auto-generate unique identifiers +- **Validate data** before creating documents +- **Handle errors gracefully** with try-catch blocks +- **Use queries efficiently** with proper filters and limits +- **Store sensitive data** in environment variables +- **Enable file security** on storage buckets +- **Set appropriate file size limits** on buckets +- **Use transactions** for atomic multi-document operations +- **Test with sandbox** before production deployment +- **Monitor function executions** for errors and performance +- **Use webhooks** for real-time event handling +- **Keep API keys secure** - never commit to version control + +### ❌ Don't: + +- **Expose API keys** in client-side code +- **Skip permission configuration** - always set appropriate permissions +- **Create collections without attributes** - define schema first +- **Use weak passwords** for user accounts +- **Ignore query limits** - always paginate large result sets +- **Store large files** without compression +- **Hardcode credentials** in function code +- **Skip error handling** in production code +- **Use `read("any")` for sensitive data** - restrict access properly +- **Forget to enable collections** - disabled collections are inaccessible +- **Mix test and production data** - use separate projects +- **Skip backup strategy** - export data regularly +- **Ignore rate limits** - implement proper throttling +- **Use synchronous functions** for long operations - use async + +## Troubleshooting + +### Error: "Invalid API key" +**Cause:** Incorrect or missing API key +**Solution:** +1. Verify API key in Appwrite console +2. Check environment variable is set correctly +3. Ensure API key has required scopes +4. Regenerate key if compromised + +### Error: "Database not found" +**Cause:** Invalid database ID or database doesn't exist +**Solution:** +1. Call `list_databases` to verify database exists +2. Check database ID spelling +3. Ensure database is enabled +4. Create database if it doesn't exist + +### Error: "Collection not found" +**Cause:** Invalid collection ID or collection doesn't exist +**Solution:** +1. Call `list_collections` to verify collection exists +2. Check collection ID spelling +3. Ensure collection is enabled +4. Create collection if it doesn't exist + +### Error: "Document not found" +**Cause:** Invalid document ID or document was deleted +**Solution:** +1. Verify document ID is correct +2. Check if document was deleted +3. Ensure user has read permissions +4. Query collection to find document + +### Error: "Attribute not found" +**Cause:** Trying to query or set non-existent attribute +**Solution:** +1. Call `list_attributes` to see available attributes +2. Create attribute before using it +3. Check attribute key spelling +4. Wait for attribute creation to complete (async operation) + +### Error: "Permission denied" +**Cause:** User doesn't have required permissions +**Solution:** +1. Check document/collection permissions +2. Verify user is authenticated +3. Update permissions to grant access +4. Use `read("any")` for public data + +### Error: "File too large" +**Cause:** File exceeds bucket's maximum file size +**Solution:** +1. Check bucket's `maximum_file_size` setting +2. Compress file before upload +3. Update bucket settings to allow larger files +4. Split large files into chunks + +### Error: "Invalid file extension" +**Cause:** File type not allowed in bucket +**Solution:** +1. Check bucket's `allowed_file_extensions` +2. Convert file to allowed format +3. Update bucket to allow file type +4. Remove extension restriction if appropriate + +### Error: "Function execution failed" +**Cause:** Error in function code or timeout +**Solution:** +1. Check function logs in Appwrite console +2. Verify function has required environment variables +3. Increase timeout if needed +4. Test function locally before deployment +5. Check function runtime is correct + +### Error: "Rate limit exceeded" +**Cause:** Too many requests in short time +**Solution:** +1. Implement exponential backoff +2. Cache frequently accessed data +3. Batch operations when possible +4. Upgrade plan for higher limits +5. Optimize query patterns + +## Configuration + +**Authentication Required:** Appwrite API key, Project ID, and Endpoint URL + +**Setup Steps:** + +1. Create Appwrite account at https://cloud.appwrite.io +2. Create a new project or select existing one +3. Navigate to Settings → API Keys +4. Create API key with required scopes: + - `databases.read`, `databases.write` for database operations + - `users.read`, `users.write` for user management + - `files.read`, `files.write` for storage operations + - `functions.read`, `functions.write` for serverless functions + - Or select "All" for full access +5. Copy Project ID from Settings page +6. Note your region (e.g., `nyc`, `fra`, `sfo`) +7. Set environment variables: + ```bash + export APPWRITE_PROJECT_ID="your-project-id" + export APPWRITE_API_KEY="your-api-key" + export APPWRITE_ENDPOINT="https://nyc.cloud.appwrite.io/v1" + ``` + +**MCP Configuration:** + +For API server (minimal - databases only): +```json +{ + "mcpServers": { + "appwrite-api": { + "command": "uvx", + "args": ["mcp-server-appwrite"], + "env": { + "APPWRITE_PROJECT_ID": "${APPWRITE_PROJECT_ID}", + "APPWRITE_API_KEY": "${APPWRITE_API_KEY}", + "APPWRITE_ENDPOINT": "${APPWRITE_ENDPOINT}" + } + } + } +} +``` + +For API server (with additional services): +```json +{ + "mcpServers": { + "appwrite-api": { + "command": "uvx", + "args": [ + "mcp-server-appwrite", + "--users", + "--storage", + "--functions", + "--sites" + ], + "env": { + "APPWRITE_PROJECT_ID": "${APPWRITE_PROJECT_ID}", + "APPWRITE_API_KEY": "${APPWRITE_API_KEY}", + "APPWRITE_ENDPOINT": "${APPWRITE_ENDPOINT}" + } + } + } +} +``` + +For documentation server: +```json +{ + "mcpServers": { + "appwrite-docs": { + "url": "https://mcp-for-docs.appwrite.io", + "type": "http" + } + } +} +``` + +**Permissions:** API key should have appropriate scopes for intended operations. Use least privilege principle - only grant necessary permissions. + +## Tips + +1. **Start with databases** - Most apps need data storage first +2. **Use document security** - Enable for collections with user-specific data +3. **Create indexes early** - Add indexes before large datasets +4. **Test permissions** - Verify access control works as expected +5. **Use query helpers** - Leverage Appwrite's query builder +6. **Monitor usage** - Check Appwrite console for metrics +7. **Enable real-time** - Use subscriptions for live updates +8. **Batch operations** - Use transactions for related changes +9. **Cache strategically** - Reduce API calls with smart caching +10. **Read the docs** - Use the docs MCP server for guidance +11. **Use TypeScript** - Type safety prevents many errors +12. **Version your schema** - Track database structure changes +13. **Test locally** - Use Appwrite CLI for local development +14. **Backup regularly** - Export data periodically +15. **Monitor logs** - Check function and API logs for issues + +## Resources + +- [Appwrite Documentation](https://appwrite.io/docs) +- [API Reference](https://appwrite.io/docs/references) +- [Quick Starts](https://appwrite.io/docs/quick-starts) +- [Database Guide](https://appwrite.io/docs/products/databases) +- [Authentication Guide](https://appwrite.io/docs/products/auth) +- [Storage Guide](https://appwrite.io/docs/products/storage) +- [Functions Guide](https://appwrite.io/docs/products/functions) +- [Sites Guide](https://appwrite.io/docs/products/sites) +- [Community Discord](https://appwrite.io/discord) +- [GitHub Repository](https://github.com/appwrite/appwrite) + +--- + +**Package:** `mcp-server-appwrite` (Python via uvx) +**Source:** Official Appwrite +**License:** BSD-3-Clause +**Connection:** Python MCP server with API key authentication diff --git a/appwrite/mcp.json b/appwrite/mcp.json new file mode 100644 index 0000000..6a71f67 --- /dev/null +++ b/appwrite/mcp.json @@ -0,0 +1,19 @@ +{ + "mcpServers": { + "appwrite-api": { + "command": "uvx", + "args": [ + "mcp-server-appwrite" + ], + "env": { + "APPWRITE_PROJECT_ID": "${APPWRITE_PROJECT_ID}", + "APPWRITE_API_KEY": "${APPWRITE_API_KEY}", + "APPWRITE_ENDPOINT": "${APPWRITE_ENDPOINT}" + } + }, + "appwrite-docs": { + "url": "https://mcp-for-docs.appwrite.io", + "type": "http" + } + } +} diff --git a/appwrite/steering/steering.md b/appwrite/steering/steering.md new file mode 100644 index 0000000..cb8d454 --- /dev/null +++ b/appwrite/steering/steering.md @@ -0,0 +1,724 @@ +# Appwrite Best Practices + +This guide provides best practices for building applications with Appwrite. + +## Database Design + +### Schema Planning + +**Always define your schema before creating documents:** + +```javascript +// ✅ Good: Define attributes first +await createStringAttribute({ key: "name", size: 255, required: true }) +await createEmailAttribute({ key: "email", required: true }) +await createBooleanAttribute({ key: "is_active", required: true, default: true }) + +// Then create documents +await createDocument({ data: { name: "John", email: "john@example.com", is_active: true }}) +``` + +**Use appropriate attribute types:** +- `string` - Short text (names, titles) - specify size +- `email` - Email addresses with validation +- `url` - URLs with validation +- `integer` - Whole numbers +- `float` - Decimal numbers +- `boolean` - True/false values +- `datetime` - ISO 8601 timestamps +- `enum` - Predefined values +- `relationship` - References to other collections + +### Indexing Strategy + +**Create indexes for frequently queried attributes:** + +```javascript +// ✅ Good: Index commonly queried fields +await createIndex({ + key: "email_index", + type: "unique", + attributes: ["email"] +}) + +await createIndex({ + key: "created_at_index", + type: "key", + attributes: ["$createdAt"], + orders: ["DESC"] +}) + +// For full-text search +await createIndex({ + key: "title_search", + type: "fulltext", + attributes: ["title", "content"] +}) +``` + +**Index types:** +- `key` - Standard index for equality and range queries +- `unique` - Ensures unique values (e.g., email, username) +- `fulltext` - Full-text search on text fields +- `array` - Index array values + +### Query Optimization + +**Use specific queries instead of fetching all documents:** + +```javascript +// ❌ Bad: Fetch everything +const all = await listDocuments({ collection_id: "posts" }) + +// ✅ Good: Use filters and limits +const recent = await listDocuments({ + collection_id: "posts", + queries: [ + "equal(\"status\", \"published\")", + "orderDesc(\"$createdAt\")", + "limit(10)" + ] +}) +``` + +**Common query methods:** +- `equal(attribute, value)` - Exact match +- `notEqual(attribute, value)` - Not equal +- `lessThan(attribute, value)` - Less than +- `greaterThan(attribute, value)` - Greater than +- `search(attribute, value)` - Full-text search +- `orderAsc(attribute)` - Sort ascending +- `orderDesc(attribute)` - Sort descending +- `limit(count)` - Limit results +- `offset(count)` - Skip results + +## Security & Permissions + +### Document-Level Security + +**Enable document security for user-specific data:** + +```javascript +// ✅ Good: Enable document security +await createCollection({ + collection_id: "posts", + name: "Posts", + document_security: true, + permissions: ["read(\"any\")"] // Anyone can list posts +}) + +// Create document with user-specific permissions +await createDocument({ + collection_id: "posts", + document_id: "unique()", + data: { title: "My Post", content: "..." }, + permissions: [ + "read(\"any\")", // Anyone can read + "update(\"user:USER_ID\")", // Only author can update + "delete(\"user:USER_ID\")" // Only author can delete + ] +}) +``` + +### Permission Patterns + +**Common permission patterns:** + +```javascript +// Public read, authenticated write +permissions: [ + "read(\"any\")", + "create(\"users\")", + "update(\"users\")", + "delete(\"users\")" +] + +// User-specific access +permissions: [ + "read(\"user:USER_ID\")", + "update(\"user:USER_ID\")", + "delete(\"user:USER_ID\")" +] + +// Team-based access +permissions: [ + "read(\"team:TEAM_ID\")", + "update(\"team:TEAM_ID/owner\")", + "delete(\"team:TEAM_ID/owner\")" +] + +// Role-based access +permissions: [ + "read(\"any\")", + "update(\"role:admin\")", + "delete(\"role:admin\")" +] +``` + +### API Key Security + +**Never expose API keys in client-side code:** + +```javascript +// ❌ Bad: API key in frontend +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('PROJECT_ID') + .setKey('API_KEY') // NEVER DO THIS! + +// ✅ Good: Use API key only in backend/server +// Frontend should use account sessions +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('PROJECT_ID') +``` + +## User Management + +### User Creation + +**Create users with proper validation:** + +```javascript +// ✅ Good: Validate before creating +function validateEmail(email) { + return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) +} + +function validatePassword(password) { + return password.length >= 8 && /[A-Z]/.test(password) && /[0-9]/.test(password) +} + +if (validateEmail(email) && validatePassword(password)) { + await createUser({ + user_id: "unique()", + email: email, + password: password, + name: name + }) +} +``` + +### User Preferences + +**Store user settings in preferences:** + +```javascript +// ✅ Good: Use preferences for user settings +await updatePrefs({ + user_id: userId, + prefs: { + theme: "dark", + language: "en", + notifications: { + email: true, + push: false + } + } +}) +``` + +## Storage Management + +### Bucket Configuration + +**Configure buckets with appropriate limits:** + +```javascript +// ✅ Good: Set reasonable limits +await createBucket({ + bucket_id: "avatars", + name: "User Avatars", + permissions: ["read(\"any\")"], + file_security: true, + enabled: true, + maximum_file_size: 5000000, // 5MB + allowed_file_extensions: ["jpg", "jpeg", "png", "gif", "webp"], + compression: "gzip", + encryption: true, + antivirus: true +}) +``` + +### File Upload Best Practices + +**Validate files before upload:** + +```javascript +// ✅ Good: Validate file before upload +function validateFile(file) { + const maxSize = 5 * 1024 * 1024 // 5MB + const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'] + + if (file.size > maxSize) { + throw new Error('File too large') + } + + if (!allowedTypes.includes(file.type)) { + throw new Error('Invalid file type') + } + + return true +} + +if (validateFile(file)) { + await createFile({ + bucket_id: "avatars", + file_id: "unique()", + file: file, + permissions: ["read(\"any\")"] + }) +} +``` + +### Image Optimization + +**Use preview endpoint for optimized images:** + +```javascript +// ✅ Good: Use preview with optimization +const imageUrl = `${endpoint}/storage/buckets/${bucketId}/files/${fileId}/preview?width=400&height=400&quality=80&output=webp` + +// For thumbnails +const thumbnail = `${endpoint}/storage/buckets/${bucketId}/files/${fileId}/preview?width=150&height=150&gravity=center&output=webp` +``` + +## Functions Development + +### Function Structure + +**Organize function code properly:** + +```javascript +// ✅ Good: Clean function structure +export default async ({ req, res, log, error }) => { + try { + // Validate input + const { amount, currency } = JSON.parse(req.body) + + if (!amount || !currency) { + return res.json({ error: 'Missing required fields' }, 400) + } + + // Process logic + const result = await processPayment(amount, currency) + + // Return response + return res.json({ success: true, result }) + + } catch (err) { + error(err.message) + return res.json({ error: 'Internal server error' }, 500) + } +} +``` + +### Environment Variables + +**Use environment variables for secrets:** + +```javascript +// ✅ Good: Use environment variables +const stripeKey = process.env.STRIPE_API_KEY +const webhookSecret = process.env.WEBHOOK_SECRET + +// ❌ Bad: Hardcoded secrets +const stripeKey = 'sk_test_...' // NEVER DO THIS! +``` + +### Error Handling + +**Implement comprehensive error handling:** + +```javascript +// ✅ Good: Proper error handling +export default async ({ req, res, log, error }) => { + try { + const data = JSON.parse(req.body) + + // Validate + if (!data.email) { + return res.json({ error: 'Email required' }, 400) + } + + // Process + const result = await sendEmail(data.email) + + log('Email sent successfully') + return res.json({ success: true }) + + } catch (err) { + error(`Failed to send email: ${err.message}`) + + // Return appropriate error + if (err.code === 'INVALID_EMAIL') { + return res.json({ error: 'Invalid email address' }, 400) + } + + return res.json({ error: 'Internal server error' }, 500) + } +} +``` + +## Real-time Subscriptions + +### Subscribe to Changes + +**Use real-time for live updates:** + +```javascript +// ✅ Good: Subscribe to specific channels +client.subscribe('databases.main.collections.posts.documents', response => { + if (response.events.includes('databases.*.collections.*.documents.*.create')) { + console.log('New post created:', response.payload) + } + + if (response.events.includes('databases.*.collections.*.documents.*.update')) { + console.log('Post updated:', response.payload) + } +}) + +// Subscribe to specific document +client.subscribe('databases.main.collections.posts.documents.POST_ID', response => { + console.log('Document changed:', response.payload) +}) +``` + +## Error Handling + +### Graceful Error Handling + +**Always handle errors gracefully:** + +```javascript +// ✅ Good: Comprehensive error handling +async function createPost(title, content) { + try { + const document = await createDocument({ + database_id: "main", + collection_id: "posts", + document_id: "unique()", + data: { title, content } + }) + + return { success: true, document } + + } catch (error) { + // Handle specific errors + if (error.code === 404) { + console.error('Collection not found') + return { success: false, error: 'Collection not found' } + } + + if (error.code === 401) { + console.error('Unauthorized') + return { success: false, error: 'Unauthorized' } + } + + if (error.code === 409) { + console.error('Document already exists') + return { success: false, error: 'Duplicate document' } + } + + // Generic error + console.error('Failed to create post:', error) + return { success: false, error: 'Failed to create post' } + } +} +``` + +## Performance Optimization + +### Caching Strategy + +**Implement caching for frequently accessed data:** + +```javascript +// ✅ Good: Cache frequently accessed data +const cache = new Map() + +async function getPost(postId) { + // Check cache first + if (cache.has(postId)) { + return cache.get(postId) + } + + // Fetch from database + const post = await getDocument({ + database_id: "main", + collection_id: "posts", + document_id: postId + }) + + // Cache for 5 minutes + cache.set(postId, post) + setTimeout(() => cache.delete(postId), 5 * 60 * 1000) + + return post +} +``` + +### Batch Operations + +**Use transactions for multiple related operations:** + +```javascript +// ✅ Good: Use transactions for atomic operations +const transaction = await createTransaction({ ttl: 300 }) + +try { + // Create user + await createDocument({ + database_id: "main", + collection_id: "users", + document_id: "unique()", + data: { name: "John", email: "john@example.com" }, + transaction_id: transaction.id + }) + + // Create user profile + await createDocument({ + database_id: "main", + collection_id: "profiles", + document_id: "unique()", + data: { user_id: userId, bio: "..." }, + transaction_id: transaction.id + }) + + // Commit transaction + await updateTransaction({ + transaction_id: transaction.id, + commit: true + }) + +} catch (error) { + // Rollback on error + await updateTransaction({ + transaction_id: transaction.id, + rollback: true + }) +} +``` + +## Testing + +### Test Environment + +**Use separate projects for testing:** + +```javascript +// ✅ Good: Separate test and production +const config = { + test: { + endpoint: 'https://cloud.appwrite.io/v1', + project: 'TEST_PROJECT_ID', + apiKey: 'TEST_API_KEY' + }, + production: { + endpoint: 'https://cloud.appwrite.io/v1', + project: 'PROD_PROJECT_ID', + apiKey: 'PROD_API_KEY' + } +} + +const env = process.env.NODE_ENV || 'test' +const client = new Client() + .setEndpoint(config[env].endpoint) + .setProject(config[env].project) + .setKey(config[env].apiKey) +``` + +### Integration Tests + +**Write tests for critical operations:** + +```javascript +// ✅ Good: Test critical operations +describe('User Management', () => { + test('should create user', async () => { + const user = await createUser({ + user_id: "unique()", + email: "test@example.com", + password: "SecurePass123!", + name: "Test User" + }) + + expect(user.email).toBe("test@example.com") + expect(user.name).toBe("Test User") + }) + + test('should handle duplicate email', async () => { + await expect( + createUser({ + user_id: "unique()", + email: "test@example.com", + password: "SecurePass123!", + name: "Test User" + }) + ).rejects.toThrow() + }) +}) +``` + +## Monitoring & Logging + +### Function Logging + +**Use structured logging:** + +```javascript +// ✅ Good: Structured logging +export default async ({ req, res, log, error }) => { + log('Function started', { + method: req.method, + path: req.path, + timestamp: new Date().toISOString() + }) + + try { + const result = await processRequest(req) + + log('Function completed successfully', { + duration: Date.now() - startTime, + result: result + }) + + return res.json({ success: true, result }) + + } catch (err) { + error('Function failed', { + error: err.message, + stack: err.stack, + timestamp: new Date().toISOString() + }) + + return res.json({ error: 'Internal server error' }, 500) + } +} +``` + +### Usage Monitoring + +**Monitor API usage and performance:** + +```javascript +// ✅ Good: Track API usage +const metrics = { + requests: 0, + errors: 0, + latency: [] +} + +async function apiCall(operation) { + const start = Date.now() + metrics.requests++ + + try { + const result = await operation() + metrics.latency.push(Date.now() - start) + return result + + } catch (error) { + metrics.errors++ + throw error + } +} + +// Log metrics periodically +setInterval(() => { + console.log('API Metrics:', { + requests: metrics.requests, + errors: metrics.errors, + avgLatency: metrics.latency.reduce((a, b) => a + b, 0) / metrics.latency.length, + errorRate: (metrics.errors / metrics.requests * 100).toFixed(2) + '%' + }) +}, 60000) // Every minute +``` + +## Migration & Backup + +### Data Export + +**Regularly export important data:** + +```javascript +// ✅ Good: Export data for backup +async function exportCollection(databaseId, collectionId) { + const documents = [] + let offset = 0 + const limit = 100 + + while (true) { + const response = await listDocuments({ + database_id: databaseId, + collection_id: collectionId, + queries: [`limit(${limit})`, `offset(${offset})`] + }) + + documents.push(...response.documents) + + if (response.documents.length < limit) { + break + } + + offset += limit + } + + // Save to file + fs.writeFileSync( + `backup-${collectionId}-${Date.now()}.json`, + JSON.stringify(documents, null, 2) + ) + + return documents +} +``` + +### Schema Migration + +**Version your schema changes:** + +```javascript +// ✅ Good: Version schema migrations +const migrations = { + v1: async () => { + await createStringAttribute({ + database_id: "main", + collection_id: "users", + key: "name", + size: 255, + required: true + }) + }, + + v2: async () => { + await createEmailAttribute({ + database_id: "main", + collection_id: "users", + key: "email", + required: true + }) + }, + + v3: async () => { + await createBooleanAttribute({ + database_id: "main", + collection_id: "users", + key: "is_verified", + required: true, + default: false + }) + } +} + +async function runMigrations(currentVersion, targetVersion) { + for (let v = currentVersion + 1; v <= targetVersion; v++) { + console.log(`Running migration v${v}`) + await migrations[`v${v}`]() + } +} +``` + +--- + +Following these best practices will help you build secure, performant, and maintainable applications with Appwrite. From 297887b3d2ece68b3d7685f45e45c7d297b758cd Mon Sep 17 00:00:00 2001 From: Amaan Ahmad <20dpee018ct@manuu.edu.in> Date: Mon, 11 May 2026 10:48:47 +0530 Subject: [PATCH 2/2] Update Appwrite power to MCP Server 2.0 - Updated POWER.md with MCP 2.0 two-tool architecture - Removed all service flag documentation (--users, --storage, etc.) - Added natural language query examples and workflows - Enhanced steering.md with MCP 2.0 best practices - Simplified configuration (all services now automatic) - Updated to mcp-server-appwrite v0.4.1+ Key improvements: - Zero configuration - no service flags needed - Reduced context usage - only 2 tools exposed - Natural language support - conversational queries - Startup validation - credentials checked on launch - All Appwrite services automatically available --- appwrite/POWER.md | 609 ++++++++++++---------------------- appwrite/steering/steering.md | 79 ++++- 2 files changed, 295 insertions(+), 393 deletions(-) diff --git a/appwrite/POWER.md b/appwrite/POWER.md index d15cbad..382f1d9 100644 --- a/appwrite/POWER.md +++ b/appwrite/POWER.md @@ -2,8 +2,9 @@ name: "appwrite" displayName: "Appwrite Backend Platform" description: "Build backend services with Appwrite - databases, authentication, storage, functions, and messaging for web and mobile apps" -keywords: ["appwrite", "backend", "database", "auth", "authentication", "storage", "functions", "serverless", "baas", "api", "users", "teams", "messaging"] +keywords: ["appwrite", "backend", "database", "auth", "authentication", "storage", "functions", "serverless", "baas", "api", "users", "sites", "messaging"] author: "Appwrite" +version: "2.0.0" --- # Onboarding @@ -15,15 +16,13 @@ Before using Appwrite MCP, ensure you have completed the following steps. Check that the required tools are installed: **For API Server:** -- **uv**: Required to run the Appwrite API MCP server +- **uv**: Required to run the Appwrite API MCP server (version 0.4.1+) - Verify with: `uv --version` - Install if missing: Follow instructions at https://docs.astral.sh/uv/getting-started/installation/ - **CRITICAL**: If uv is not installed, DO NOT proceed with API server setup **For Docs Server:** -- **Node.js and npm**: Required for the documentation MCP server - - Verify with: `node --version` and `npm --version` - - Install if missing: Download from https://nodejs.org/ +- **No prerequisites required** - HTTP-based server, works out of the box ## Step 2: Configure Appwrite Credentials @@ -48,14 +47,20 @@ Set these environment variables on your system or add them to your MCP configura - `APPWRITE_API_KEY` - Your API key (keep secure!) - `APPWRITE_ENDPOINT` - Your endpoint URL (e.g., `https://nyc.cloud.appwrite.io/v1`) -## Step 3: Choose MCP Servers +## Step 3: Understand MCP Server 2.0 Architecture This power provides two MCP servers: -- **appwrite-api**: Interact with Appwrite services (databases, users, storage, functions, etc.) +- **appwrite-api**: Interact with Appwrite services using the new 2-tool architecture - **appwrite-docs**: Query Appwrite documentation for guidance and examples -You can enable one or both depending on your needs. The API server is essential for building applications, while the docs server helps with learning and troubleshooting. +**What's New in MCP Server 2.0:** +- **Zero Configuration**: No more service flags (`--users`, `--storage`, etc.) - all services are automatically available +- **Compact Architecture**: Only 2 tools exposed to the model (`appwrite_search_tools` and `appwrite_call_tool`) +- **Reduced Context Usage**: Full Appwrite tool catalog stays internal and is searched at runtime +- **Automatic Service Discovery**: All supported Appwrite services are automatically registered + +You can enable one or both servers depending on your needs. The API server is essential for building applications, while the docs server helps with learning and troubleshooting. ## Step 4: Add Development Hooks (Optional) @@ -109,90 +114,72 @@ Appwrite is an open-source backend-as-a-service platform that provides authentic ### appwrite-api -**Package:** `mcp-server-appwrite` (via uvx) +**Package:** `mcp-server-appwrite` (version 0.4.1+, via uvx) **Connection:** Python-based MCP server **Authentication:** API key with project ID and endpoint +**Architecture:** MCP Server 2.0 with compact two-tool design + +**Revolutionary Two-Tool Architecture:** + +Instead of exposing dozens of tools directly to the model, MCP Server 2.0 uses only **two MCP tools**: + +- `appwrite_search_tools` - Searches the full Appwrite tool catalog based on natural language intent +- `appwrite_call_tool` - Executes a specific Appwrite operation by name + +**Key Benefits:** +- **Zero Configuration**: No service flags needed - all Appwrite services work automatically +- **Minimal Context Usage**: Full tool catalog stays internal, freeing up context for your code +- **Automatic Discovery**: All services (databases, users, storage, functions, messaging, sites, teams) are available by default +- **Smart Search**: AI searches for the right tool based on your intent +- **Validation on Startup**: Credentials and scopes are validated when the server starts, not on first tool call + +**No More Service Flags!** + +Previous versions required flags like `--users`, `--storage`, `--functions`, etc. These are **completely removed** in version 2.0. Simply run: + +```json +{ + "command": "uvx", + "args": ["mcp-server-appwrite"] +} +``` + +All services are automatically available without any configuration. -**Command-line Arguments:** - -By default, only Database tools are enabled. Use these flags to enable additional APIs: - -- `--tables-db` - TablesDB API (relational database operations) -- `--users` - Users API (user management and authentication) -- `--teams` - Teams API (team and membership management) -- `--storage` - Storage API (file upload, download, management) -- `--functions` - Functions API (serverless function deployment) -- `--messaging` - Messaging API (email, SMS, push notifications) -- `--locale` - Locale API (country, language, currency data) -- `--avatars` - Avatars API (generate avatars and QR codes) -- `--sites` - Sites API (deploy static sites and SSR apps) -- `--databases` - Legacy Databases API -- `--all` - Enable all Appwrite APIs - -**Important:** Only enable the APIs you need. Each enabled API adds tools to the LLM context, reducing available context window. Start with databases and add others as needed. - -**Available Tools (varies by enabled APIs):** - -**Databases API** (enabled by default): -- `mcp_appwrite_api_databases_create` - Create a new database -- `mcp_appwrite_api_databases_list` - List all databases -- `mcp_appwrite_api_databases_get` - Get database details -- `mcp_appwrite_api_databases_update` - Update database properties -- `mcp_appwrite_api_databases_delete` - Delete a database -- `mcp_appwrite_api_databases_create_collection` - Create a collection -- `mcp_appwrite_api_databases_list_collections` - List collections -- `mcp_appwrite_api_databases_get_collection` - Get collection details -- `mcp_appwrite_api_databases_update_collection` - Update collection -- `mcp_appwrite_api_databases_delete_collection` - Delete collection -- `mcp_appwrite_api_databases_create_document` - Create a document -- `mcp_appwrite_api_databases_list_documents` - Query documents -- `mcp_appwrite_api_databases_get_document` - Get document by ID -- `mcp_appwrite_api_databases_update_document` - Update document -- `mcp_appwrite_api_databases_delete_document` - Delete document -- Plus attribute, index, and transaction management tools - -**Users API** (with `--users` flag): -- `mcp_appwrite_api_users_create` - Create a new user -- `mcp_appwrite_api_users_list` - List all users -- `mcp_appwrite_api_users_get` - Get user details -- `mcp_appwrite_api_users_update_email` - Update user email -- `mcp_appwrite_api_users_update_password` - Update user password -- `mcp_appwrite_api_users_delete` - Delete a user -- Plus session, preferences, and MFA management tools - -**Storage API** (with `--storage` flag): -- `mcp_appwrite_api_storage_create_bucket` - Create storage bucket -- `mcp_appwrite_api_storage_list_buckets` - List all buckets -- `mcp_appwrite_api_storage_create_file` - Upload a file -- `mcp_appwrite_api_storage_list_files` - List files in bucket -- `mcp_appwrite_api_storage_get_file` - Get file metadata -- `mcp_appwrite_api_storage_get_file_download` - Download file -- `mcp_appwrite_api_storage_get_file_preview` - Get image preview -- `mcp_appwrite_api_storage_delete_file` - Delete a file - -**Functions API** (with `--functions` flag): -- `mcp_appwrite_api_functions_create` - Create a function -- `mcp_appwrite_api_functions_list` - List all functions -- `mcp_appwrite_api_functions_create_deployment` - Deploy function code -- `mcp_appwrite_api_functions_create_execution` - Execute a function -- `mcp_appwrite_api_functions_list_executions` - List function executions -- Plus variable and runtime management tools - -**Messaging API** (with `--messaging` flag): -- `mcp_appwrite_api_messaging_create_email` - Send email message -- `mcp_appwrite_api_messaging_create_sms` - Send SMS message -- `mcp_appwrite_api_messaging_create_push` - Send push notification -- `mcp_appwrite_api_messaging_create_topic` - Create messaging topic -- `mcp_appwrite_api_messaging_create_subscriber` - Add subscriber -- Plus provider and target management tools - -**Sites API** (with `--sites` flag): -- `mcp_appwrite_api_sites_create` - Create a new site -- `mcp_appwrite_api_sites_list` - List all sites -- `mcp_appwrite_api_sites_create_deployment` - Deploy site code -- `mcp_appwrite_api_sites_list_deployments` - List deployments -- `mcp_appwrite_api_sites_update_site_deployment` - Activate deployment -- Plus variable and framework management tools +**Available Tools (via search and call pattern):** + +The server provides access to all Appwrite services through the two-tool architecture: + +**Core Services** (automatically available): +- **Databases**: Collections, documents, queries, indexes, attributes, transactions +- **Users**: User management, sessions, preferences, MFA, OAuth +- **Storage**: Buckets, file operations, image transformations, previews +- **Functions**: Serverless deployment, executions, variables, multiple runtimes +- **Messaging**: Email, SMS, push notifications, topics, subscribers +- **Sites**: Static sites, SSR applications, deployments, frameworks +- **Teams**: Team management, memberships, roles, invitations +- **Locale**: Country, language, currency, timezone data +- **Avatars**: Generate avatars, QR codes, favicons + +**How It Works:** + +1. **Search**: AI uses `appwrite_search_tools` with natural language (e.g., "create a user", "list databases") +2. **Discover**: Server searches internal catalog and returns matching tool definitions +3. **Execute**: AI calls `appwrite_call_tool` with the specific tool name and parameters +4. **Result**: Server executes the operation and returns the result + +**Example Flow:** +``` +User: "Create a new database called 'production'" +↓ +AI: appwrite_search_tools(query="create database") +↓ +Server: Returns tool definition for "databases_create" +↓ +AI: appwrite_call_tool(tool_name="databases_create", arguments={...}) +↓ +Server: Executes and returns database creation result +``` ### appwrite-docs @@ -202,337 +189,178 @@ By default, only Database tools are enabled. Use these flags to enable additiona **Available Tools:** -- `search_documentation` - Search Appwrite documentation -- `get_documentation_page` - Get specific documentation page -- `list_documentation_sections` - List available doc sections +- `search_documentation` - Search Appwrite documentation with natural language +- `get_documentation_page` - Get specific documentation page content +- `list_documentation_sections` - List available documentation sections - `get_api_reference` - Get API reference for specific endpoint -- `get_code_examples` - Get code examples for specific feature - -## Tool Usage Examples +- `get_code_examples` - Get code examples for specific features -### Database Operations - -**Create a database:** -```javascript -mcp_appwrite_api_databases_create({ - "database_id": "main", - "name": "Main Database", - "enabled": true -}) -``` - -**Create a collection:** -```javascript -mcp_appwrite_api_databases_create_collection({ - "database_id": "main", - "collection_id": "users", - "name": "Users", - "permissions": ["read(\"any\")"], - "document_security": true -}) -``` - -**Add attributes to collection:** -```javascript -// String attribute -mcp_appwrite_api_databases_create_string_attribute({ - "database_id": "main", - "collection_id": "users", - "key": "name", - "size": 255, - "required": true -}) +**Perfect for:** +- Learning Appwrite APIs and best practices +- Finding code examples and implementation patterns +- Troubleshooting errors and issues +- Understanding service capabilities +- Getting up-to-date documentation -// Email attribute -mcp_appwrite_api_databases_create_email_attribute({ - "database_id": "main", - "collection_id": "users", - "key": "email", - "required": true -}) +## Tool Usage Examples -// Boolean attribute -mcp_appwrite_api_databases_create_boolean_attribute({ - "database_id": "main", - "collection_id": "users", - "key": "is_active", - "required": true, - "default": true -}) -``` +### Using the Two-Tool Architecture -**Create a document:** -```javascript -mcp_appwrite_api_databases_create_document({ - "database_id": "main", - "collection_id": "users", - "document_id": "unique()", - "data": { - "name": "John Doe", - "email": "john@example.com", - "is_active": true - }, - "permissions": ["read(\"user:USER_ID\")"] -}) -``` +**Example 1: Create a Database** -**Query documents:** ```javascript -mcp_appwrite_api_databases_list_documents({ - "database_id": "main", - "collection_id": "users", - "queries": [ - "equal(\"is_active\", true)", - "orderDesc(\"$createdAt\")", - "limit(10)" - ] +// Step 1: Search for the right tool +appwrite_search_tools({ + "query": "create a new database" }) -``` -### User Management +// Returns: Tool definition for "databases_create" -**Create a user:** -```javascript -mcp_appwrite_api_users_create({ - "user_id": "unique()", - "email": "user@example.com", - "password": "SecurePass123!", - "name": "Jane Smith" +// Step 2: Call the tool +appwrite_call_tool({ + "tool_name": "databases_create", + "arguments": { + "database_id": "main", + "name": "Main Database", + "enabled": true + } }) ``` -**List users:** -```javascript -mcp_appwrite_api_users_list({ - "queries": ["limit(25)"], - "search": "john" -}) -``` +**Example 2: Create a User** -**Update user email:** ```javascript -mcp_appwrite_api_users_update_email({ - "user_id": "USER_ID", - "email": "newemail@example.com" +// Search +appwrite_search_tools({ + "query": "create user with email and password" +}) + +// Call +appwrite_call_tool({ + "tool_name": "users_create", + "arguments": { + "user_id": "unique()", + "email": "user@example.com", + "password": "SecurePass123!", + "name": "John Doe" + } }) ``` -### Storage Operations +**Example 3: Upload a File** -**Create a storage bucket:** ```javascript -mcp_appwrite_api_storage_create_bucket({ - "bucket_id": "avatars", - "name": "User Avatars", - "permissions": ["read(\"any\")"], - "file_security": true, - "enabled": true, - "maximum_file_size": 5000000, // 5MB - "allowed_file_extensions": ["jpg", "jpeg", "png", "gif"] +// Search +appwrite_search_tools({ + "query": "upload file to storage bucket" +}) + +// Call +appwrite_call_tool({ + "tool_name": "storage_create_file", + "arguments": { + "bucket_id": "avatars", + "file_id": "unique()", + "file": "/path/to/avatar.jpg", + "permissions": ["read(\"any\")"] + } }) ``` -**Upload a file:** -```javascript -mcp_appwrite_api_storage_create_file({ - "bucket_id": "avatars", - "file_id": "unique()", - "file": "/path/to/avatar.jpg", - "permissions": ["read(\"any\")"] -}) -``` +### Natural Language Queries -### Documentation Queries +The search tool understands natural language, so you can ask in various ways: -**Search documentation:** -```javascript -search_documentation({ - "query": "real-time subscriptions", - "limit": 5 -}) -``` +- "How do I create a collection?" +- "List all users in my project" +- "Upload an image to storage" +- "Deploy a serverless function" +- "Send an email notification" -**Get API reference:** -```javascript -get_api_reference({ - "endpoint": "/databases/{databaseId}/collections/{collectionId}/documents", - "method": "POST" -}) -``` +The AI will automatically search for the right tool and execute it. ## Common Workflows ### Workflow 1: Complete Database Setup ```javascript +// The AI will automatically search and call the right tools + // Step 1: Create database -const db = await mcp_appwrite_api_databases_create({ - "database_id": "main", - "name": "Main Database", - "enabled": true -}) +"Create a database called 'main'" +// AI searches for and calls: databases_create // Step 2: Create collection -const collection = await mcp_appwrite_api_databases_create_collection({ - "database_id": "main", - "collection_id": "posts", - "name": "Blog Posts", - "permissions": ["read(\"any\")"], - "document_security": true -}) +"Create a collection called 'posts' in the main database with public read access" +// AI searches for and calls: databases_create_collection // Step 3: Add attributes -await mcp_appwrite_api_databases_create_string_attribute({ - "database_id": "main", - "collection_id": "posts", - "key": "title", - "size": 255, - "required": true -}) - -await mcp_appwrite_api_databases_create_string_attribute({ - "database_id": "main", - "collection_id": "posts", - "key": "content", - "size": 10000, - "required": true -}) - -await mcp_appwrite_api_databases_create_datetime_attribute({ - "database_id": "main", - "collection_id": "posts", - "key": "published_at", - "required": false -}) +"Add a string attribute 'title' (max 255 chars, required) to the posts collection" +"Add a string attribute 'content' (max 10000 chars, required) to the posts collection" +"Add a datetime attribute 'published_at' (optional) to the posts collection" +// AI searches for and calls: databases_create_string_attribute (x2), databases_create_datetime_attribute -// Step 4: Create index for queries -await mcp_appwrite_api_databases_create_index({ - "database_id": "main", - "collection_id": "posts", - "key": "title_index", - "type": "key", - "attributes": ["title"] -}) +// Step 4: Create index +"Create an index on the title field for the posts collection" +// AI searches for and calls: databases_create_index // Step 5: Create first document -await mcp_appwrite_api_databases_create_document({ - "database_id": "main", - "collection_id": "posts", - "document_id": "unique()", - "data": { - "title": "Getting Started with Appwrite", - "content": "Appwrite is an amazing backend platform...", - "published_at": "2024-02-05T10:00:00.000Z" - } -}) +"Create a post with title 'Getting Started with Appwrite' and content '...'" +// AI searches for and calls: databases_create_document ``` ### Workflow 2: User Authentication Setup ```javascript -// Step 1: Create admin user -const admin = await mcp_appwrite_api_users_create({ - "user_id": "unique()", - "email": "admin@example.com", - "password": "SecureAdminPass123!", - "name": "Admin User" -}) +// Natural language workflow -// Step 2: Create team for organization -const team = await mcp_appwrite_api_teams_create({ - "team_id": "unique()", - "name": "Engineering Team" -}) +"Create an admin user with email admin@example.com" +// AI: searches for users_create, executes with proper parameters -// Step 3: Add user to team -await mcp_appwrite_api_teams_create_membership({ - "team_id": team.id, - "email": "admin@example.com", - "roles": ["owner"], - "url": "https://example.com/join-team" -}) +"Create a team called 'Engineering Team'" +// AI: searches for teams_create, executes -// Step 4: Set user preferences -await mcp_appwrite_api_users_update_prefs({ - "user_id": admin.id, - "prefs": { - "theme": "dark", - "notifications": true - } -}) +"Add the admin user to the Engineering Team as owner" +// AI: searches for teams_create_membership, executes + +"Set user preferences for dark theme and email notifications" +// AI: searches for users_update_prefs, executes ``` ### Workflow 3: File Upload and Management ```javascript -// Step 1: Create storage bucket -const bucket = await mcp_appwrite_api_storage_create_bucket({ - "bucket_id": "documents", - "name": "User Documents", - "permissions": ["read(\"any\")"], - "file_security": true, - "enabled": true, - "maximum_file_size": 10000000, // 10MB - "allowed_file_extensions": ["pdf", "doc", "docx", "txt"] -}) +// Conversational approach -// Step 2: Upload file -const file = await mcp_appwrite_api_storage_create_file({ - "bucket_id": "documents", - "file_id": "unique()", - "file": "/path/to/document.pdf", - "permissions": ["read(\"user:USER_ID\")"] -}) +"Create a storage bucket for user documents with 10MB limit, allowing PDF and DOCX files" +// AI: searches for storage_create_bucket, configures properly -// Step 3: Get file download URL -const download = await mcp_appwrite_api_storage_get_file_download({ - "bucket_id": "documents", - "file_id": file.id -}) +"Upload document.pdf to the documents bucket" +// AI: searches for storage_create_file, handles upload -// Step 4: List all files -const files = await mcp_appwrite_api_storage_list_files({ - "bucket_id": "documents", - "queries": ["limit(25)"] -}) +"Get the download URL for the uploaded file" +// AI: searches for storage_get_file_download, returns URL + +"List all files in the documents bucket" +// AI: searches for storage_list_files, returns list ``` ### Workflow 4: Serverless Function Deployment ```javascript -// Step 1: Create function -const func = await mcp_appwrite_api_functions_create({ - "function_id": "unique()", - "name": "Process Payment", - "runtime": "node-18.0", - "execute": ["any"], - "events": [], - "schedule": "", - "timeout": 15 -}) +// Simple natural language commands -// Step 2: Create deployment -const deployment = await mcp_appwrite_api_functions_create_deployment({ - "function_id": func.id, - "code": "/path/to/function.tar.gz", - "activate": true, - "entrypoint": "index.js" -}) +"Create a function called 'Process Payment' using Node.js 18 runtime" +// AI: searches for functions_create, sets up function -// Step 3: Set environment variables -await mcp_appwrite_api_functions_create_variable({ - "function_id": func.id, - "key": "STRIPE_API_KEY", - "value": "sk_test_...", - "secret": true -}) +"Deploy the function code from /path/to/function.tar.gz" +// AI: searches for functions_create_deployment, handles deployment -// Step 4: Execute function -const execution = await mcp_appwrite_api_functions_create_execution({ - "function_id": func.id, - "body": JSON.stringify({ amount: 1000, currency: "usd" }), - "xasync": false -}) +"Set environment variable STRIPE_API_KEY for the function" +// AI: searches for functions_create_variable, adds variable + +"Execute the function with payment data" +// AI: searches for functions_create_execution, runs function ``` ## Best Practices @@ -682,7 +510,7 @@ const execution = await mcp_appwrite_api_functions_create_execution({ **MCP Configuration:** -For API server (minimal - databases only): +**Minimal Configuration (MCP Server 2.0):** ```json { "mcpServers": { @@ -699,33 +527,19 @@ For API server (minimal - databases only): } ``` -For API server (with additional services): +**With Documentation Server:** ```json { "mcpServers": { "appwrite-api": { "command": "uvx", - "args": [ - "mcp-server-appwrite", - "--users", - "--storage", - "--functions", - "--sites" - ], + "args": ["mcp-server-appwrite"], "env": { "APPWRITE_PROJECT_ID": "${APPWRITE_PROJECT_ID}", "APPWRITE_API_KEY": "${APPWRITE_API_KEY}", "APPWRITE_ENDPOINT": "${APPWRITE_ENDPOINT}" } - } - } -} -``` - -For documentation server: -```json -{ - "mcpServers": { + }, "appwrite-docs": { "url": "https://mcp-for-docs.appwrite.io", "type": "http" @@ -734,29 +548,38 @@ For documentation server: } ``` -**Permissions:** API key should have appropriate scopes for intended operations. Use least privilege principle - only grant necessary permissions. +**Important Notes:** +- **No service flags needed** - All services are automatically available +- **Remove old flags** - If upgrading from v1.x, remove `--users`, `--storage`, `--functions`, etc. +- **Validation on startup** - Server validates credentials when it starts, not on first tool call +- **Using uvx** - Automatically fetches the latest version (0.4.1+) ## Tips -1. **Start with databases** - Most apps need data storage first -2. **Use document security** - Enable for collections with user-specific data -3. **Create indexes early** - Add indexes before large datasets -4. **Test permissions** - Verify access control works as expected -5. **Use query helpers** - Leverage Appwrite's query builder -6. **Monitor usage** - Check Appwrite console for metrics -7. **Enable real-time** - Use subscriptions for live updates -8. **Batch operations** - Use transactions for related changes -9. **Cache strategically** - Reduce API calls with smart caching -10. **Read the docs** - Use the docs MCP server for guidance -11. **Use TypeScript** - Type safety prevents many errors -12. **Version your schema** - Track database structure changes -13. **Test locally** - Use Appwrite CLI for local development -14. **Backup regularly** - Export data periodically -15. **Monitor logs** - Check function and API logs for issues +1. **Use natural language** - The search tool understands conversational queries +2. **All services available** - No need to enable specific services, everything works out of the box +3. **Minimal context usage** - MCP 2.0 architecture uses less context, leaving more room for your code +4. **Start with databases** - Most apps need data storage first +5. **Use document security** - Enable for collections with user-specific data +6. **Create indexes early** - Add indexes before large datasets +7. **Test permissions** - Verify access control works as expected +8. **Monitor usage** - Check Appwrite console for metrics +9. **Enable real-time** - Use subscriptions for live updates +10. **Batch operations** - Use transactions for related changes +11. **Cache strategically** - Reduce API calls with smart caching +12. **Read the docs** - Use the docs MCP server for guidance +13. **Use TypeScript** - Type safety prevents many errors +14. **Version your schema** - Track database structure changes +15. **Backup regularly** - Export data periodically +16. **Monitor logs** - Check function and API logs for issues +17. **Upgrade from v1.x** - Remove all service flags from your configuration ## Resources - [Appwrite Documentation](https://appwrite.io/docs) +- [MCP Server 2.0 Announcement](https://appwrite.io/blog/post/announcing-appwrite-mcp-server-2) +- [MCP Server GitHub Repository](https://github.com/appwrite/mcp-for-api) +- [MCP Server on PyPI](https://pypi.org/project/mcp-server-appwrite/) - [API Reference](https://appwrite.io/docs/references) - [Quick Starts](https://appwrite.io/docs/quick-starts) - [Database Guide](https://appwrite.io/docs/products/databases) @@ -770,6 +593,8 @@ For documentation server: --- **Package:** `mcp-server-appwrite` (Python via uvx) +**Version:** 0.4.1+ **Source:** Official Appwrite -**License:** BSD-3-Clause -**Connection:** Python MCP server with API key authentication +**License:** MIT +**Connection:** Python MCP server with API key authentication +**Architecture:** MCP Server 2.0 with two-tool design diff --git a/appwrite/steering/steering.md b/appwrite/steering/steering.md index cb8d454..9300394 100644 --- a/appwrite/steering/steering.md +++ b/appwrite/steering/steering.md @@ -1,6 +1,83 @@ # Appwrite Best Practices -This guide provides best practices for building applications with Appwrite. +This guide provides best practices for building applications with Appwrite, including guidance for using MCP Server 2.0. + +## MCP Server 2.0 Usage + +### Natural Language Queries + +**Use conversational language to interact with Appwrite:** + +```javascript +// ✅ Good: Natural language queries +"Create a database called 'production' with a 'users' collection" +"Add a user with email john@example.com and password SecurePass123" +"Upload profile.jpg to the avatars bucket" +"List all documents in the posts collection where status is published" + +// The AI will automatically: +// 1. Search for the right tool using appwrite_search_tools +// 2. Execute the operation using appwrite_call_tool +// 3. Return the result +``` + +### Understanding the Two-Tool Architecture + +**How MCP 2.0 works:** + +1. **Search Phase**: AI uses `appwrite_search_tools` with your natural language query +2. **Discovery Phase**: Server searches internal catalog and returns matching tool definitions +3. **Execution Phase**: AI calls `appwrite_call_tool` with the specific tool name and parameters +4. **Result Phase**: Server executes and returns the result + +```javascript +// Example flow: +User: "Create a new user" +↓ +AI: appwrite_search_tools({ query: "create user" }) +↓ +Server: Returns tool definition for "users_create" +↓ +AI: appwrite_call_tool({ + tool_name: "users_create", + arguments: { email: "...", password: "..." } +}) +↓ +Server: Executes and returns user creation result +``` + +### Migration from v1.x + +**Remove all service flags from your configuration:** + +```json +// ❌ Bad: Old v1.x configuration +{ + "args": [ + "mcp-server-appwrite", + "--users", + "--storage", + "--functions", + "--messaging" + ] +} + +// ✅ Good: New v2.0 configuration +{ + "args": ["mcp-server-appwrite"] +} +``` + +**All services are now automatically available:** +- Databases +- Users +- Storage +- Functions +- Messaging +- Sites +- Teams +- Locale +- Avatars ## Database Design