for builders · about 30 minutes
Connect one tool. Give your agent a Card.
About 30 minutes with test data. Connect a remote MCP tool, give an agent a Card, run a call inside it, approve one outside it, and check what the tool actually did.
quick start · test data only
Six steps. One Card, end to end.
you need
- A KIFF account. Sign up at app.kiff.dev.
- Claude Code or Codex.
- A remote MCP tool in test mode that takes an amount in whole euros. The refund tutorial builds one on Stripe test mode.
- A paid test order of €300 in that tool. With the tutorial's tool,
python3 create_test_order.pycreates one and prints its order number.
- agent
- tester-agent
- tool
- refund_order · amount_eur
- order
- YOUR_ORDER_NUMBER · paid €300
- Card
- €50 a call · €200 and 10 calls a day · Ask
the skill assists
Your coding agent, with the KIFF skill, explains each step, drafts the Card and reads KIFF's answers. It can be wrong, and it never decides.
KIFF enforces
KIFF checks every call against the Card before the tool gets it, whatever the agent or the skill says.
Add the KIFF skill
Claude Code:
/plugin marketplace add kiff/kiff-plugins, then/plugin install kiff-cards@kiff. Codex: add the skill fromkiff.dev/skills/kiff.md. Then paste the prompt, with your tool's URL.- skill
- Tells you which screens to open and drafts the Card terms. It never asks for a key.
- KIFF
- An agent's key can only ask. It cannot connect tools, issue Cards or approve.
Stuck? The KIFF skill
I'm testing KIFF with test data only. Use the KIFF skill (https://kiff.dev/skills/kiff.md). My test tool is a remote MCP server at [YOUR TOOL URL]. Its refund_order tool takes order_number and amount_eur (whole euros), in test mode. My agent is tester-agent. 1. Walk me through connecting refund_order in KIFF Cloud. I do every click. Never ask for, read or type a key. 2. Draft a Card for tester-agent: €50 most per call, €200 a day, 10 calls a day, Ask outside the Card, holds wait 10 minutes. One sentence per line on why. 3. Once I'm connected, call kiff_card and tell me what the Card allows. Never route around a held or refused call.expectThe agent lists the steps and a five-line Card draft, and asks you to do the clicks.
Connect one tool
In KIFF Cloud, Tools → Connect a tool. Enter the server URL and its credential, then List the server's tools. On
refund_order, set the amount a Card limits toamount_eurand click Connect refund_order. Addtester-agentunder Agents, and connect your client from its Tools tab.- skill
- Explains each field and the client setup.
- KIFF
- KIFF keeps the tool's credential, so the agent reaches the tool only through KIFF.
If your client also has the tool configured directly, remove that entry: KIFF only governs calls that go through it. Stuck? MCP gateway
expectYour client lists kiff_card and refund_order. A call now is refused: the tool has no Card yet.
Give tester-agent a Card
On
refund_order, Give an agent a Card: €50 most per call, €200 and 10 calls per day, Ask outside the Card, holds wait 10 minutes. Issue this Card, then ask your agent to callkiff_card.- skill
- Proposes the limits and explains Ask and Stop. You decide.
- KIFF
- Only an owner or admin issues, changes or revokes a Card. It lives with you, not in the agent.
Stuck? KIFF Cards
expectkiff_card names tester-agent: €50 a call, €200 and 10 calls a day, nothing used yet.
Run a call inside the Card
A €20 refund is under every limit, so nobody needs to approve it. In this prompt and the next two, replace
YOUR_ORDER_NUMBERwith your test order's number.- skill
- Gives the call its own kiff_operation_id and reports the result.
- KIFF
- Checks €20 against the Card, sends the call to the tool once and signs a receipt.
Running the test again? Give each new call a new id, such as
tester-20-002. Reuse an id only to resend the same call, as in the next step.Use only the KIFF MCP tools. Call refund_order exactly once with: order_number=YOUR_ORDER_NUMBER amount_eur=20 reason=KIFF tester run kiff_operation_id=tester-20-001 Report the tool's result and whether the call was sent.expectA €20 test refund. kiff_card: €20 of €200 used, 1 of 10 calls.
Go past the limit, then approve once
An €80 refund is over €50 a call. Run the first prompt, open the review link or Needs you within 10 minutes, choose Approve once, then run the second prompt with the same arguments.
- skill
- Stops on the hold, shows you the link, and resends the identical call.
- KIFF
- Nothing reaches the tool until a person approves. The €80 still counts toward the €200.
If the totals have no room when the call is resent, the approved call waits until the period resets or an admin adds room. Stuck? Held calls and approvals
Use only the KIFF MCP tools. Call refund_order exactly once with: order_number=YOUR_ORDER_NUMBER amount_eur=80 reason=KIFF tester exception kiff_operation_id=tester-80-001 Report state, sent and the review link. Stop if held. Do not retry, change the arguments, or refund another way.Resume the approved operation through KIFF. Call refund_order with exactly the original arguments: order_number=YOUR_ORDER_NUMBER amount_eur=80 reason=KIFF tester exception kiff_operation_id=tester-80-001 Change nothing. Report the actual tool result.expectFirst: state held, sent no, a link to app.kiff.dev. After approving: an €80 test refund, and €100 of €200 used.
Check what the tool did
Allowed is not the same as done. Open Activity and read the Tool column for both calls, then find the two refunds in the tool's own test dashboard.
- skill
- Reports what the tool returned. It does not call an error done.
- KIFF
- Keeps the tool's reported outcome next to the decision. An agent cannot write it.
expectActivity shows both calls done. The tool shows €20 and €80 refunded, €100 in total.
you're done when
- The skill guided setup and never asked for a key.
- The €20 call went through without an approval.
- The €80 call was held, and nothing was sent.
- After Approve once, the same call ran, and €100 of €200 was used.
- Activity and the tool's own records agree.
It works. Now a real action.
Tell us what you tested and where you got stuck. We'll help you put a Card on a real action in your stack.
why builders use KIFF
Build the agent once. Let the owner change its authority.
When every limit lives in prompts or code, every change a client asks for is an engineering change for you. With KIFF the owner changes the Card, and your agent keeps running the same code. Approval does not scale; delegation does.
work gets cheap
Agents attempt more actions, more often, in more situations.
totals start to matter
Each action may be fine. A thousand in a day is a different exposure.
approval does not scale
If a person signs off every action, the savings stop there.
delegate, with bounds
Defined work, valid conditions, up to a total. People set, change and withdraw it.
Build the agent. Not the authority layer around it: limits, ownership, balances, revocation and evidence come with KIFF instead of being rebuilt for every customer.
the instrument · closer to a pilot’s licence than a credit card
Money is only the first thing a card can count.
REFUND_ORDERonly on a paid order
€5,000 a day
CHANGE_ACCOUNT_EMAILonly once the customer is verified
3 an hour
DEPLOY_SERVICEonly when the build has passed
2 a day
PURGE_ROWSonly on records past retention
50,000 rows a day
Illustrative cards, each expressible today. Not a payment card, and not a badge. The domain decides whether an action is valid at all; a limit bounds exposure. It does not make a wrong action right.
- Observe
Advisory decisions; the agent keeps its flow.
- Issue small
A narrow set of actions and a low limit.
- Widen it on the record
Raise it when the statement earns it.
- Withdraw
Revoke in one step. No redeploy, no call to you.
a card’s day · tap through
What the owner sees, one decision at a time.
You issue the refunds agent its card.
REFUND_ORDER, only when the order is PAID, up to €5,000 per calendar day.
REFUND_ORDERPAID- card issued · €5,000/day · by ops lead
The agent proposes a €4,000 refund on a paid order.
Within the conditions and the ceiling. KIFF authorizes and draws €4,000; your system runs the refund.
REFUND_ORDERPAID- card issued · €5,000/day · by ops lead
- REFUND_ORDER €4,000 · ord_8812 · authorized
The agent proposes a further €1,500 refund.
The order may be eligible, but €1,500 exceeds the €1,000 left today. Refused, nothing drawn.
REFUND_ORDERPAID- card issued · €5,000/day · by ops lead
- REFUND_ORDER €4,000 · ord_8812 · authorized
- REFUND_ORDER €1,500 · ord_9120 · refused, ceiling
You revoke the card.
One action from the owner. No redeploy, no call to the builder.
REFUND_ORDERPAID- card issued · €5,000/day · by ops lead
- REFUND_ORDER €4,000 · ord_8812 · authorized
- REFUND_ORDER €1,500 · ord_9120 · refused, ceiling
- card revoked · by ops lead
The agent is told to try €200 anyway.
New instructions do not restore authority. The proposal is refused.
REFUND_ORDERPAID- card issued · €5,000/day · by ops lead
- REFUND_ORDER €4,000 · ord_8812 · authorized
- REFUND_ORDER €1,500 · ord_9120 · refused, ceiling
- card revoked · by ops lead
- REFUND_ORDER €200 · ord_9377 · refused, revoked
Illustrative decisions, not a customer run. KIFF authorizes; the owner’s system executes.
why not write it yourself?
A limit is quick to write. Keeping it correct is the hard part.
LIMIT = 5000 # per day
spent_today = load_spent()
def refund(order, amount):
if spent_today + amount <= LIMIT:
save_spent(spent_today + amount)
payments.refund(order, amount)A typical first version. Tap each production event to compare it with KIFF.
Two runs refund €800 in the same second, with €1,000 left.
Both read €1,000 left. Both pass. €1,600 goes out.
Draws on a card are locked. The second sees €200 left and is refused.
The payment call times out and the framework retries the same refund.
The retry is counted again. The limit is reached by money that moved once.
The draw is keyed to the proposal. The retry counts once.
The agent is redeployed at noon, or scaled to three workers.
Each process keeps its own count, or starts from zero. The limit multiplies.
One balance per card, held centrally across every run, process and machine.
The store holding the balance does not answer.
The error becomes zero spent. The agent has a full limit.
An unreadable balance refuses. It shows as unknown, never zero.
The agent is told a VIP customer needs more room today.
The limit sits in config the agent’s deployment can change.
The agent’s key cannot change its card. A ceiling change takes the owner’s management key.
The owner asks what happened on Tuesday.
Application logs, written by the same system that acted.
A signed, tamper-evident record of every authorization and refusal.
what building with KIFF includes
Ship the agent without rebuilding its controls.
One workflow at a time: integration and control testing first, then the owner handover, then operations views once it is live.
- Integrate
The first card: the domain, the card and the check before the tool call, on one real workflow.
- Control testing
Did the operation respect the owner’s authority under concurrency, retries, restarts, outages and revocation?
- Hand over
The Card Handover Package: authority, coverage, tests, emergency steps and the owner’s acceptance.
- Operate
Operations views: the owner sees each agent and its authority; you see the health of what you built.
A passing control test shows the protected path holds. It does not prove the whole workflow is safe, or that no other path exists. Actions that bypass the check need their own controls.
# No adapter needed. Wrap the one function that moves money.
def issue_refund(order, amount):
d = kiff.decide("REFUND_ORDER", entity=order, amount=amount)
if not d.allowed:
return d # blocked or held, never execute
payments.refund(order, amount) # your code, unchanged| 08:00 | card issued · €5,000 per day | by ops lead | |
| 09:12 | ord_8812 · order PAID | authorized | −€4,000 |
| 11:40 | ord_9120 · €1,500 | refused · ceiling | €0 |
where this goes · not built today
Authority someone can read.
Today a card is enforced within one KIFF account, for the agents that hold it, on software actions. We are building toward these with the teams who need them; none is available yet.
physical agents
Equipment, areas and shifts a robot may work.
short-lived authority
A card for one task or one window.
agents that delegate
Pass part of the authority on, never growing the total.
across organizations
Show verifiably what an agent may do for another company.
Start with one workflow.
A conversation, not a commitment. Any implementation scope, price and duration is agreed before work begins.