Docs RAG walkthrough
Two ways to see the retrieval loop - chunk documents, embed them, and answer a
query with cited chunks. The runnable source lives in
examples/docs_rag/;
run the commands from a repository checkout.
Offline, no server and no database
Section titled “Offline, no server and no database”uv run python examples/docs_rag/run_offline.pyThis chunks the corpus/ documents, embeds them with the deterministic
provider, and prints the chunks most similar to a query, each with its source
and chunk index. The deterministic embedder is not semantic, so treat the
ranking as illustrative of the shape, not the quality.
Real, with Postgres and a real embedder
Section titled “Real, with Postgres and a real embedder”-
Apply the schema once (the vector width must match
ARROWHEAD_EMBEDDING_DIMENSIONS):Terminal window psql "$WRITE_DSN" -f deploy/pgvector_schema.sql -
Configure a real embedding provider and the read and write credentials. Enabling auth requires the OAuth settings too (issuer, audience, the server’s public URL, and a JWKS URI or public key; see the deployment runbook), or the server refuses to start:
Terminal window export ARROWHEAD_AUTH_ENABLED=trueexport ARROWHEAD_OAUTH_ISSUER=https://auth.exampleexport ARROWHEAD_OAUTH_AUDIENCE=https://mcp.exampleexport ARROWHEAD_OAUTH_JWKS_URI=https://auth.example/.well-known/jwks.jsonexport ARROWHEAD_SERVER_PUBLIC_URL=https://mcp.exampleexport ARROWHEAD_SQL_DSN=postgresql+asyncpg://reader@host/dbexport ARROWHEAD_VECTOR_WRITE_DSN=postgresql+asyncpg://writer@host/dbexport ARROWHEAD_PGVECTOR_COLLECTIONS=doc_chunksexport ARROWHEAD_EMBEDDING_PROVIDER=httpexport ARROWHEAD_EMBEDDING_ENDPOINT=https://api.example/v1/embeddingsexport ARROWHEAD_EMBEDDING_API_KEY=...export ARROWHEAD_EMBEDDING_DIMENSIONS=1536export ARROWHEAD_EGRESS_ALLOWED_HOSTS=api.example -
Grant the caller the
ingestaction, which the default policy denies, viaARROWHEAD_AUTHZ_POLICY:{"grants": [{"subject": "*", "actions": ["ingest", "query"],"kinds": ["table"], "prefix": "doc_chunks"}]} -
Call
doc_index(collection="doc_chunks")to index the corpus, thenvector_query(collection="doc_chunks", query="how long do refunds take?"). Each result carries the source document and chunk index it came from.
The write role should be limited to INSERT, UPDATE, DELETE, and SELECT
on the chunks table (a re-index upserts unchanged rows, so UPDATE is
required); the read tools use the read-only ARROWHEAD_SQL_DSN.