MCP Tools
Rekor offers two MCP interfaces for different stages of the agent lifecycle:
| Interface | For whom | What it does | Endpoint |
|---|---|---|---|
| Admin MCP | Agent builders | 13 generic tools for setup: create bases, define schemas, manage inbound webhooks/triggers, configure endpoints | mcp.rekor.pro/mcp |
| MCP Factory | Specialized agents | Custom, domain-specific tools generated from your record_type schemas (e.g., create_invoice, list_payments) | mcp.rekor.pro/t/{slug}/mcp |
Use the Admin MCP to build your data model. Use MCP Factory toolsets to let production agents use it — with tools tailored to their specific domain.
Admin MCP
Sixteen tools that give AI agents full CRUD over bases, record_types, records, relationships, files, and integrations. Each tool supports multiple actions via an action parameter — one tool per domain, not one tool per operation.
Connecting an Agent
Point any MCP-compatible client at Rekor's MCP server.
Claude Desktop / Claude Code
Add this to your MCP config:
{
"mcpServers": {
"rekor": {
"url": "https://mcp.rekor.pro/mcp",
"headers": {
"Authorization": "Bearer rec_your_token_here"
}
}
}
}
Any MCP Client
The MCP server endpoint is https://mcp.rekor.pro/mcp (Streamable HTTP). Pass a Bearer token for authentication.
Discovery Pattern
Agents should always start with manage_base(list) to discover available bases, then manage_record_type(list) to see what data types exist. This gives the agent full context before it starts reading or writing.
// Step 1: What bases exist?
manage_base({ action: "list" })
// Step 2: What record_types does this base have?
manage_record_type({ action: "list", base_id: "crm" })
// Step 3: Read or write records
sql_query({ base_id: "crm", query: "SELECT * FROM records WHERE org_id = {org_id:String} AND base_id = {base_id:String} AND record_type = 'contacts' AND deleted = false LIMIT 10" })
Common Workflows
CRUD a record
// Create or update
manage_record({ action: "upsert", base_id: "crm", record_type: "contacts",
external_id: "c_001", external_source: "crm",
data: { name: "Jane Doe", email: "jane@acme.com" } })
// Read
manage_record({ action: "get", base_id: "crm", record_type: "contacts", id: "..." })
// Delete
manage_record({ action: "delete", base_id: "crm", record_type: "contacts", id: "..." })
Query with SQL
// Filter + sort
sql_query({ base_id: "crm",
query: "SELECT data.title.:String as deal, CAST(data.value, 'Float64') as value FROM records WHERE org_id = {org_id:String} AND base_id = {base_id:String} AND record_type = 'deals' AND data.stage.:String = 'negotiation' AND deleted = false ORDER BY value DESC LIMIT 20" })
// Aggregate
sql_query({ base_id: "crm",
query: "SELECT data.stage.:String as stage, sum(CAST(data.value, 'Float64')) as pipeline FROM records WHERE org_id = {org_id:String} AND base_id = {base_id:String} AND record_type = 'deals' AND deleted = false GROUP BY stage" })
Link records with relationships
// Declare the relationship type once (config — preview then promote)
manage_relationship_type({ action: "upsert", base_id: "crm",
rel_type: "owns", source_record_types: ["contacts"], target_record_types: ["deals"] })
// Create a relationship
manage_relationship({ action: "upsert", base_id: "crm",
rel_type: "owns", source_record_type: "contacts", source_id: "c_001",
target_record_type: "deals", target_id: "d_001" })
// Traverse
query_relationships({ base_id: "crm", record_type: "contacts",
record_id: "c_001", rel_type: "owns", direction: "outgoing" })
Available Tools
| Tool | Description |
|---|---|
batch_operations | Execute multiple record, relationship, and record_type operations atomically. All operations succeed or all fail. Use for transactions, multi-entity writes, or any case where consistency between operations is required. Max 1,000 operations. |
get_change_history | Retrieve the change history (audit log) for a record, relationship, record_type, or relationship type — every version as a full snapshot, plus who changed it (actor), the operation (create/update/delete/cancel/archive), and when. Admin-only: organization owners/admins, or a token explicitly granted read:audit; ordinary agent tokens receive 403. |
manage_attachment | Manage file attachments on records. Filenames can include paths for folder structure (e.g. 'docs/guide.md', 'src/index.ts'). Upload returns a presigned URL — the agent uploads bytes directly. |
manage_base | Manage bases. Actions: create, get, list, delete, create_preview, list_previews. Start here to discover existing bases before operating. Note: schema changes (record_types, triggers, inbound webhooks) can only be made in preview bases. Use create_preview to create a preview from a production database, then promote via CLI. |
manage_file | Manage files (path-addressed, versioned content) within a file type. Actions: create (upload text content, mints a content version), get (metadata; ?version reads a retained one), list (by path prefix), move (rename), delete, history (list content versions), diff (compare two versions — metadata delta + text content diff). Binary uploads/downloads use the CLI or REST; this tool handles text content and metadata. |
manage_file_type | Manage file types (Buckets) — the config for a set of files: storage policy + optional metadata schema. Actions: upsert, get, list, delete. Config writes require a preview database. |
manage_inbound_webhook | Manage inbound webhook endpoints. Inbound webhooks accept JSON and upsert through the normal write path; an optional mapping canonicalizes the received payload to the record_type's schema before write. |
manage_record | Create, read, update, patch, delete, or cancel individual records. 'upsert' (PUT) writes the FULL record — send every field; supply external_id (and optional external_source) for idempotent writes from external systems (the internal UUID is auto-generated). 'patch' is a PARTIAL update — send only the fields you want to change and the rest are kept (top-level merge; nested objects replaced wholesale). Use patch to flip a status or set a flag without re-sending the whole record; it addresses an existing record by record_id or external_id and 404s if none exists. (For a record_type backed by an external source, the provided fields are forwarded to that upstream system, which decides how they are applied.) Use record_id (internal UUID) for get/delete/cancel or to address a known record. Records may be archived (_archived: true in response) — an archived record stays readable and can still be cancelled, but it cannot be deleted, and re-upserting by the same external_id creates a new record rather than updating the archived one. Keep record data small (structured JSON only) — store binary or large content (PDFs, images, files) as an attachment via manage_attachment and reference it from the record; oversized payloads are rejected. |
manage_record_type | Manage record_type schemas. Actions: upsert, get, list, delete. Use list to discover what record_types exist in a database. |
manage_relationship | Create, read, update, or delete relationships between records. Relationships are typed, directed links with optional metadata. |
manage_relationship_type | Manage relationship types. A relationship type must exist before any relationship of that type can be created — it optionally validates the relationship's metadata against a JSON Schema and restricts which record_types it may connect. Actions: upsert, get, list, delete. |
manage_trigger | Manage triggers. A webhook trigger fires a signed HTTP POST when records/relationships change; an internal_write trigger makes Rekor patch a referenced record itself (no executor); an external_write trigger writes the changed record out through an external source's write path (reusing its translation, endpoint, and auth) and links the upstream-assigned id back (no executor). |
provider_adapter | Convert between LLM provider tool formats (openai, anthropic, google, mcp) and Record record_types. Actions: import_tools (create record_types from tool definitions), export_tools (export record_types as tool definitions), import_tool_call (create a record from a tool call in provider format). |
query_records | List and search records in a record_type. Supports exact filtering, fuzzy text search, sorting, and pagination via the Filter DSL. Use the `search` operator on a field to match approximate values when you don't have the exact stored string (e.g. {"field":"data.car_model","op":"search","value":"honda civic"}); results come back ranked by closeness with a `_search_score`. Combine `search` with exact operators (eq/in/gte/...) in the same filter to narrow first, then rank. |
query_relationships | Query relationships for a specific record. Find related records by type and direction. |
sql_query | Execute a read-only SQL query against database data. Tables: records, relationships, record_types, bases, operations_log. Always include BOTH org_id = {org_id:String} AND base_id = {base_id:String}, plus deleted = false, in WHERE (a database id is per-org, not globally unique, so org_id is required to isolate your data). Queries return the latest version of each row automatically. |
MCP Factory
For production agents that need domain-specific tools instead of generic CRUD, see MCP Factory. Create custom toolsets where agents see create_invoice and list_payments — not manage_record.