The manual

How to make your agent ask before it acts.

From first install to running it in production. What to type, what you will see, and what to do when something refuses.

Start free, no card → Already have an account

VERIFIED every command here was run from a clean machine against the published package

01What Fidacy is, in one page

Your AI agent can be talked into things. A prompt injection, a spoofed invoice, a lookalike vendor name, a model having a bad day. When the action it takes is consequential, a payment, a deletion, an export, being sorry afterwards is not a control.

Fidacy sits between the agent and the action. The agent has to ask before it acts. Fidacy checks the request against rules you wrote, answers YES or NO, and signs that answer. Nothing about the answer depends on trusting us: the signature verifies offline against a public key, so you, your auditor, your insurer or a court can check it without our cooperation.

Three properties are worth holding in your head, because everything else follows from them.

Deny by default. An empty allowlist means every payee is refused. You add what is allowed; you never have to predict what is forbidden.

Local first. The default install decides on your machine, offline. Payment details, file paths and amounts do not leave it. A hosted account adds server-signed verdicts and identity checks on top, and even then the local rules keep working if the network does not.

Both answers are signed. A firewall that only records refusals proves nothing about the payments it let through. Fidacy signs the YES too, which is what turns your logs into evidence.

The one sentence to keep

You decide the rules in advance, the agent asks, the firewall answers and signs.

02Install it in five minutes

Step 1: register Fidacy with your agent

npx -y @fidacy/mcp install

This scans your machine for every MCP host it knows: Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, Codex, Gemini CLI, OpenClaw. It shows you what it found and the exact file it would touch, then stops.

It writes nothing on this first run. That is on purpose: it is your config file, so you see the plan before anything changes. To apply it:

npx -y @fidacy/mcp install --write

Every existing MCP server in those files is left alone, ours is added, and the original is copied to <file>.fidacy-backup first. Running it twice changes nothing the second time.

Two hosts are reported instead of written, because their config format is not one we have confirmed, and writing a guess into your config would break your agent. For Codex (~/.codex/config.toml) add under [mcp_servers.fidacy] the command npx with args ["-y", "@fidacy/mcp"]. For Gemini CLI (~/.gemini/settings.json) add the same shape under mcpServers.

OpenClaw is different by design. An OpenClaw plugin cannot register an MCP server, and the native plugin is better anyway because it runs in process with no subprocess per call:

openclaw plugins install @fidacy/openclaw-plugin

Step 2: restart your agent

MCP servers are read at startup. Until you restart, nothing has changed.

Step 3: confirm it is there

Ask your agent: what Fidacy tools do you have? You should see eleven, starting with request_payment.

Not a hang

If you run npx -y @fidacy/mcp in a terminal you will see a banner and then apparent silence. That is correct. It is a server waiting for an agent to speak to it on stdin. Ctrl+C exits.

You now have a working firewall with a safe default mandate: no payee approved, 2500 per payment, 10000 total, USD. Every payment your agent attempts is refused, and each refusal is signed. That sounds aggressive and it is the right starting point: you open exactly what you mean to open, next.

03Your first session: see a NO and a YES

Do not configure anything yet. Ask your agent, in plain words:

show me Fidacy blocking a payment

The agent will attempt a payment to an ordinary payee and get a signed refusal, then attempt one to the payee fidacy:demo and get a signed approval. Nothing settles either way, because Fidacy never moves money: it decides, and something else executes.

You now have both halves of the product in front of you: a NO you can hand to someone, and a YES you can hand to someone.

If the agent ignores you, run the two attempts yourself by asking for a specific payment. The refusal is the same. Some hosts do not pass a server's instructions to the model, so the model may simply not know the demo exists.

This invitation disappears from the banner after your first real decision. It is a first-run thing, not a permanent fixture.

04How a decision is made

Your rules live in ~/.fidacy/config.json. The file is created on first run with permissions 0600, and it is re-read before every decision, so an edit applies immediately with no restart.

Approving a payee

npx -y @fidacy/mcp allow acme-supplies

You can pass several at once, or edit payees in the file directly. Both take effect on the next payment.

Why this is not a tool

Approving is deliberately a terminal command and not something your agent can call. An agent under a prompt injection would otherwise add its own fraudulent payee to the allowlist and then pay it, which is precisely the attack Fidacy exists to stop. Approving is a human act.

What gets checked, and in what order

  1. Is the request well formed? An amount that is not a positive number, an empty payee, a missing currency: refused before any rule runs.
  2. Is the mandate itself usable? A cap that is not a number, a window that is not a date: refused. It never runs without a limit it cannot enforce.
  3. Is the mandate live? Not revoked, and now is inside its window.
  4. Currency, amount, caps. Wrong currency, over the per-payment ceiling, or past the total budget for the window.
  5. Is the payee approved? If not, one extra question: does it look like one that is? A payee that folds to the same string as an approved one, or is within two characters of it, is reported as a lookalike rather than an unknown payee. That distinction matters: "unknown payee" reads like you forgot something, "this imitates the vendor you approved" reads like the attack it usually is.
  6. Is the purpose allowed? Categories, if you narrowed them.
  7. Has this invoice been paid already? One payment per invoice reference, regardless of amount. This is the control that stops the same invoice coming back at a higher figure.

The first rule that fails ends the decision, and its name comes back to you in violatedRule, like per_tx_cap_exceeded:5000>2500. Chapter 12 translates every one of them.

Two details that save confusion later. Blocked attempts do not consume your budget: only payments that went through count against the total. And invoice references are normalized before comparison, so INV-1, inv 1 and a version carrying an invisible character are the same invoice, which is how an attacker gets a duplicate past a naive check.

05The tools your agent can call

Eleven tools. You do not call these; your agent does, and you read the results.

ToolWhat it does
request_paymentThe decision. Every payment goes through it and comes back ALLOW or DENY, signed.
list_decisionsRecent decisions. Ask for "what got blocked this week".
explain_decisionWhy one specific decision went the way it did, in plain language.
spend_summaryWhat your agents spent over N days (7 by default).
sentinel_alertsAnything that looks unusual against the thresholds.
verify_mandateThe rules currently in force, plus our public key.
get_audit_proofThe tamper-evident proof for one decision.
assess_actionA server-signed verdict, with identity and behavior checks the local firewall cannot do alone. Needs a key.
anchor_artifactProves a file or conversation existed exactly as it was, at a moment, anchored to Bitcoin. Needs a key.
check_artifactChecks a hash against what was anchored. Detects tampering. Needs a key.
upgradeReturns your personal link to claim a free account.
register_emailRecords your email, only after you explicitly give it.

A useful habit: after any refusal that surprises you, ask your agent to explain that decision. The explanation names the rule, why it exists, and what to change if the refusal was wrong.

06Beyond payments: the protect wizard

Out of the box Fidacy gates payments. It can gate much more, and that part is opt in because blocking a class of action your agent legitimately needs would break your work.

npx -y @fidacy/mcp protect

Seven questions, each about one class of action. For each you answer y (allowed, and recorded), a (held for your approval), or n (refused). The classes: deleting files, reading credentials, exfiltrating data, exporting CRM records, writing to databases, sending email, and critical system commands.

Then it asks which systems your agent is allowed to reach, and if you named any, whether anything heading somewhere else should be refused.

Two things people get wrong here

Naming your systems does not lock down everything else on its own. Undeclared destinations stay allowed until you say otherwise, which is the last question. Flipping it is powerful and will block any tool you forgot to declare, so do it once you know what your agent actually touches.

Naming a system grants read on it. Write and export stay off until you turn them on deliberately.

The wizard needs a real terminal. In CI or a non-interactive shell it will tell you so rather than half-configuring you.

07The dashboard, screen by screen

A free account takes about two minutes and no card. A sandbox key is created with your workspace, so you can do something real immediately.

Get started is where you land, and where your key is shown once. Copy it then. Set it where your agent runs:

export FIDACY_ENGINE_API_KEY=fky_test_your_key_here

The screens you will actually use

Overview is the verdict feed: every assessment with its decision and risk score. Before your first verdict it shows sample rows so you know what the shape of the answer will be, which is more useful than an empty table.

Control Room is the live evidence feed. Pick a decision and you can download an Incident Pack (everything a third party needs to reconstruct what happened) or revoke the authority behind it on the spot.

Policies is your server-side rulebook, and it is different from the local config file. Here you set per-transaction maximums, allowed currencies and geographies, velocity limits, the minimum identity you require from an agent, and the mode for each action class. The approval email lives here: if you set a class to "ask", this is the address that gets the approve or refuse link. That email flow is server-side only.

Authority issues a narrow mandate to a specific agent: this action, on this resource, this many times, until this date. Revoking one is immediate, and the evidence of what it did stays.

Agents is where you register an agent and get a cnf to put in its mandate. This is the step that turns "we don't know who this agent is" into a verifiable identity, and it is what lets you require proven identity in Policies.

Receipts and Audit are the proof surfaces. Settings holds your API keys (create, scope, revoke) and your account. Keys are shown once at creation, and revoking one stops anything using it immediately. There is also a Guided demo that runs a complete gated action end to end, so a new workspace can see the product work before any agent is wired.

What lives where

You configureWhere
Approved payees, caps, currency, categoriesLocal file, ~/.fidacy/config.json
Which systems the agent may reach, unknown destinationsLocal file, via protect
Per-transaction max, currencies, geos, velocityDashboard, Policies
Action class modes with approval emailDashboard, Policies
Identity floor: anyone, declared, registered key, provenDashboard, Policies
Narrow per-agent mandatesDashboard, Authority
API keys, agents, webhooksDashboard, Settings and Agents

The payee allowlist has no dashboard editor today. It lives with the install, on purpose, so a compromised console cannot silently widen who your agents can pay.

08Proving a decision to someone else

This is what separates a log from evidence, so it is worth doing once before you need it.

Get the receipt. Ask your agent to get the audit proof for that decision, or open the decision in the dashboard and download the Incident Pack.

Hand it over. The person checking does not need an account, our cooperation, or even our servers to be up. They verify the signature against our public key set, using the open source verifier or any standard JOSE library.

npm i @fidacy/verify

What it proves. That this exact decision, with this exact content, was made by this key, under this policy version. The policy version is sealed inside the signature, so nobody can claim afterwards that different rules were in force.

Anchoring, for things that must survive years. The point is the timestamp: a signature proves who said something, not when, because whoever holds the key can restate a date later. An external chain cannot be restated by us. Only the hash leaves your machine, which is what makes this usable for documents nobody is willing to hand over. Anyone can check one at fidacy.com/verify.

Looks like a failure, is not

The anchor verifier exits with code 2 when inclusion is proven but the Bitcoin attestation has not confirmed yet. Confirmation takes as long as a block takes. Exit 2 means wait, not invalid.

09Plans, limits and what they cost

Anonymous, no account. Twenty firewall decisions, free, nothing to sign up for. When they run out the firewall fails closed: payments are refused until you activate. That is deliberate. A trial that expires into "everything allowed" would be worse than no trial.

Free account. Three hundred server-signed verdicts every month, no card. Your block history from the anonymous install moves across when you claim it.

Pay as you go. Past the free 300 in a month: $0.10 per verdict, dropping to $0.06 past 50,000 and $0.04 past 250,000. No plan needed. Team and Scale include a monthly allowance and price the overage below that rate, which is the whole point of committing. The full ladder is on pricing.

Rate limits on the hosted engine: 600 requests per minute per organization, 300 per key. If you hit them you get a 429 telling you how long to wait.

What happens at a limit

Only server-signed verdicts and anchors pause. The local firewall keeps deciding and blocking exactly as before. You lose the proof, not the protection.

10Precautions

Write caps as bare numbers. 2500, not "2,500", not "$2500", not "2500 USD". A cap the firewall cannot compare is a cap that cannot protect you, so it refuses loudly and falls back to the safe default rather than running without a limit.

Know which key does what. FIDACY_ENGINE_API_KEY is the one that activates your install and powers hosted verdicts. There is also a key inside your config file, provisioned automatically for attribution: it does not activate anything, and confusing the two is the most common activation problem.

Non-payment protection is off until you turn it on. All eight action classes start in "record only". If you installed Fidacy expecting it to block a dangerous file deletion out of the box, run protect first.

Trailing spaces in system patterns are load bearing. A pattern of "rm " with the space trimmed becomes "rm", which matches crm, form and confirm.

Grants expire in 120 seconds. An approval is meant to be used now, not stored.

A malformed mandate variable silently reverts to the safe default. It warns on stderr and keeps running with our defaults instead of your rules. If your payees suddenly stop being recognized, check FIDACY_MANDATE_JSON first.

Some spending-mandate fields are accepted but not enforced yet. Daily and monthly maximums, velocity, and merchant category rules come back marked as deferred. Do not rely on them as controls today.

Telemetry is anonymous, and you can turn it off. What leaves your machine is an install identifier, a version, an event type, and for decisions, the outcome and the order of magnitude of the amount. The payee, the exact amount, the invoice, file paths and your hostname never leave. Every field is a closed list of values precisely so it cannot become a channel for personal data.

export FIDACY_DISABLE_TELEMETRY=1

11Getting the most out of it

Start narrow, then open with intent. The default refuses everything, and that is a feature. Run for a day, look at what got refused, and approve exactly those payees. You end up with an allowlist that reflects reality rather than your guess about it.

Set caps to your real ceiling, not a comfortable one. A per-payment cap of 2500 stops an agent that was talked into sending 50,000. A cap of 100,000 stops nothing. The cap is your worst acceptable single mistake.

Use invoice references on everything. They cost nothing and they are what makes duplicate-invoice fraud impossible rather than unlikely. This is the number one payment fraud pattern, and the control for it is one field.

Read the first week of refusals. Ask your agent weekly to list the decisions that were blocked, and to explain any you do not recognize. A refusal you cannot explain is either a rule that is too tight or an attempt you needed to know about, and both are worth five minutes.

Turn on the classes that would ruin your day. For most teams that is credential reads and file deletions, set to "ask", so you get an email instead of a surprise.

Require identity once your agents are registered. Registering agents and raising the identity floor moves you from rules about payments to rules about which agent may do what, which is a much stronger position.

Anchor what you might have to defend. Contracts, claims, the conversation where the customer agreed to something. It costs one call and it is the difference between your word and proof.

12When something goes wrong

Refusals you did not expect

Ask your agent to explain the decision; it will say the same thing this table says, about your specific case.

What you seeWhat it meansWhat to do
payee_not_in_allowlistDeny by default, working as intended.Run allow <payee>.
payee_lookalikeThe payee imitates one you approved.If it really is a different vendor, add it explicitly. If not, the firewall just did its job.
per_tx_cap_exceededOver the per-payment ceiling.Raise perTxMax, or split the payment.
total_cap_exceededPast the budget for the window.Raise maxTotal or wait. Blocked attempts did not consume it.
duplicate_invoiceThis invoice was already paid.If genuinely a second payment, give it its own reference.
currency_not_allowedNot the mandate's currency.One currency per mandate, on purpose. Set currency.
category_not_allowedPurpose outside what you permitted.Add it to categories.
after_mandate_windowThe mandate expired.Extend the window. Local default runs 30 days.
mandate_revokedRevoked mandates cannot be un-revoked.Issue a new one.
invalid_mandate_capYour cap is not a usable number.Write bare digits. See chapter 10.
activation_requiredThe 20 free decisions are gone.Claim a free key and set FIDACY_ENGINE_API_KEY.

Everything else

SymptomCauseFix
The server seems frozenIt is waiting on stdio. Correct behavior.Nothing. Ctrl+C to exit.
Agent does not see the toolsHost not restarted, or never registered.Restart, then install --write.
"needs an engine key"Key not set where the agent runs.Set it in the agent's environment, not just your shell.
401 unauthorizedKey missing, wrong, or revoked. All three look identical.Check the key in Settings; create a new one if unsure.
403 forbiddenThe key lacks the scope for that call.Create a key with the right scope.
429 rate_limited600/min per org, 300/min per key.Wait the seconds it tells you.
402 payment_requiredMonthly allowance or spending cap reached.Billing. The local firewall keeps protecting meanwhile.
Your payees stopped workingMalformed mandate variable fell back to defaults.Check stderr for the warning; fix or unset it.
Spend total or dedup resetAudit log was quarantined, or you upgraded across a format change.Expected. New chain starts; old history preserved but not counted.
Audit export says not continuousChain gap in the exported range.Read the body, not the status. Tell us the range.
When the network is down

Local decisions do not need the network and keep working. Hosted calls fail closed for that call only: you get an error, and no money moves. Your protection does not depend on our uptime.

13How to use the documentation

Use this manual for how to use it, and go elsewhere for the rest.

Docs explains what the layer is and how a verdict is produced. Proof shows the system's public activity and the anchor chain: send it to someone who asks whether any of this is real. Verify checks any receipt or hash, with no account. Pricing carries the full ladder.

The pulse endpoint returns live totals with no auth. Every number we publish comes from there, so you can check ours. The public key set is what makes a signature verifiable without us, and @fidacy/verify on npm is the open source verifier, Apache-2.0, with no dependency on our servers.

The fastest way to answer a question about your own setup is to ask your agent. verify_mandate tells you exactly what rules are in force right now, which is more reliable than reading a file and hoping you read it right.

Twenty decisions, no account, no card.

Chapter 2 is five minutes. If you would rather see it refuse something before reading anything, install it and ask your agent to pay someone.