# Indexify — Agent Guide (API + MCP)

This document is designed to be **pasted into an LLM/coding agent context** by **paying Indexify developers**. It describes what agents can do with **Indexify (hosted SaaS)** via:

- **HTTP API** (full surface area, including mutations like uploads and job control)
- **MCP server** (read-oriented tools for retrieval and inspection)

If you only need the formal contract and exact schemas, use the OpenAPI spec instead:
- **OpenAPI**: `/api/api-spec.yml`

## Quick discovery (canonical URLs)

- **Agent guide (this file)**: `/agents/indexify.md`
- **LLM discovery**: `/.well-known/llms.txt`
- **OpenAPI**: `/api/api-spec.yml`
- **MCP OAuth resource metadata (RFC 9728)**: `/.well-known/oauth-protected-resource` on the MCP host (Bearer minting still uses your Indexify API `POST /oauth/token`; **`authorization_servers`** in metadata lists issuer URLs)

## Key concepts

- **Project**: top-level tenant boundary (auth scopes are project-scoped).
- **Knowledge base (KB)**: container of documents, settings (parsing, embedding), and search.
- **Document**: uploaded file + metadata. Processing produces parsed outputs, chunks, elements, tables/figures, artifacts.
- **Job**: asynchronous processing lifecycle for ingestion/reprocessing and derived assets (pipeline stages; completion is not immediate).
- **Webhook**: per-KB outbound notifications for job lifecycle events (HTTP-only, not via MCP).

## Authentication / tokens (how agents should authenticate)

Indexify uses **project access tokens** (JWT) for most project APIs and for MCP calls.

- **Prerequisite**: you must have an Indexify account and a project with client credentials.
- **Mint a project token**: `POST /oauth/token` with **`application/x-www-form-urlencoded`** body: `grant_type=client_credentials`, `client_id`, `client_secret` (credentials in the body only; HTTP Basic is not supported)
- **Use the token**:
  - **HTTP**: `Authorization: Bearer <project_access_token>`
  - **MCP**: include the same Bearer token on every request to the MCP endpoint
- **Automatic client setup**: MCP hosts may fetch **`GET /.well-known/oauth-protected-resource`** to discover **`resource`** (protected MCP id) and **`authorization_servers`** before minting tokens.

Agents should request only the scopes needed. Common read scopes for retrieval:
- `kb:read`
- `search:run`
- `docs:parsed:read`

Mutations like ingest/delete/job controls require additional scopes (see OpenAPI).

## MCP vs HTTP: what to use when

### Use MCP when you are *retrieving or inspecting*
MCP tools are optimized for agent retrieval loops:
- list KBs, documents
- search (including enriched variants)
- fetch parsed outputs, chunks, elements, sections, relationships
- inspect artifacts metadata (but not binary content download)

### Use HTTP when you need *mutations or operational control*
Use the HTTP API (not MCP) for:

- **Upload / replace / reprocess / delete documents**
- **List / poll / cancel / retry jobs**
- **Configure KB webhooks** (create/update/delete/test)
- **Download binary content** (original document bytes; artifact bytes)

Rule of thumb: **MCP is for read + retrieval**; **HTTP is for writes + async control-plane**.

## Golden paths (common agent workflows)

### 1) Retrieval loop (answer with citations)

Use MCP for this flow:

1. `indexify_list_kbs` → choose `kbId`
2. `indexify_search` (or `indexify_search_enriched` / `indexify_search_with_neighbors`)
   - Set `includeSourceMetadata: true` to get stable provenance fields like `chunkId` / `chunkIndex` / `metadata`
   - Set `includeGrounding: true` when you need page/section grounding for citations
   - Set `diagnostics: true` when iterating (evaluate → refine) so you can see retrieval stats
3. Drill down only when needed:
   - `indexify_get_document_chunks` (expand context around a hit)
   - `indexify_get_parsed_document` (full parsed body in a specific format)
   - `indexify_list_document_sections` / `indexify_get_document_section` (outline navigation)
   - `indexify_list_section_elements` (elements scoped to one section)
   - `indexify_list_document_elements` / `indexify_get_document_element` (multimodal elements)
   - `indexify_list_document_tables` / `indexify_get_document_table` (tabular views)
   - `indexify_list_document_figures` / `indexify_get_document_figure`

### 2) Ingest → wait → search (end-to-end)

Use HTTP for ingest and job control, then MCP for retrieval:

1. **Upload a document** via HTTP (`POST …/documents`)
2. **Poll job status** via HTTP (job endpoints) until terminal (`completed` / `failed` / `canceled`)
3. **Search** via MCP tools (or HTTP search if your environment is HTTP-only)

Notes:
- Ingestion is async; do not assume the document is searchable immediately.
- For batch operations, prefer pagination and cursors rather than “fetch all”.

### 3) Webhook verification / delivery testing

This is HTTP-only:

- Configure per-KB webhook via HTTP (`GET/PUT/PATCH/DELETE …/webhook`)
- Send a test delivery via HTTP (`POST …/webhook/test`)
- Treat test deliveries as synthetic: payload includes a `testDelivery: true` marker (see OpenAPI).

## Operational rules agents should follow

### Pagination

Many list/search endpoints are paginated:
- Use `limit` + `cursor` (or `nextCursor`) from the prior response.
- Do not invent query params: follow OpenAPI strictly.

### Idempotency

For write endpoints that support idempotency:
- Send a unique `Idempotency-Key` per logical operation.
- Replays should return the prior success response for the same idempotency scope (see OpenAPI for details).

### Rate limiting and retries

If you receive `429` or explicit rate-limit headers:
- Back off and retry with jitter.
- Prefer smaller `limit` and narrower filters.

### Common error handling

Agents should respond to errors with concrete next steps:
- `401`/`403`: token missing/expired/insufficient scopes → mint a new token or request scopes.
- `400`/`422`: invalid input (often malformed UUIDs or unknown query keys) → correct request shape per OpenAPI.
- `404`: wrong project/KB/document id or deleted resource → re-list and reselect IDs.
- `503`: transient dependency issue → retry with exponential backoff.

## Canonical references (for agents and tool builders)

- **OpenAPI**: `/api/api-spec.yml`
- **MCP server**: connect to the hosted endpoint (see `/.well-known/llms.txt`), or follow the MCP connection instructions in the developer guide.

