appwrite/agent-skills/appwrite-dotnet

Claude Code and agent skill by appwrite/agent-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Appwrite .NET SDK skill. Use when building server-side C# or .NET applications with Appwrite, including ASP.NET and Blazor integrations. Covers user management, database/table CRUD, file storage, and functions via API keys.

Install

npx vskill@latest install appwrite/agent-skills/appwrite-dotnet

SKILL.md

Appwrite .NET SDK

Installation

bash
dotnet add package Appwrite

Setting Up the Client

csharp
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
.SetEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.SetProject(Environment.GetEnvironmentVariable("APPWRITE_PROJECT_ID"))
.SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"));

Code Examples

User Management
csharp
var users = new Users(client);
// Create user
var user = await users.Create(ID.Unique(), "user@example.com", null, "password123", "User Name");
// List users
var list = await users.List(new List<string> { Query.Limit(25) });
// Get user
var fetched = await users.Get("[USER_ID]");
// Delete user
await users.Delete("[USER_ID]");
Database Operations
Note: Use TablesDB (not the deprecated Databases class) for all new code. Only use Databases if the existing codebase already relies on it or the user explicitly requests it.
Tip: Prefer named arguments (e.g., databaseId: "...") for all SDK method calls. Only use positional arguments if the existing codebase already uses them or the user explicitly requests it.
csharp
var tablesDB = new TablesDB(client);
// Create database
var db = await tablesDB.Create(ID.Unique(), "My Database");
// Create row
var doc = await tablesDB.CreateRow("[DATABASE_ID]", "[TABLE_ID]", ID.Unique(),
new Dictionary<string, object> { { "title", "Hello World" } });
// Query rows
var results = await tablesDB.ListRows("[DATABASE_ID]", "[TABLE_ID]",
new List<string> { Query.Equal("title", "Hello World"), Query.Limit(10) });
// Get row
var row = await tablesDB.GetRow("[DATABASE_ID]", "[TABLE_ID]", "[ROW_ID]");
// Update row
await tablesDB.UpdateRow("[DATABASE_ID]", "[TABLE_ID]", "[ROW_ID]",
new Dictionary<string, object> { { "title", "Updated" } });
// Delete row
await tablesDB.DeleteRow("[DATABASE_ID]", "[TABLE_ID]", "[ROW_ID]");
String Column Types
Note: The legacy string type is deprecated. Use explicit column types for all new columns.
TypeMax charactersIndexingStorage
varchar16,383Full index (if size ≤ 768)Inline in row
text16,383Prefix onlyOff-page
mediumtext4,194,303Prefix onlyOff-page
longtext1,073,741,823Prefix onlyOff-page
  • varchar is stored inline and counts towards the 64 KB row size limit. Prefer for short, indexed fields like names, slugs, or identifiers.
  • text, mediumtext, and longtext are stored off-page (only a 20-byte pointer lives in the row), so they don't consume the row size budget. size is not required for these types.
csharp
// Create table with explicit string column types
await tablesDB.CreateTable("[DATABASE_ID]", ID.Unique(), "articles",
new List<object> {
new { key = "title", type = "varchar", size = 255, required = true }, // inline, fully indexable
new { key = "summary", type = "text", required = false }, // off-page, prefix index only
new { key = "body", type = "mediumtext", required = false }, // up to ~4 M chars
new { key = "raw_data", type = "longtext", required = false }, // up to ~1 B chars
});
Query Methods
csharp
// Filtering
Query.Equal("field", "value") // == (or pass array for IN)
Query.NotEqual("field", "value") // !=
Query.LessThan("field", 100) // <
Query.LessThanEqual("field", 100) // <=
Query.GreaterThan("field", 100) // >
Query.GreaterThanEqual("field", 100) // >=
Query.Between("field", 1, 100) // 1 <= field <= 100
Query.IsNull("field") // is null
Query.IsNotNull("field") // is not null
Query.StartsWith("field", "prefix") // starts with
Query.EndsWith("field", "suffix") // ends with
Query.Contains("field", "sub") // contains
Query.Search("field", "keywords") // full-text search (requires index)
// Sorting
Query.OrderAsc("field")
Query.OrderDesc("field")
// Pagination
Query.Limit(25) // max rows (default 25, max 100)
Query.Offset(0) // skip N rows
Query.CursorAfter("[ROW_ID]") // cursor pagination (preferred)
Query.CursorBefore("[ROW_ID]")
// Selection & Logic
Query.Select(new List<string> { "field1", "field2" })
Query.Or(new List<string> { Query.Equal("a", 1), Query.Equal("b", 2) }) // OR
Query.And(new List<string> { Query.GreaterThan("age", 18), Query.LessThan("age", 65) }) // AND (default)
Query.Relationship("comments", new List<string> { Query.Equal("approved", true), Query.Limit(25) }) // related documents
// Aggregations (optional alias)
Query.Count("*", "total")
Query.Sum("amount", "revenue")
Query.Avg("score", "avgScore")
Query.Min("price", "minPrice")
Query.Max("price", "maxPrice")
// Grouping
Query.GroupBy(new List<string> { "status", "year" })
Query.Having(new List<string> { Query.GreaterThan("total", 1) })
Query.Distinct()
// Joins (table id, left key, right key, operator, alias)
Query.Join("orders", "$id", "customerId")
Query.LeftJoin("orders", "$id", "customerId", "=", "ord")
Query.LeftJoin("orders", "ord", new List<string> {
Query.On("$id", "customerId"),
Query.Equal("ord.status", "paid"),
})
// Fluent builder. Pass Build() into list methods.
var queries = new Query.Builder()
.Equal("status", "published")
.LeftJoin("orders", "$id", "customerId", "=", "ord")
.Count("*", "total")
.GroupBy(new List<string> { "status" })
.Limit(25)
.Build();
await tablesDB.ListRows("[DATABASE_ID]", "[TABLE_ID]", queries);
File Storage
csharp
var storage = new Storage(client);
// Upload file
var file = await storage.CreateFile("[BUCKET_ID]", ID.Unique(), InputFile.FromPath("/path/to/file.png"));
// List files
var files = await storage.ListFiles("[BUCKET_ID]");
// Delete file
await storage.DeleteFile("[BUCKET_ID]", "[FILE_ID]");
InputFile Factory Methods
csharp
using Appwrite.Models;
InputFile.FromPath("/path/to/file.png") // from filesystem path
InputFile.FromBytes(byteArray, "file.png", "image/png") // from byte[]
InputFile.FromStream(stream, "file.png", "image/png", size) // from Stream (size required)
Teams
csharp
var teams = new Teams(client);
// Create team
var team = await teams.Create(ID.Unique(), "Engineering");
// List teams
var list = await teams.List();
// Create membership (invite user by email)
var membership = await teams.CreateMembership(
teamId: "[TEAM_ID]",
roles: new List<string> { "editor" },
email: "user@example.com"
);
// List memberships
var members = await teams.ListMemberships("[TEAM_ID]");
// Update membership roles
await teams.UpdateMembership("[TEAM_ID]", "[MEMBERSHIP_ID]", new List<string> { "admin" });
// Delete team
await teams.Delete("[TEAM_ID]");
Role-based access: Use Role.Team("[TEAM_ID]") for all team members or Role.Team("[TEAM_ID]", "editor") for a specific team role when setting permissions.
Serverless Functions
csharp
var functions = new Functions(client);
// Execute function
var execution = await functions.CreateExecution("[FUNCTION_ID]", body: "{\"key\": \"value\"}");
// List executions
var executions = await functions.ListExecutions("[FUNCTION_ID]");
Writing a Function Handler (.NET runtime)
csharp
// src/Main.cs — Appwrite Function entry point
using System.Text.Json;
public async Task<RuntimeOutput> Main(RuntimeContext context)
{
// context.Req.Body — raw body (string)
// context.Req.BodyJson — parsed JSON (JsonElement)
// context.Req.Headers — headers (Dictionary)
// context.Req.Method — HTTP method
// context.Req.Path — URL path
// context.Req.Query — query params (Dictionary)
context.Log($"Processing: {context.Req.Method} {context.Req.Path}");
if (context.Req.Method == "GET")
return context.Res.Json(new { message = "Hello from Appwrite Function!" });
return context.Res.Json(new { success = true }); // JSON
// context.Res.Text("Hello"); // plain text
// context.Res.Empty(); // 204
// context.Res.Redirect("https://..."); // 302
}
Server-Side Rendering (SSR) Authentication

SSR apps using .NET frameworks (ASP.NET, Blazor Server, etc.) use the server SDK to handle auth. You need two clients:

  • Admin client — uses an API key, creates sessions, bypasses rate limits (reusable singleton)
  • Session client — uses a session cookie, acts on behalf of a user (create per-request, never share)
csharp
using Appwrite;
using Appwrite.Services;
// Admin client (reusable)
var adminClient = new Client()
.SetEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.SetProject("[PROJECT_ID]")
.SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY"));
// Session client (create per-request)
var sessionClient = new Client()
.SetEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.SetProject("[PROJECT_ID]");
var session = Request.Cookies["a_session_[PROJECT_ID]"];
if (session != null)
{
sessionClient.SetSession(session);
}
Email/Password Login (ASP.NET Minimal API)
csharp
app.MapPost("/login", async (HttpContext ctx, LoginRequest body) =>
{
var account = new Account(adminClient);
var session = await account.CreateEmailPasswordSession(body.Email, body.Password);
// Cookie name must be a_session_<PROJECT_ID>
ctx.Response.Cookies.Append("a_session_[PROJECT_ID]", session.Secret, new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict,
Path = "/",
});
return Results.Ok(new { success = true });
});
Authenticated Requests
csharp
app.MapGet("/user", async (HttpContext ctx) =>
{
var session = ctx.Request.Cookies["a_session_[PROJECT_ID]"];
if (session == null) return Results.Unauthorized();
var sessionClient = new Client()
.SetEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.SetProject("[PROJECT_ID]")
.SetSession(session);
var account = new Account(sessionClient);
var user = await account.Get();
return Results.Ok(user);
});
OAuth2 SSR Flow
csharp
// Step 1: Redirect to OAuth provider
app.MapGet("/oauth", async () =>
{
var account = new Account(adminClient);
var redirectUrl = await account.CreateOAuth2Token(
provider: OAuthProvider.Github,
success: "https://example.com/oauth/success",
failure: "https://example.com/oauth/failure"
);
return Results.Redirect(redirectUrl);
});
// Step 2: Handle callback — exchange token for session
app.MapGet("/oauth/success", async (HttpContext ctx, string userId, string secret) =>
{
var account = new Account(adminClient);
var session = await account.CreateSession(userId, secret);
ctx.Response.Cookies.Append("a_session_[PROJECT_ID]", session.Secret, new CookieOptions
{
HttpOnly = true, Secure = true, SameSite = SameSiteMode.Strict, Path = "/",
});
return Results.Ok(new { success = true });
});
Cookie security: Always use HttpOnly, Secure, and SameSite = SameSiteMode.Strict to prevent XSS. The cookie name must be a_session_<PROJECT_ID>.
Forwarding user agent: Call sessionClient.SetForwardedUserAgent(ctx.Request.Headers["User-Agent"]) to record the end-user's browser info for debugging and security.

Error Handling

csharp
using Appwrite;

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
11
7-day trend score
12

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 23 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/appwrite/agent-skills/appwrite-dotnet/badge)](https://verified-skill.com/skills/appwrite/agent-skills/appwrite-dotnet)

Something wrong with this skill or its page? Tell us.