MCP server

Explanation — what & why

Vectros ships an official Model Context Protocol (MCP) server (@vectros-ai/mcp-server) that connects MCP-aware agents — Claude Desktop, Cursor, Cline, Continue, VS Code, and hosted agent platforms — directly to a tenant's hybrid search, structured records, documents, folders, and in-perimeter inference. Drop one line into the agent's config and the model can search the indexed corpus, query and write records, ingest documents, and ask questions grounded against documents — with no custom integration code.

The MCP server is a thin shim over the Vectros SDK: partner-observable behavior matches the SDK and the underlying HTTP API one-to-one. Tenant isolation and scope enforcement all hold — running an MCP server does not expand a credential's reach. What it does is make that reach available to the agent as callable tools.

Two properties are worth understanding up front:

  • Data-plane tools only. The server exposes exactly 21 tools, and every one of them wraps a Vectros data-plane operation. There are no web-search or third-party agent tools — none are present, by design. An agent driven through this server reaches your tenant's data and nothing else.
  • Built for the context window. A tool result is injected straight into the model's context, a fundamentally different consumption shape than a UI response. The server applies deliberately smaller default limits than the HTTP API to protect the window and the cost.

How-to

Install and configure (stdio — the desktop case)

Drop this into your MCP client config (Claude Desktop: claude_desktop_config.json; Cursor / Cline / Continue have equivalents):

{
  "mcpServers": {
    "vectros": {
      "command": "npx",
      "args": ["-y", "@vectros-ai/mcp-server"],
      "env": {
        "VECTROS_API_KEY": "ssk_live_..."
      }
    }
  }
}

Restart the client. That is the whole install. The server runs as a stdio subprocess of the client; JSON-RPC over stdin/stdout is the wire protocol. No ports, no URLs, no auth ceremony.

VECTROS_API_KEY accepts any of the three credential types, but a scoped permanent key (ssk_*) is the right shape for a desktop install — the blast radius of a root key on a desktop is too broad.

Provision the credential in one command

You do not have to hand-build that ssk_*. The companion CLI mints a least-privilege scoped key and its access profile and merges the config entry above for you — no root key, no manual portal steps:

npx -y @vectros-ai/cli bootstrap

See cli.md for the full bootstrap flow. The minted key is data-plane only and per-machine.

Install and configure (HTTP — the hosted case)

For self-hosted scenarios — running the server behind a network boundary, sharing it across agent instances, deploying as a sidecar — the same package exposes a second binary that speaks Streamable HTTP instead of stdio:

VECTROS_API_KEY=ssk_live_... \
VECTROS_MCP_HTTP_PORT=8765 \
VECTROS_MCP_HTTP_BEARER_TOKEN=$(openssl rand -hex 32) \
  npx -y -p @vectros-ai/mcp-server vectros-mcp-server-http

The server listens on 127.0.0.1:8765 by default. A bearer token is optional on localhost but required to bind a non-loopback host — without one, anyone who can reach the port could call Vectros with your credentials, so the server refuses to start (override with VECTROS_MCP_HTTP_ALLOW_INSECURE=1, which is not recommended). DNS-rebinding protection is built in; set VECTROS_MCP_HTTP_ALLOWED_HOSTS to your public hostname(s) when running behind a reverse proxy.

Constrain which tools an agent gets

Narrow the catalog at install time with VECTROS_MCP_TOOLS — a comma-separated list of tool names (e.g. "hybrid_search,rag_ask"). This gives an agent read-only search without exposing writes or inference cost. Unknown tool names fail fast at startup with a clear error.

Reference

The 21 tools

Every tool wraps a Vectros data-plane operation. Records, documents, and folders each have a full create / read / update / delete / query set; search and inference round it out; list_schemas, current_identity, lookup_principal, and version_history are discovery and history.

ToolPurpose
hybrid_searchKeyword + dense ranking across indexed documents and records. Narrow by ownership, folder, type, metadata filters, date window, keyword precision, and relevance floors.
list_schemasDiscover the available record / document / identity types (filter by surface, or resolve one by type name).
current_identityDescribe the credential's tenant and principal scope.
lookup_principalResolve a user / org / client by your own externalId (to its Vectros id, for the ownership filters) or by a schema lookup field. Read-only.
record_createCreate a structured record. Idempotent by externalId; optional per-record indexMode.
record_getFetch a record by id.
record_updateUpdate a record.
record_deleteDelete a record.
record_queryLook up (exact / composite / range / prefix, ascending or descending) or list records by type — see record_query supports composite (multi-field) lookups below.
document_ingestCreate a document — inline text, or a local file upload. Idempotent by externalId; optional schemaId + payload for a typed, lookup-queryable document.
document_getFetch a document by id (metadata; optional text; optional presigned file download URL).
document_updateUpdate a document.
document_deleteDelete a document.
document_queryLook up (exact / range / prefix, ascending or descending) or list documents.
document_askAsk a question scoped to a single document.
folder_createCreate a folder.
folder_updateUpdate a folder.
folder_deleteDelete a folder.
folder_queryLook up or list folders (paginated).
rag_askAsk a question grounded against the indexed corpus. Scope retrieval (ownership, folder, type, metadata filters, date window) and steer generation (instructions, temperature).
version_historyRead the change history (create / update / delete, with actor and diff) of a record or document. Read-only.

There are deliberately no web, search-the-internet, or third-party agent tools — the server's reach is your tenant's data plane only.

Read-only resources

Alongside the tools, the server exposes two read-only MCP resources for ambient context an agent can pick up without spending a tool call:

  • a schema catalog resource (the same payload as list_schemas), and
  • an identity resource (the same payload as current_identity).

Transports

TransportBinaryDefault bindUse for
stdiovectros-mcp-servern/a (subprocess)Desktop agents.
Streamable HTTPvectros-mcp-server-http127.0.0.1:8765Hosted / shared / sidecar deployments.

document_ingest is dual-mode

Pass text for an inline-body ingest, or filePath for a local-file upload — exactly one; both is an error.

  • text mode works on both transports.
  • filePath mode is stdio-only. The HTTP transport rejects filePath at validation time, because a remote server cannot read the caller's local filesystem. On HTTP, ingest text inline or call the SDK's upload method from your own code.
  • On stdio, an uploaded path is jailed to a configured ingest root (VECTROS_MCP_INGEST_ROOT, else the server's working directory). Paths that escape the root (traversal, absolute, or symlink) or match a sensitive-file pattern (SSH/AWS/credential files, .env, and similar) are refused before any bytes are read.
  • File uploads are asynchronous: the tool returns with status PENDING_INDEX; poll document_get until it reports INDEXED.
  • Idempotent by externalId. Pass a stable externalId and re-ingesting the same one returns the existing document instead of creating a duplicate — the same semantics record_create has, so a retried ingest is safe.
  • Typed documents. Pass schemaId + payload to bind the document to a schema; its declared lookup fields then become directly queryable via document_query, exactly like records.

record_query supports composite (multi-field) lookups

A schema can declare a lookup over 2–3 fields together (see blueprints.md); record_query queries one by comma-joining the field names in field (e.g. "status,area") and passing values — one value per field, in the schema's declared order — or a single value to match just the first named field, which groups the results by the rest. Supplying fewer values than the lookup declares is allowed only as a leading run of the declared fields (the first field alone, the first two, and so on — never a later field alone). A composite lookup is exact-match only: from/to/prefix don't apply. sortFrom/sortTo narrow an exact match to a window of the sort key, but on a composite lookup need a value for every declared field — a partial (grouped) match has no single ordering to window. Document, user, and entity lookups remain single-field only; composite lookups exist for records only.

Context-window protection

Because tool results land directly in the model's context, the server caps results more tightly than the HTTP API:

ToolAPI defaultAPI maxMCP defaultMCP max
hybrid_search1050350
record_query1001003100
rag_ask retrieval550

hybrid_search pages with offset (skip the first N hits). record_query pages with the cursor envelope instead — pass the nextCursor a page returns back as startFrom to fetch the next one, and stop only when nextCursor comes back null; a full page is not itself a signal to keep going, and a hand-built startFrom is rejected. rag_ask retrieval does not page at all — limit is a one-shot cap on how many passages ground a single answer, not an offset you advance; ask again with different scoping filters to change what's retrieved. Agents that want a full document fall back to document_ask for question-driven extraction rather than dumping text into context.

Long-running calls stay alive

rag_ask and document_ask can run tens of seconds. MCP clients have tool-execution timeouts that would otherwise fire mid-generation. The server emits an MCP progress notification for each streamed chunk, keeping the JSON-RPC connection warm; the final aggregated answer arrives as the tool result. Clients that surface progress show the answer building; clients that ignore it still receive the complete answer.

Startup credential validation

On connect, the server performs a credential check so a bad key fails fast as a startup error rather than opaquely failing on the first tool call. Disable it with VECTROS_MCP_SKIP_PING_VALIDATION=1 (useful in CI where the API is not reachable).

Credential resolution

The server takes its key from the first source that supplies one:

  1. VECTROS_API_KEY — always wins when set.
  2. The vectros CLI keyring — if the key is unset and the CLI is on PATH, the server runs vectros keyring show --format raw as a subprocess and uses the key it prints (the active entry, or VECTROS_KEYRING_ALIAS if set). One credential store, shared by the server, scripts, and hooks — no plaintext copy per tool. Same pattern as git credential / aws credential_process.
  3. Neither — startup fails with guidance naming both options.

The key is held in memory only and never logged; startup logs the resolved alias so you can see which identity the server is running as. vectros keyring doctor shows that view, including which entries hold live keys (the ones that act on real data).

Startup warns when it picks an identity you didn't name — that is, when VECTROS_API_KEY is unset and no VECTROS_KEYRING_ALIAS is given, so the key comes from whichever entry vectros switch last made active. That is easy to arrive at by accident: a blank placeholder ("VECTROS_API_KEY": "" in a client config, or -e VECTROS_API_KEY passing an unset var through Docker) looks unconfigured but resolves like an unset key. The warning does not depend on which key turns up — silently getting a ssk_live_* key (acting on real data) and silently getting a ssk_test_* one (not acting on it, when you thought you were) are both surprises. Nothing is blocked: name an entry with VECTROS_KEYRING_ALIAS, or set VECTROS_API_KEY, and the warning stops. vectros keyring doctor shows which entry is active and which keys are live.

Environment variables

VariableRequiredDefaultPurpose
VECTROS_API_KEYno*Vectros credential. Recommended: ssk_*. *Required unless the vectros CLI is installed with a usable keyring entry: when this is unset, the server resolves the key by running vectros keyring show --format raw (see Credential resolution). Takes precedence when set.
VECTROS_KEYRING_ALIASno(the active entry)Resolve this vectros keyring entry instead of the active one. Ignored when VECTROS_API_KEY is set.
VECTROS_API_BASE_URLnohttps://api.vectros.aiAPI base URL. Use the staging URL for the staging tenant. Validated before the key is attached.
VECTROS_MCP_TOOLSno(all)Comma-separated tool filter.
VECTROS_MCP_INGEST_ROOTnoserver cwdRoot directory document_ingest file uploads are jailed to (stdio).
VECTROS_MCP_DEBUGnoSet 1 for debug logging on stderr.
VECTROS_MCP_SKIP_PING_VALIDATIONnoSet 1 to skip the startup credential check.
VECTROS_MCP_HTTP_PORTHTTP only8765Listen port.
VECTROS_MCP_HTTP_HOSTHTTP only127.0.0.1Bind address.
VECTROS_MCP_HTTP_BEARER_TOKENHTTP onlyClient→server bearer token. Required to bind a non-loopback host.
VECTROS_MCP_HTTP_ALLOWED_HOSTSHTTP onlyExtra allowed Host header values (DNS-rebinding protection).
VECTROS_MCP_HTTP_ALLOWED_ORIGINSHTTP onlyExtra allowed Origin header values.
VECTROS_MCP_HTTP_ALLOW_INSECUREHTTP onlySet 1 to bind a non-loopback host without a bearer token (not recommended).

Notes & limits

  • Exactly 21 data-plane tools; no web/agent tools. The server cannot reach the public internet or any non-Vectros service.
  • document_ingest file upload is stdio-only. Use text mode (or the SDK) on HTTP.
  • One upstream credential per process. The HTTP transport uses its VECTROS_API_KEY for all upstream calls; the incoming HTTP bearer token is for client→server auth only, not mapped to a per-request Vectros credential. Deploy one server per credential boundary you want to enforce.
  • current_identity returns the full identity shape — tenant, environment, principal type, principal key id and label, and (for scoped credentials) the allowed actions and data scope ({ userId, scopes[] }). It degrades to a derived-only shape only when no upstream call can be made (e.g. a test mock).
  • rag_ask / document_ask aggregate before returning. The full answer is assembled server-side (progress notifications cover the latency); native tool-level streaming is not yet exposed.

Where to go next

  • cli.mdbootstrap provisions the ssk_* this server runs on.
  • sdk.md — the SDK the tools wrap, for when you want code instead of an agent.
  • blueprints.md — declare the schemas the agent will read and write.
  • The blueprint walkthroughs — narrated builds where an agent drives a provisioned blueprint over MCP.