About appwrite-backend
appwrite-backend is a skill for agents working with Appwrite. It routes tasks to focused guidance and sets rules for safe data operations, SDK selection, and production changes.
Key features
- 01Routes Appwrite tasks to specialized guidance
- 02Defines safe mutation and migration practices
- 03Guides SDK selection by runtime and target
- 04Sets rules for ACLs, retries, and limits
Use cases
- 01Plan a production schema or data migration
- 02Handle bulk writes and transaction boundaries
- 03Choose an SDK for an Appwrite runtime
MCP support
For agent operations, the skill requires using MCP server guidance and reporting capability gaps rather than falling back to SDKs, HTTP, or the command line.
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ sgaabdu4/ appwrite-backend --skill appwrite-backendAfter installing, type/appwrite-backendin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/atomic-operators.mdauth-methods.mdauthentication.mdavatars.mdbulk-operations.mdchunked-queries.mdcost-optimization.mddestructive-erasure.mderror-handling.mdfunctions-advanced.mdfunctions.mdgraphql.mdhealth.mdlimits.mdlocale.mdmcp-servers.mdmessaging.mdpagination-performance.mdperformance.mdpermissions.mdproduction-migrations.mdquery-optimization.mdrealtime.mdrelationships.mdschema-management.mdself-hosting-ops.mdself-hosting.mdstorage-files.mdteams.mdtransactions.mdDetails
From the project READMEAppwrite Development
Route
Load the owner before acting. Unlisted detail = read the owner, never infer.
| Trigger | Owner |
|---|---|
| Any agent operation against Appwrite, MCP server setup, or Appwrite documentation lookup | mcp-servers |
| Production schema/data/ACL/function cutover | production-migrations + transactions when writes share a transaction |
| TablesDB transaction or cross-service consistency | transactions + permissions when ACLs change |
| Permanent account/subject-data erasure across TablesDB, Auth, Storage, provider data, or retained audit evidence | destructive-erasure + transactions |
| Mass row create/update/upsert/delete, transaction-limit pressure, per-row write loop | bulk-operations + transactions when atomic scope spans requests/tables |
Filter by more IDs than the deployed Query.equal() value cap | chunked-queries |
| Table/column/index design, encryption at rest, auto-increment, timestamp override, CSV import/export | schema-management |
Query shape, select, spatial, time helpers, missing-index suspicion | query-optimization |
| Counter, array, string, or date field mutated concurrently | atomic-operators |
| Relationship modeling or traversal | relationships |
| List, feed, infinite scroll, or large-offset paging | pagination-performance |
| Slow path, caching, delta sync, bootstrap ordering | performance |
| Bandwidth, execution, or storage cost | cost-optimization |
| Sessions, MFA, SSR auth, JWT, user labels, security settings | authentication |
| OAuth, magic link, email OTP, phone, anonymous, custom token, email verification, password recovery, session list/delete, user preferences | auth-methods |
| ACL design, lockout, public-leak suspicion | permissions |
| Team, membership, or multi-tenancy | teams |
| Upload, download, preview, transform, bucket config | storage-files |
| Function authoring, handler, runtime, cold start, env vars | functions |
| Function events, schedules, idempotency, binary payloads, CI/CD | functions-advanced |
| Function execution SDK model or response-format parsing failure, execution mode, response retrieval or execution timeout | functions-advanced |
| Realtime subscription, channel, presence, event filtering | realtime |
| Push, email, or SMS delivery | messaging |
| Outbound event delivery to an external system | webhooks |
| Avatar, initials, QR, flag, favicon | avatars |
429, retry, typed error, timeout, code-zero transport failure, client request burst, partial-sync report | error-handling + performance for startup/bootstrap request bursts |
| Platform ceiling or limit error | limits |
| Country, currency, language, or geo lookup | locale |
| GraphQL endpoint | graphql |
| Self-hosted install, config, security, scaling, SDK version pins | self-hosting |
| Self-hosted backup, restore, upgrade, data-loss incident | self-hosting-ops |
| Health check, queue depth, uptime monitoring | health |
Invariants
- MCP for agent operations; official SDKs for application code — agent reads, mutations, deployments, and diagnosis use mcp-servers. Missing MCP capability → report the gap; no direct SDK, HTTP, or command-line fallback for agent operations. Application code uses official SDKs; raw Appwrite HTTP (
fetch,requests,dio,package:http,curl) requires a missing SDK endpoint or an isolated, testedClient.callmodel-parsing workaround. - Pin SDKs by target and call shape — Cloud: latest stable official SDK. Self-hosted: exact release-matched pins for the deployed server version (
2.xor1.9.x) in self-hosting. “Compatible with1.9.x” does not mean release-matched. Before changing a pin, audit every intervening breaking change and prove the repository's real SDK calls against the candidate; version resolution alone is insufficient. A verified repository SDK pin outranks a skill pin. - TablesDB, not the legacy
Databasesservice — its Collections/Documents API is deprecated since1.8.0. DocumentsDB and VectorsDB are separate services, not that legacy API. - Allocate Appwrite IDs once with
ID.unique()— retryable create: callID.unique()before the first attempt → persist the returned ID in the durable draft/intent → reuse that exact ID for every retry/reconciliation. A freshID.unique()on retry creates a second resource. Business/natural identity remains in indexed columns; never derive resource IDs from names, timestamps, slugs, hashes, or custom generators. - Explicit ACL — server SDK/Console create = empty resource ACL; client SDK create = creator read/update/delete. Pass explicit
Permission/Rolewhenever ACL correctness matters. - Bind limits to the deployed target — page size, bulk rows/request, transaction operations, and
Query.equal()value cap come from the deployed server source/config, never from memory. - Choose execution mode by the required result — response data → synchronous
createExecutionwithin its 30-second limit. Async background work → bounded status monitoring + source-of-truth reconciliation; execution polling/realtime cannot return the response body or headers. Long-running results need an authorized durable result read. Report destructive failure only after reconciliation proves the entity still exists. Consume synchronous responses directly; ambiguous status/404→ reconcile before retrying. Use functions-advanced. - Prove destructive scope — schema/access contraction requires complete live inventory + exact approved resource IDs + backup/recovery proof. Missing fields, incomplete pagination, or unknown access effects fail closed. Use production-migrations.
- Stage production migrations — additive expand → type-aware resumable backfill → compatible deployment → contract/read-back → consumer activation. Partial data/schema never activates downstream code. Use production-migrations.
- Preserve write intent before optimizing — update-only work never routes through
upsertRow/upsertRows; a pre-read, existence check, or full payload does not remove create-on-missing semantics. Same patch across rows →updateRows; heterogeneous per-row updates →createOperationswithaction: updateinside the verified transaction budget, or redesign. Transaction pressure never authorizes upsert. Use bulk-operations. - Batch collection writes before coding — target count can exceed one or is data-dependent → inventory the full mutation set + deployed limits before implementation. Compatible server bulk method exists → per-row write loop is forbidden. Bulk is unsupported → complete operation budget + atomic late-failure proof required. Full plan over cap → redesign or resumable fixed-point workflow; never split one atomic invariant across committed batches. Use bulk-operations + transactions.
- Preserve failure causality — cleanup, compensation, or rollback failure never replaces the primary exception. Retain both errors + stack traces + execution/transaction IDs, report the operation failed, then reconcile the exact postcondition. Use transactions.
- Coordinate client demand and uncertain outcomes — one endpoint/project-scoped coordinator owns foreground, sync, auth, and retry traffic. Bound concurrency; share 429/transport cooldowns; classify code-zero network failures; retry reads within one deadline; reconcile writes/transactions before any repeat; report one incident per failed operation; and never advance a sync checkpoint after partial failure. Use error-handling.
SDK Routing
| Runtime | Package |
|---|---|
| Web TypeScript/JavaScript/React | appwrite |
| Node.js/Deno/TypeScript SSR/Functions | node-appwrite |
| Flutter client | appwrite |
| Dart server/Functions | dart_appwrite |
| Python server/Functions | appwrite |
- Call style: TypeScript object parameters, Python keyword arguments, Dart named parameters. Positional only when matching existing code or on explicit request.
- Client SDKs use account sessions and user-scoped APIs. Server SDKs use API keys. SSR uses two clients: a reusable admin client for session creation, and a per-request session client via
setSession(...)— never shared. - Cloud project endpoint =
https://<REGION>.cloud.appwrite.io/v1. - Initialize clients outside warm Function handlers where the runtime allows.
Resources
Docs https://appwrite.io/docs · API https://appwrite.io/docs/apis/rest · SDKs https://github.com/appwrite
Comments
Markdown supported