MoonDB exposes an MCP endpoint at POST /mcp so AI agents can manage projects through a single JSON-RPC 2.0 interface instead of crafting individual REST calls. Native integration is supported by Cursor, Claude Code, and Windsurf.
.cursor/mcp.json{
"mcpServers": {
"moondb": {
"url": "https://moondb.ai/mcp",
"headers": { "X-API-Key": "mk_..." }
}
}
}
claude mcp add --transport http \ moondb https://moondb.ai/mcp \ --header "X-API-Key: mk_..."
~/.codeium/windsurf/mcp_config.json{
"mcpServers": {
"moondb": {
"serverUrl": "https://moondb.ai/mcp",
"headers": { "X-API-Key": "mk_..." }
}
}
}
Get your mk_… account key from the dashboard Account tab.
Pass your API key as X-API-Key: mk_... or Authorization: Bearer mk_.... All tools operate on projects owned by the authenticated account.
Every request is a JSON-RPC 2.0 envelope:
POST /mcp
Content-Type: application/json
X-API-Key: mk_...
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": { "name": "create_project", "arguments": { "name": "my-app" } } }
id)MCP clients send JSON-RPC notifications such as notifications/initialized right after initialize. Per JSON-RPC 2.0 the server MUST NOT respond — MoonDB returns HTTP 202 Accepted with an empty body for any envelope that omits id or whose method starts with notifications/.
A request with an unrecognised method returns a JSON-RPC error envelope (error.code: -32601 "Method not found", HTTP 200), not HTTP 404 — so clients don't treat the endpoint as missing.
initialize — returns server info, capabilities, and an instructions field that primes the model on MoonDB's schema conventions (auth_table, owner_field, ref types, no SQL columns, confirm_destructive) plus the REST surfaces (/auth/*, /storage/*, /ai/*) that generated app code should call. MCP clients inject instructions into the model's system context.notifications/* — accepted with 202 (see above).tools/list — returns all tool definitions.tools/call — executes a tool with provided arguments.ping — health-check, returns empty result.| Tool | Description | Required args |
|---|---|---|
create_project | Create a new project. Returns admin_key + public_key (admin shown once). | name |
list_projects | List every project owned by the calling account, with api_url and public_key. | — |
rotate_keys | Rotate admin_key and/or public_key. Previous keys are invalidated immediately. | project_id, one of admin/public/both |
| Tool | Description | Required args |
|---|---|---|
set_schema | Apply schema & auto-migrate. Tool description embeds the full schema reference so the model has the format inline. | project_id, schema (full { "tables": { ... } } object) |
validate_schema | Dry-run: parse + validate + diff against current schema without mutating anything. Same migrations / warnings / destructive flag set_schema would return. | project_id, schema |
get_schema | Current schema + tables_info summary. Call before set_schema to see what already exists. | project_id |
seed | Bulk insert with topological ordering and @table.index cross-refs. For auth_table rows send "password" plain — MoonDB hashes server-side. | project_id, data: { table: [rows] } |
get_reference | Return the full canonical agent reference (same source as /v1/llm-context). With project_id, returns the project-scoped version including current schema. | — (project_id optional) |
| Tool | Description | Required args |
|---|---|---|
query | Filtered SELECT. Supports the full operator set (eq, neq, gt, gte, lt, lte, like, in, is_null, not_null) via {"field": "<op>.<value>"}; bare value = eq. Also sort (comma-separated) and select. | project_id, table |
get_row | Fetch one row by id. Hidden columns are stripped. | project_id, table, id |
insert | Insert one row (object) or many (array). Server-managed columns (id, created_at, updated_at, password_hash) are auto-filled. | project_id, table, data |
update_row | PATCH-semantics: only fields you send change; omitted columns keep their value. | project_id, table, id, data |
delete_row | Hard delete (or soft delete if schema.options.soft_delete: true). Cascade rules from refs apply. | project_id, table, id |
| Tool | Description | Required args |
|---|---|---|
ai_call | Call an AI endpoint declared under ai_endpoints in the schema. Text models return result; image models return base64. | project_id, endpoint |
# 1. Create project { "jsonrpc":"2.0", "id":1, "method":"tools/call", "params":{"name":"create_project","arguments":{"name":"todo-app"}} } # 2. Dry-run the schema before applying { "jsonrpc":"2.0", "id":2, "method":"tools/call", "params":{"name":"validate_schema","arguments":{ "project_id":"...", "schema":{"tables":{"tasks":{"columns":{"title":"string required","done":"bool default false"}}}} }} } # 3. Apply schema { "jsonrpc":"2.0", "id":3, "method":"tools/call", "params":{"name":"set_schema","arguments":{ "project_id":"...", "schema":{"tables":{"tasks":{"columns":{"title":"string required","done":"bool default false"}}}} }} } # 4. Seed demo data with cross-refs { "jsonrpc":"2.0", "id":4, "method":"tools/call", "params":{"name":"seed","arguments":{ "project_id":"...", "data":{"tasks":[{"title":"Buy milk"},{"title":"Walk dog"}]} }} } # 5. Query with operators + sort { "jsonrpc":"2.0", "id":5, "method":"tools/call", "params":{"name":"query","arguments":{ "project_id":"...","table":"tasks", "filters":{"done":"eq.false"}, "sort":"created_at.desc","select":"id,title" }} }
End-user auth (/auth/*), file upload/download (/storage/*), and runtime AI calls from the user-facing app are intentionally not MCP tools. The agent's job there is to generate fetch() calls in the user's application code that hit the project's REST endpoints — not to perform those operations itself. The initialize.instructions primer documents these REST surfaces explicitly.