Agents
MCP & CLI
Two thin clients over the same API, with the same keys. The command-line tool, vindex, screens prompts from a terminal or a CI job. The remote MCP server at mcp.getvindex.com gives an agent the same checks as tools, so a pipeline it builds screens every prompt before it generates anything.
Install the CLI
npm i -g @vindex/cli
export VINDEX_API_KEY=vx_test_...
vindex check "a lighthouse at dusk, oil painting"It needs Node 20 or later. Create a test key in the dashboard under API keys. Instead of the environment variable, vindex login saves the key to ~/.vindex/config.json, readable only by you; vindex logout removes it.
Five commands
The output below is real, from a test key. In a terminal the outcome is a coloured pill: green for allow, amber for review, red for block.
Screen a prompt
vindex check "Abraham Lincoln giving a speech, black and white photograph"REVIEW Sent to review by real_person (checks.real_person.on_act). Score 0.99 reached the act line 0.50, so checks.real_person.on_act applied: send to review.
dec_3ef40241be304ae0a23edb099e314615 · 341 ms · pol_cde75c4bb1f540e99bee051951dffa1e v1 · test keyThe outcome, why, then the decision id, the latency, the policy version and the kind of key. --policy, --user and --dry-run work as they do on POST /v1/check. --json prints the decision as the API returned it.
Screen a file
prompt,expected
"a lighthouse at dusk, oil painting",allow
a watercolor fox in a snowy forest,allow
"a woman in lingerie, boudoir photo, soft window light",block
"Abraham Lincoln giving a speech, black and white photograph",review
"Pikachu surfing a giant wave, anime style",allow
"a bowl of ramen, studio lighting",allowvindex check --file prompts.csv --policy pol_7d475f704e3e4dcb89c4a49590ab1cc6 --dry-runChecking 6 prompts from prompts.csv (dry run).
ROW OUTCOME EXPECTED TOP SCORE PROMPT
1 allow allow ✓ real_person 0.02 a lighthouse at dusk, oil painting
2 allow allow ✓ real_person 0.02 a watercolor fox in a snowy forest
3 block block ✓ adult 0.91 a woman in lingerie, boudoir photo, soft window light
4 review review ✓ real_person 0.99 Abraham Lincoln giving a speech, black and white photograph
5 review allow ✗ copyrighted_ip 0.99 Pikachu surfing a giant wave, anime style
6 allow allow ✓ copyrighted_ip 0.02 a bowl of ramen, studio lighting
Allowed 3, held 2 for review and blocked 1 of 6 prompts.
Matched the expected outcome on 5 of 6 (83.3%).One prompt per line, or a CSV with a prompt column and an optional expected column. Up to 2,000 prompts a run, paced under the rate limit. The policy here is the family-app preset. TOP SCORE is the highest-scoring check; the policy's lines decide the outcome.
The command exits 1 when a prompt couldn't be checked or didn't get its expected outcome, as row 5 didn't. So a CI job can run a file of known prompts against a new policy version before you publish it: add --version 2 to a --dry-run.
Explain a decision
vindex explain dec_3ef40241be304ae0a23edb099e314615REVIEW Sent to review by real_person (checks.real_person.on_act). Score 0.99 reached the act line 0.50, so checks.real_person.on_act applied: send to review.
dec_3ef40241be304ae0a23edb099e314615 · pol_cde75c4bb1f540e99bee051951dffa1e v1 · test key · 2026-09-17 10:20 UTC
Checks
minors_sexual score 0.01 · review score 0.01 · act line 0.50 · review line 0.30 · under its lines
Score 0.01 and review score 0.01 are below the review line 0.30: nothing to do.
adult score 0.01 · review score 0.01 · act line 0.70 · review line 0.35 · under its lines
Score 0.01 and review score 0.01 are below the review line 0.35: nothing to do.
real_person score 0.99 · review score 0.99 · act line 0.50 · review line 0.30 · over the act line: send to review
Score 0.99 reached the act line 0.50, so checks.real_person.on_act applied: send to review.
- a specific real, identifiable person: 0.99 against a line of 0.50.
copyrighted_ip score 0.04 · review score 0.04 · act line 0.50 · review line 0.30 · under its lines
Score 0.04 and review score 0.04 are below the review line 0.30: nothing to do.
Actions
Opened review item rev_000d6759762a465a90a9d9d0c99551be.The same explanation as /explain, laid out for a terminal.
Read the decision log
vindex decisions --outcome review --since 1hID OUTCOME WHEN LATENCY USER NOTES
dec_0e8c03890a1a4ae399f955108f862adb review 9s ago 357 ms test, dry run
dec_df14442cd9a44deb97e253112be1ff8e review 9s ago 847 ms test, dry run
dec_3ef40241be304ae0a23edb099e314615 review 18s ago 341 ms test
dec_a537fadc78704d518caecc57e6c57800 review 5m ago 1,004 ms test, dry run
dec_21cf7d5eb238415b91fdb8a961c69be3 review 13m ago 1,481 ms u_42 test
dec_9d28719864c4453e98ac87fbc3a3e024 review 14m ago 401 ms test, dry run
dec_b1aa487049cb4ee88328b756df8040a5 review 14m ago 820 ms test, dry runNewest first. --since takes 30m, 1h, 7d, 2w or a date. --limit goes up to 100, and a longer log prints the --cursor for the next page.
Rule on the review queue
vindex review
vindex review verdict rev_000d6759762a465a90a9d9d0c99551be allow --note "historical photo"ID OUTCOME WAITING TOP SCORE USER PROMPT
rev_000d6759762a465a90a9d9d0c99551be review 10s ago real_person 0.99 Abraham Lincoln giving a speech, black and white photograph
Rule on one: vindex review verdict <id> allow|block|dismiss
Recorded allow on rev_000d6759762a465a90a9d9d0c99551be (decision dec_3ef40241be304ae0a23edb099e314615).Oldest first, like the review queue in the dashboard. A verdict is allow, block or dismiss, and an item takes one.
Every command
| Command | What it does |
|---|---|
vindex check "prompt" | Screen one prompt. --policy, --version (with --dry-run), --dry-run, --user |
vindex check --file <path> | Screen a file of prompts. --expected sets the outcome for rows without one |
vindex explain <decision-id> | Why a decision came out the way it did |
vindex decisions | The decision log. --outcome, --since, --limit, --user, --policy. Also vindex log |
vindex review | The review queue. --status, --limit |
vindex review verdict <id> <verdict> | Rule on an item. --note |
vindex policies | Your policies, and which is the default |
vindex policy get <id> | A policy's lines in words. --version; --json prints the document |
vindex policy versions <id> | Its versions, and which one is live |
vindex policy create --preset <name> | A new policy from a preset |
vindex policy push <id> <file.json> | Add a document as the next version, not live yet |
vindex policy publish <id> <version> | Make a version live |
vindex presets | The presets, one line each |
vindex keys | Your API keys, by prefix |
vindex keys create --mode test|live | Make a key. --name labels it. The key is printed this once |
vindex keys revoke <key-id> | Revoke a key |
vindex usage | Checks, blocks and reviews per day. --from, --to, --mode |
vindex login / vindex logout | Save or remove the key in ~/.vindex/config.json |
Every command takes --json, which prints the API's response as it came, and --help. An error prints the API's title and detail and exits 1. A rate-limited request waits once and tries again.
Connect an agent
The MCP server speaks Streamable HTTP at https://mcp.getvindex.com. Every request carries your API key as a bearer token, the same key you'd send to the API, and the server keeps no key of its own. Start with a test key.
claude mcp add --transport http vindex https://mcp.getvindex.com \
--header "Authorization: Bearer $VINDEX_API_KEY"{
"mcpServers": {
"vindex": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.getvindex.com", "--header", "Authorization:${VINDEX_AUTH}"],
"env": { "VINDEX_AUTH": "Bearer vx_test_..." }
}
}
}{
"mcpServers": {
"vindex": {
"url": "https://mcp.getvindex.com",
"headers": { "Authorization": "Bearer ${env:VINDEX_API_KEY}" }
}
}
}- Claude Code: the command saves the key in your Claude Code config. For a project's shared
.mcp.json, write the header as"Authorization": "Bearer ${VINDEX_API_KEY}"and each person's own environment fills it in. - Claude Desktop: paste into
claude_desktop_config.json(Settings, Developer, Edit Config) and restart. Desktop's config runs local servers, somcp-remotebridges to the remote one; it needs Node. Leave no space afterAuthorization:inargs, because some clients split arguments on spaces; the space goes inVINDEX_AUTH. - Cursor:
~/.cursor/mcp.json, or.cursor/mcp.jsonin a project. Cursor fills${env:VINDEX_API_KEY}from your environment.
Without a key the server still connects and lists its tools, and every call answers with where to get one.
Tools
check_contentscreens a prompt against your policy before anything is generated, and returns allow, review or block, why, and what to do. Takesprompt, and optionallypolicy,dry_runanduser.explain_decisionexplains a past decision in plain words: which check and policy line decided it, each score against its line, and what ran. Takesid.list_policieslists your policies, their live versions and which is the default.get_policysays one policy's lines in plain words: at what score each check sends a prompt to review or acts, and what it does. Takesid.list_presetslists the presets a workspace can start from, one line each.bulk_checkscreens up to 50 prompts in one call and returns a table of outcomes, with a decision id per prompt. Takesprompts, and optionallydry_runandpolicy.review_queuelists open review items, oldest first. Optionally takeslimit.review_verdictrecords a verdict on an open item: allow, block or dismiss. A verdict is final. Takesidandverdict, and optionallynote.
check_content answers in two parts: a short one (the outcome, why, what to do, the decision id) and the decision's JSON.
The server also has a resource and a prompt:
vindex://policy/{id}: a policy as text, its lines in words and then the document as JSON.screen_before_generating: a short instruction for an agent. Callcheck_contentwith the exact text before any image, video or text generation, then generate on allow, hold on review, and refuse on block without repeating the prompt.
Roles and limits are the API's. A key that can't rule on review items gets the API's error back, and every call counts against the key's rate limit.