Skip to content

Configuration reference

Every setting is an environment variable with the ARROWHEAD_ prefix; a local .env file is honored for development. The prose here mirrors the annotated .env.example in the repository, and the defaults shown are the values the server uses when a variable is unset.

Which tool families this deployment exposes: core, docs, coding, or full. A tool outside the active profile is never registered, so it costs no context and a call to it is unknown. The exec family is gated a second time behind ARROWHEAD_EXEC_ENABLED even under coding or full.

Variable Default
ARROWHEAD_PROFILE full

stdio for Inspector over a pipe; http to serve the streamable endpoint.

Variable Default
ARROWHEAD_TRANSPORT stdio
ARROWHEAD_HOST 127.0.0.1
ARROWHEAD_PORT 8000
ARROWHEAD_STATELESS_HTTP true

Comma-separated Host and Origin allowlists for the HTTP endpoint. Set these to your public hostname when deploying behind a proxy.

Variable Default
ARROWHEAD_ALLOWED_HOSTS (empty)
ARROWHEAD_ALLOWED_ORIGINS (empty)

Leave disabled only for local stdio development. The server’s public URL is always required when enabled.

Variable Default
ARROWHEAD_AUTH_ENABLED false

Serving HTTP with auth disabled exposes every tool with no check; the server refuses to start that way unless this is set for a trusted-network test.

Variable Default
ARROWHEAD_ALLOW_INSECURE_HTTP false
ARROWHEAD_SERVER_PUBLIC_URL (unset)

“jwt” verifies against any OAuth 2.1 issuer (bring-your-own-IdP, e.g. Keycloak); “workos” wires WorkOS AuthKit, purpose-built for MCP.

Variable Default
ARROWHEAD_OAUTH_PROVIDER jwt

jwt provider: issuer, audience (= the canonical resource URI, must equal SERVER_PUBLIC_URL’s resource), and one key source (JWKS URI preferred).

Variable Default
ARROWHEAD_OAUTH_ISSUER (unset)
ARROWHEAD_OAUTH_AUDIENCE (unset)
ARROWHEAD_OAUTH_JWKS_URI (unset)
ARROWHEAD_OAUTH_PUBLIC_KEY (unset)

workos provider: the AuthKit domain from the WorkOS dashboard. AuthKit serves the OAuth metadata MCP clients need for automatic registration.

Variable Default
ARROWHEAD_OAUTH_AUTHKIT_DOMAIN (unset)

Per-resource authorization (document tools)

Section titled “Per-resource authorization (document tools)”

JSON policy applied on top of scopes. Empty uses a safe default: any authenticated caller may search, read, and scan the corpus, but write only within its own “<subject>/” namespace. Ignored when auth is off. Example:

ARROWHEAD_AUTHZ_POLICY={"grants":[{"subject":"*","actions":["read","search","scan"],"prefix":""},{"subject":"*","actions":["write"],"prefix":"${subject}/"}]}
Variable Default
ARROWHEAD_AUTHZ_POLICY (empty)

The only directory read_file may read from.

Variable Default
ARROWHEAD_JAIL_ROOT sandbox
ARROWHEAD_READ_FILE_MAX_BYTES 1000000

The jailed root the document tools operate on, separate from the read-only read_file sandbox. Only these extensions are documents.

Variable Default
ARROWHEAD_DOCS_ROOT documents
ARROWHEAD_DOC_MAX_BYTES 1000000
ARROWHEAD_DOC_ALLOWED_EXTENSIONS .json,.md,.txt

Content hardening caps applied to returned document content.

Variable Default
ARROWHEAD_CONTENT_MAX_BYTES 1000000
ARROWHEAD_JSON_MAX_DEPTH 64
ARROWHEAD_JSON_MAX_ELEMENTS 100000

Regex is off by default (denial-of-service surface); when enabled it runs through a ReDoS-resistant engine with a hard timeout.

Variable Default
ARROWHEAD_SEARCH_QUERY_MAX_LENGTH 200
ARROWHEAD_SEARCH_REGEX_ENABLED false
ARROWHEAD_SEARCH_REGEX_TIMEOUT_MS 250
ARROWHEAD_SEARCH_MAX_FILES 2000
ARROWHEAD_SEARCH_MAX_RESULTS 50
ARROWHEAD_SEARCH_MAX_TOTAL_BYTES 200000
ARROWHEAD_SEARCH_SNIPPET_MAX_CHARS 200
Variable Default
ARROWHEAD_SCAN_MAX_FILES 2000
ARROWHEAD_SCAN_PER_FILE_MAX_BYTES 1000000
ARROWHEAD_SCAN_TIMEOUT_SECONDS 10.0
ARROWHEAD_SCAN_MAX_FINDINGS 200
Variable Default
ARROWHEAD_DOC_WRITE_MAX_BYTES 1000000
ARROWHEAD_DOC_WRITE_QUOTA_BYTES 50000000

Overwriting asks for confirmation via elicitation; when the client cannot elicit, the explicit overwrite flag stands in as the opt-in.

Variable Default
ARROWHEAD_REQUIRE_WRITE_CONFIRMATION true
Variable Default
ARROWHEAD_FETCH_TIMEOUT_SECONDS 10.0
ARROWHEAD_FETCH_MAX_RESPONSE_BYTES 1000000
ARROWHEAD_FETCH_MAX_REDIRECTS 3

Egress allowlist (safe_fetch, doc_retrieve)

Section titled “Egress allowlist (safe_fetch, doc_retrieve)”

Comma-separated hostnames the fetch and retrieve tools may reach, enforced on every redirect hop. Empty allows any public host; the SSRF guard blocks private ranges regardless. Set this to restrict outbound requests to approved destinations.

Variable Default
ARROWHEAD_EGRESS_ALLOWED_HOSTS (empty)

Extra ports permitted beyond 80 and 443 (comma-separated). Empty allows only the two web ports, so a public host cannot be used to reach an internal service on a non-web port.

Variable Default
ARROWHEAD_EGRESS_ALLOWED_PORTS (empty)
Variable Default
ARROWHEAD_EXPRESSION_MAX_LENGTH 200

The read tool runs a single vetted read-only statement against this database. The DSN is a SQLAlchemy async URL. Empty leaves the connector unconfigured and the tool refuses to run. A read-only database role is the recommended credential; the connector also runs each query in a read-only transaction under a server-side statement timeout where supported.

ARROWHEAD_SQL_DSN=postgresql+asyncpg://readonly@db.example.com/app
Variable Default
ARROWHEAD_SQL_DSN (empty)

The dialect the guard parses against; empty infers it from the DSN driver.

Variable Default
ARROWHEAD_SQL_DIALECT (empty)
ARROWHEAD_SQL_QUERY_MAX_LENGTH 2000
ARROWHEAD_SQL_MAX_ROWS 1000
ARROWHEAD_SQL_MAX_BYTES 1000000
ARROWHEAD_SQL_MAX_COLUMNS 100
ARROWHEAD_SQL_TIMEOUT_SECONDS 10.0

pgvector search (postgres extra), over the SQL DSN database

Section titled “pgvector search (postgres extra), over the SQL DSN database”

Only these collections (comma-separated table names) may be searched, and the tenant filter is the authenticated caller, never an argument. Empty leaves the search tool unconfigured. The column names default to a common convention and are overridable per deployment.

Variable Default
ARROWHEAD_PGVECTOR_COLLECTIONS (empty)
ARROWHEAD_PGVECTOR_TENANT_COLUMN tenant
ARROWHEAD_PGVECTOR_ID_COLUMN id
ARROWHEAD_PGVECTOR_CONTENT_COLUMN content
ARROWHEAD_PGVECTOR_EMBEDDING_COLUMN embedding

Provenance columns written by doc_index and returned by vector_query so a retrieved chunk carries its source document and position as a citation.

Variable Default
ARROWHEAD_PGVECTOR_SOURCE_COLUMN source
ARROWHEAD_PGVECTOR_CHUNK_INDEX_COLUMN chunk_index

content_hash powers diff-aware re-indexing; content_tsv powers the full-text branch of hybrid_query. Both are added by deploy/pgvector_schema.sql.

Variable Default
ARROWHEAD_PGVECTOR_CONTENT_HASH_COLUMN content_hash
ARROWHEAD_PGVECTOR_TSVECTOR_COLUMN content_tsv
ARROWHEAD_PGVECTOR_MAX_K 50
ARROWHEAD_PGVECTOR_MAX_DIMENSIONS 2000

Embeddings (used by doc_index and vector_query)

Section titled “Embeddings (used by doc_index and vector_query)”

“deterministic” is a stdlib, offline, non-semantic provider for tests and local development. “http” posts to an OpenAI-compatible endpoint through the SSRF guard; the endpoint host must be on the egress allowlist and the key is supplied here, never forwarded to any other host.

Variable Default
ARROWHEAD_EMBEDDING_PROVIDER deterministic
ARROWHEAD_EMBEDDING_DIMENSIONS 1536
ARROWHEAD_EMBEDDING_ENDPOINT (empty)
ARROWHEAD_EMBEDDING_MODEL (empty)
ARROWHEAD_EMBEDDING_API_KEY (empty)
ARROWHEAD_EMBEDDING_BATCH_SIZE 64
ARROWHEAD_EMBEDDING_TIMEOUT_SECONDS 30.0
ARROWHEAD_EMBEDDING_MAX_TEXTS 10000
ARROWHEAD_EMBEDDING_MAX_RESPONSE_BYTES 8000000

Writing chunks needs a write-capable credential, kept separate from the read-only SQL DSN so the read tools stay least privilege; ingestion refuses to run until it is set. The caps bound how much one call may index.

Variable Default
ARROWHEAD_VECTOR_WRITE_DSN (empty)
ARROWHEAD_VECTOR_INDEX_MAX_FILES 500
ARROWHEAD_VECTOR_INDEX_MAX_CHUNKS 5000
ARROWHEAD_VECTOR_INDEX_CHUNK_MAX_CHARS 1500
ARROWHEAD_VECTOR_INDEX_CHUNK_OVERLAP 200
ARROWHEAD_VECTOR_INDEX_TIMEOUT_SECONDS 30.0

Source files chunk along their structure with this wider window. A re-index re-embeds only chunks whose content hash changed; set reuse false to restore the wholesale delete-and-insert on a schema without the content_hash column.

Variable Default
ARROWHEAD_CODE_CHUNK_MAX_CHARS 2000
ARROWHEAD_INDEX_REUSE_UNCHANGED true

Fuses vector similarity with Postgres full-text rank by reciprocal rank fusion. The candidate multiplier sizes each branch’s pool as a multiple of k. The text search configuration must name an installed Postgres regconfig.

Variable Default
ARROWHEAD_HYBRID_RRF_K 60
ARROWHEAD_HYBRID_CANDIDATE_MULTIPLIER 4
ARROWHEAD_FTS_LANGUAGE english

The code tools read a jailed source tree, separate from the document corpus: read-only, with version-control and dependency directories pruned, binary files refused, and per-file and per-walk caps.

Variable Default
ARROWHEAD_REPO_ROOT repo
ARROWHEAD_REPO_MAX_FILE_BYTES 500000
ARROWHEAD_REPO_ALLOWED_EXTENSIONS .c,.cpp,.cs,.go,.h,.hpp,.java,.js,.json,.jsx,.kt,.md,.php,.py,.pyi,.rb,.rs,.scala,.sh,.sql,.swift,.toml,.ts,.tsx,.txt,.yaml,.yml
ARROWHEAD_REPO_EXCLUDED_DIRS .git,.hg,.svn,.venv,node_modules,__pycache__,dist,build,target
ARROWHEAD_REPO_SEARCH_MAX_FILES 5000
ARROWHEAD_SYMBOL_MAP_MAX_FILES 500
ARROWHEAD_SYMBOL_MAP_MAX_SYMBOLS 5000
ARROWHEAD_DEPENDENCY_GRAPH_MAX_FILES 500

“none” keeps the assist tools refusing. “anthropic” posts to the Anthropic Messages API; “openai” posts to any OpenAI-compatible chat-completions URL, which covers Ollama, vLLM, and LM Studio. The key is supplied here and never appears in an error. A local endpoint must be named in ARROWHEAD_LLM_INTERNAL_HOSTS (exact host:port pairs) to be reachable.

Variable Default
ARROWHEAD_LLM_PROVIDER none
ARROWHEAD_LLM_ENDPOINT (empty)
ARROWHEAD_LLM_MODEL (empty)
ARROWHEAD_LLM_API_KEY (empty)
ARROWHEAD_LLM_MAX_TOKENS 1024
ARROWHEAD_LLM_TIMEOUT_SECONDS 60.0
ARROWHEAD_LLM_MAX_PROMPT_CHARS 32000
ARROWHEAD_LLM_INTERNAL_HOSTS (empty)
ARROWHEAD_DIFF_MAX_BYTES 200000

Off by default and, even when enabled, denied by the default policy: a deployment opts in twice, by this flag and by granting the execute action. The subprocess runner bounds resources and scrubs the environment but does not block network or filesystem reads; use the container runner for that.

Variable Default
ARROWHEAD_EXEC_ENABLED false
ARROWHEAD_EXEC_RUNNER subprocess
ARROWHEAD_EXEC_CONTAINER_IMAGE (empty)
ARROWHEAD_EXEC_WORKDIR exec-scratch
ARROWHEAD_EXEC_CPU_SECONDS 10
ARROWHEAD_EXEC_WALL_SECONDS 30.0
ARROWHEAD_EXEC_TEST_WALL_SECONDS 120.0
ARROWHEAD_EXEC_MEMORY_BYTES 512000000
ARROWHEAD_EXEC_MAX_OUTPUT_BYTES 200000
ARROWHEAD_EXEC_MAX_CODE_BYTES 100000
ARROWHEAD_EXEC_MAX_COPY_BYTES 50000000
ARROWHEAD_EXEC_COPY_MAX_FILES 500

The argv run_tests executes inside the scratch copy, shell-split; empty refuses run_tests.

Variable Default
ARROWHEAD_EXEC_TEST_COMMAND (empty)

Working sets and context packer (context family)

Section titled “Working sets and context packer (context family)”

A working set is a named, owner-scoped collection of pinned references; the packer assembles a token-budgeted, secret-scanned bundle from it plus retrieval. Bounds keep one caller from growing state without limit.

Variable Default
ARROWHEAD_WORKINGSET_MAX_SETS 100
ARROWHEAD_WORKINGSET_MAX_ITEMS 200
ARROWHEAD_PACK_MAX_TOKENS 8000

Agent memory and scratchpad (memory family)

Section titled “Agent memory and scratchpad (memory family)”

Owner-scoped memories in namespaces plus an exact-key kv store. The backend is a jailed file tree under the memory root by default; setting a Postgres DSN (write-capable, separate from the read-only SQL DSN) moves storage there, with semantic recall once the http embedding provider is configured. Apply deploy/memory_schema.sql first.

Variable Default
ARROWHEAD_MEMORY_ROOT memory
ARROWHEAD_MEMORY_DSN (empty)
ARROWHEAD_MEMORY_MAX_CONTENT_BYTES 100000
ARROWHEAD_MEMORY_MAX_METADATA_BYTES 4096
ARROWHEAD_MEMORY_MAX_ENTRIES_PER_NAMESPACE 500
ARROWHEAD_MEMORY_MAX_NAMESPACES 50
ARROWHEAD_MEMORY_QUOTA_BYTES 50000000
ARROWHEAD_MEMORY_MAX_K 20
ARROWHEAD_KV_MAX_KEYS 1000
ARROWHEAD_KV_MAX_VALUE_BYTES 100000
ARROWHEAD_KV_MAX_TTL_SECONDS 604800

Timers share the in-process task registry and do not survive a restart.

Variable Default
ARROWHEAD_TASK_SCHEDULE_MAX_DELAY_SECONDS 86400.0
ARROWHEAD_TASK_SCHEDULE_MIN_REPEAT_SECONDS 60.0
ARROWHEAD_TASK_SCHEDULE_MAX_PER_OWNER 20
ARROWHEAD_TASK_PAYLOAD_MAX_BYTES 16384

Outbound webhook notifications (notify family)

Section titled “Outbound webhook notifications (notify family)”

Comma-separated absolute http(s) URL prefixes. Empty leaves the notify family unregistered; even an allowlisted target is still SSRF-guarded, and the notify action must additionally be granted in the authz policy.

Variable Default
ARROWHEAD_NOTIFY_ALLOWLIST (empty)
ARROWHEAD_NOTIFY_TIMEOUT_SECONDS 10.0
ARROWHEAD_NOTIFY_MAX_PAYLOAD_BYTES 100000
ARROWHEAD_NOTIFY_MAX_RESPONSE_BYTES 10000

Ceilings are calls per caller per minute. Redis, if set, shares the buckets across replicas; without it limits apply per process.

Variable Default
ARROWHEAD_RATE_LIMIT_ENABLED true
ARROWHEAD_SAFE_FETCH_PER_MINUTE 30
ARROWHEAD_CALCULATE_PER_MINUTE 120
ARROWHEAD_READ_FILE_PER_MINUTE 60
ARROWHEAD_DOC_SEARCH_PER_MINUTE 60
ARROWHEAD_DOC_READ_PER_MINUTE 60
ARROWHEAD_DOC_RETRIEVE_PER_MINUTE 30
ARROWHEAD_DOC_SCAN_PER_MINUTE 20
ARROWHEAD_DOC_WRITE_PER_MINUTE 30
ARROWHEAD_SQL_QUERY_PER_MINUTE 60
ARROWHEAD_VECTOR_SEARCH_PER_MINUTE 30
ARROWHEAD_VECTOR_QUERY_PER_MINUTE 30
ARROWHEAD_HYBRID_QUERY_PER_MINUTE 30
ARROWHEAD_VECTOR_INDEX_PER_MINUTE 6
ARROWHEAD_CODE_SEARCH_PER_MINUTE 60
ARROWHEAD_CODE_READ_PER_MINUTE 60
ARROWHEAD_SYMBOL_MAP_PER_MINUTE 20
ARROWHEAD_DEPENDENCY_GRAPH_PER_MINUTE 10
ARROWHEAD_CODE_EXPLAIN_PER_MINUTE 10
ARROWHEAD_SUMMARIZE_DIFF_PER_MINUTE 10
ARROWHEAD_RERANK_PER_MINUTE 20
ARROWHEAD_RUN_SNIPPET_PER_MINUTE 10
ARROWHEAD_RUN_TESTS_PER_MINUTE 4
ARROWHEAD_WORKINGSET_GET_PER_MINUTE 60
ARROWHEAD_WORKINGSET_UPDATE_PER_MINUTE 30
ARROWHEAD_PACK_CONTEXT_PER_MINUTE 10

Starting an async task is expensive (a background scan); polling is cheap.

Variable Default
ARROWHEAD_TASK_START_PER_MINUTE 10
ARROWHEAD_TASK_GET_PER_MINUTE 120
ARROWHEAD_TASK_UPDATE_PER_MINUTE 30
ARROWHEAD_TASK_LIST_PER_MINUTE 60
ARROWHEAD_TASK_SCHEDULE_PER_MINUTE 10
ARROWHEAD_MEMORY_STORE_PER_MINUTE 30
ARROWHEAD_MEMORY_SEARCH_PER_MINUTE 60
ARROWHEAD_MEMORY_LIST_PER_MINUTE 60
ARROWHEAD_MEMORY_DELETE_PER_MINUTE 30
ARROWHEAD_KV_SET_PER_MINUTE 60
ARROWHEAD_KV_GET_PER_MINUTE 120
ARROWHEAD_KV_DELETE_PER_MINUTE 60
ARROWHEAD_NOTIFY_WEBHOOK_PER_MINUTE 10

Reading a resource, getting a prompt, and completing an argument are rate-limited per caller too.

Variable Default
ARROWHEAD_RESOURCE_READ_PER_MINUTE 60
ARROWHEAD_PROMPT_GET_PER_MINUTE 60
ARROWHEAD_COMPLETION_PER_MINUTE 60

Any tool without an explicit ceiling above falls back to this default.

Variable Default
ARROWHEAD_DEFAULT_TOOL_PER_MINUTE 60
ARROWHEAD_REDIS_URL (unset)

Comma-separated tool names to take out of service without a redeploy.

Variable Default
ARROWHEAD_DISABLED_TOOLS (empty)

How long clients may cache a list result and a single resource read; both ride in the result _meta with a private cache scope.

Variable Default
ARROWHEAD_TOOL_LIST_TTL_MS 3600000
ARROWHEAD_RESOURCE_READ_TTL_MS 60000

Set the OTLP/HTTP collector base endpoint to export traces and metrics; leave empty and both stay no-op at no cost. Headers are comma-separated key=value pairs (e.g. a collector API key). Audit logs are always emitted as JSON on stdout for the platform’s log drain regardless of this.

Variable Default
ARROWHEAD_OTEL_EXPORTER_OTLP_ENDPOINT (unset)
ARROWHEAD_OTEL_EXPORTER_OTLP_HEADERS (unset)
ARROWHEAD_OTEL_SERVICE_NAME arrowhead