AgentDBDocs

Files and imports

With AgentDB you can:

  • keep files next to your records, such as a contract PDF on a deal;
  • share one file through a link that expires;
  • import a spreadsheet of contacts without pasting it into a chat;
  • export your data at any time.

Your AI does most of this for you. This page shows the calls it makes, so you know what happens.

#Upload a file

Your AI sends a small file as base64 with files_upload. It can attach the file to a record in the same call.

MCPChecked
{"tool": "files_upload", "arguments": {"filename": "notes.txt", "content_type": "text/plain", "content_base64": "SGVsbG8gZnJvbSBFeGFtcGxlIEx0ZC4K", "folder": "notes", "tags": ["example"]}}

The answer holds the file id, its size, its SHA-256 and its status.

  • Size: inline uploads go up to 4 MiB by default. workspace_info shows the exact limit.
  • Bigger files: the REST API and the CLI upload in two steps, and resume large uploads in parts.
  • Content never changes. To change a file, upload a new version. The file id stays the same.
  • Folders and tags help you find files later. A folder is a label such as contracts/2026.

From a terminal, the CLI uploads a file from disk: agentdb files upload ./contract.pdf --record rec_... --role contract.

#Attach a file to a record

One file can belong to several records. Each attachment has a role, such as invoice_pdf or photo.

In practice your AI attaches files to records you already have. The example first creates a client record:

MCPChecked
{"tool": "schema_define_object", "arguments": {"name": "client"}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "client", "name": "name", "type": "text", "unique": true}}
MCPChecked
{"tool": "records_create", "arguments": {"object": "client", "data": {"name": "Example Ltd"}}}
MCPChecked
{"tool": "files_attach", "arguments": {"file_id": "$FILE_ID", "record_id": "$CLIENT_ID", "role": "contract"}}

files_list with a record_id shows the files of one record. files_detach removes an attachment and keeps the file.

#Download a file

files_download returns the bytes as base64. Your AI also sees images as images.

MCPChecked
{"tool": "files_download", "arguments": {"file_id": "$FILE_ID"}}

A signed link lets someone open one file without an API key. Use it for a dashboard, an email or a web page.

MCPChecked
{"tool": "files_link_create", "arguments": {"file_id": "$FILE_ID", "expires_in_seconds": 3600}}
  • Expiry: from 60 seconds to 7 days. The default is 1 hour.
  • Who can open it: anyone who has the link, until it expires.
  • Stop it early: files_link_revoke ends the link at once. Deleting the file ends it too.
  • Access follows you: if you lose access to the file, your links stop working.
  • Inline display: only images, audio and video open in the browser. Other files always download.

#File types and media

AgentDB accepts the file types it can verify. That includes images, PDF, Office documents, text, CSV, JSON, audio and video.

  • AgentDB checks the first bytes of every upload against the declared type.
  • A file that does not match is refused with CONTENT_MISMATCH.
  • HTML, SVG and program files are refused by default.
  • For images, audio and video, AgentDB reads the size and duration. You find them in the file's metadata.
  • Text files are indexed. files_search finds words in file names and in text content.

See File types for the full list.

Store only synthetic or non-sensitive files while the service is in beta.

#Import a CSV, JSON or JSONL file

You can import hundreds of rows in one call. The file goes straight to AgentDB over HTTPS. It does not pass through the chat.

The steps:

  1. Your AI defines the object and a unique field to match on, such as email.
  2. It calls imports_start and gets a one-time upload link.
  3. It uploads the file to that link. Or it gives you a browser link to drop the file.
  4. It calls imports_inspect to see the columns, types and possible problems.
  5. It calls imports_run with dry_run: true first. Then it runs the import for real.

The upload link works once, for 30 minutes. It is not an API key and cannot read data.

MCPChecked
{"tool": "imports_start", "arguments": {"filename": "contacts.csv"}}

Your AI then uploads the file with the upload_url from the answer:

Shell
curl -sS --fail-with-body -T contacts.csv '<upload_url>'

A small file can also go through files_upload. The import tools accept its file_id. The next examples use that route.

MCPChecked
{"tool": "schema_define_object", "arguments": {"name": "contact"}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "contact", "name": "name", "type": "text"}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "contact", "name": "email", "type": "email", "unique": true}}
MCPChecked
{"tool": "files_upload", "arguments": {"filename": "contacts.csv", "content_type": "text/csv", "content_base64": "bmFtZSxlbWFpbApBZGEgTG92ZWxhY2UsYWRhQGV4YW1wbGUuY29tCkdyYWNlIEhvcHBlcixncmFjZUBleGFtcGxlLmNvbQo="}}

The file holds two rows: Ada Lovelace (ada@example.com) and Grace Hopper (grace@example.com).

MCPChecked
{"tool": "imports_inspect", "arguments": {"file_id": "$CSV_ID", "object": "contact"}}

imports_inspect reports per column: filled and empty counts, duplicates, the detected type and sample values. It also suggests match keys and spots spelling variants.

MCPChecked
{"tool": "imports_run", "arguments": {"file_id": "$CSV_ID", "object": "contact", "match_on": "email", "dry_run": true}}

A dry run does the whole import and then rolls it back. The report shows exactly what a real run would do.

MCPChecked
{"tool": "imports_run", "arguments": {"file_id": "$CSV_ID", "object": "contact", "match_on": "email"}}

How an import behaves:

  • Matching: a row with a new email creates a record. A known email updates that record.
  • Errors: each failed row is listed with its line, identifier, field and error code.
  • Partial or all-or-nothing: by default valid rows are imported. With atomic: true, one failed row stops the whole import.
  • Links: links connects each row to an existing record, such as a contact to its company.
  • Missing link targets: AgentDB never invents a missing company. on_unresolved_link decides what happens to that row.
  • Messy values: AgentDB never changes values by itself. It suggests fixes, and applies only the normalize rules you approve.
  • Large files: one call handles up to 10,000 rows. Continue with rows.offset for the rest.
  • Retries: run the same import again and nothing is duplicated. Rows report unchanged.

From a terminal: agentdb import contacts.csv --object contact --match-on email --dry-run.

#Export your data

Owners and admins can export records, links, schema and file metadata at any time. The export is NDJSON: one JSON object per line.

RESTChecked
curl https://app.agentdb.link/v1/workspaces/$AGENTDB_WORKSPACE/export \
  -H "Authorization: Bearer $AGENTDB_TOKEN"
  • ?objects=contact,company limits the export to some objects.
  • ?format=bundle returns a .tar.gz that also holds the file bytes.
  • Your AI can call records_export for small exports, up to 2 MiB.
  • From a terminal: agentdb data-export --output backup.ndjson, or add --bundle for files too.

workspace_import loads an export into a new workspace. It never merges into an existing one.