Skip to main content
Glama

intent-gateway is a self-hosted gateway, run with npx or Docker, that gives AI agents real shopping under a privacy policy the developer controls. It is the open-source developer channel of intent: the agent searches and prepares a checkout, a person approves each purchase with a passkey, and the developer's own Shop account pays.

Developers · Docs · Security · Contributing

licence: Apache-2.0 ci npm next

Pre-alpha preview. Preview releases are on npm (intent-gateway@next) and GHCR (ghcr.io/golden007eye/intent-gateway). The demo runs on your machine and needs nothing: no invite, no account. Real purchases need an invite: they go through the Intent Cloud host this preview uses by default, where approving needs an Intent Cloud passkey made at an invite-gated sign-up (Real purchases).

Quickstart: the demo

The demo runs the whole flow on your machine with no setup: a demo Intent Cloud on 127.0.0.1 with a sample catalog and the published test keys, and a local confirm page that stands in for the passkey step. Every tool result says DEMO: test keys, sample catalog, nothing can be bought.

You need Node 22 LTS (22.22.2 or later), 24 LTS (24.15 or later) or 26+ and Claude Code. Any MCP client works the same way. Node 23 and 25 are not supported; Docker needs no Node.

1 · Add the demo gateway to Claude Code:

$ claude mcp add intent -- npx -y intent-gateway@next demo

If Claude Code already has an MCP server named intent (for example a connector added in your Claude account), use another name, claude mcp add intent-demo -- …, so the agent cannot pick the wrong one.

2 · Ask for something. Start claude and ask:

> Find stickers to ZIP 94107 in the US, under $20, and prepare a cart for the cheapest.

The agent calls find_offers, which the gateway answers by searching the demo Shop itself, then create_cart, which creates the Shop checkout and submits it for approval, and shows an approval link such as http://127.0.0.1:8788/confirm/c/…. Open it, check the item and total, enter the demo code and click Approve $ with demo passkey. The code is six digits, new on every start and never shown to the agent; the page shows the command that reads it (cat <data dir>/demo/approval-code). Then ask the agent to check the approval status: it reports the purchase as approved, with the approver passkey's fingerprint, and the gateway pays it at once from the demo Shop's agent budget (one tap), so the status reads ordered (read from Shop). Keep the Claude Code session open until then: the confirm page runs inside the gateway it started.

Working on a remote machine over SSH? Forward the confirm page to your laptop's browser with ssh -L 8788:127.0.0.1:8788 <host>. If port 8788 is taken, the demo uses another one and says so on startup; INTENT_DEMO_CONFIRM_PORT chooses it (demo page).

3 · Check what was sent:

$ npx -y intent-gateway@next verify --demo

It re-checks the local hash chain, every receipt Intent Cloud returns, the approval and the order, and ends with verify: ok. npx -y intent-gateway@next log --demo shows each action with the values it sent and its outcome; add -v for every entry, or --json for one action per line (the log). The demo page has the details, and npx -y intent-gateway@next demo --http serves the demo over HTTP instead, printing the line to connect with and the demo code.

From a clone

To run the code on main instead of the preview release, build the package (this needs pnpm: corepack enable) and use it in place of intent-gateway@next:

$ git clone https://github.com/golden007eye/intent-gateway.git
$ cd intent-gateway
$ pnpm install && pnpm build && npm pack && mv intent-gateway-*.tgz intent-gateway.tgz
$ claude mcp add intent -- npx -y "file:$PWD/intent-gateway.tgz" demo
$ npx -y ./intent-gateway.tgz verify --demo

With Docker

The image runs the same package and serves MCP over HTTP. Pull the preview from GHCR and name it intent-gateway, the name the commands below and the gateway's own hints use (or build it from a clone: docker build -t intent-gateway .):

$ docker pull ghcr.io/golden007eye/intent-gateway:0.1.0-preview.7
$ docker tag ghcr.io/golden007eye/intent-gateway:0.1.0-preview.7 intent-gateway
$ docker run -d --name intent -p 127.0.0.1:8787:8787 -p 127.0.0.1:8788:8788 \
    -e INTENT_DEMO=1 -v intent-data:/data intent-gateway
$ docker logs intent

On its first start the container makes an HTTP token and saves it in /data/http-token; once the gateway is serving it prints the token once, inside the line to paste (a start that fails prints no line). That line is also kept in the container's log (docker logs); add -e INTENT_QUIET_TOKEN=1 to never print it.

$ claude mcp add intent --transport http http://127.0.0.1:8787/mcp --header "Authorization: Bearer <token>"

Later starts reuse the token without printing it; read it with docker exec intent cat /data/http-token. Port 8788 is the demo's confirm page and must be published on the same host port, as above. Over SSH, ssh -L 8788:127.0.0.1:8788 <host> is the only forward you need: the agent runs on the server and connects to 8787 there. The demo code is in docker logs intent, or read it with docker exec intent cat /data/demo/approval-code. Check what was sent with docker exec intent intent verify --demo.

Always publish ports as -p 127.0.0.1:…, never a bare -p 8787:8787. For a bind mount instead of a volume, add --user "$(id -u):$(id -g)". Without INTENT_DEMO=1 the container talks to the Intent Cloud host this preview uses by default, whose root key this build pins; when it cannot reach that host, it exits with a line saying so and how to re-run it in demo mode.

Related MCP server: Parley

Real purchases, with an invite

Real purchases go through the Intent Cloud host this preview uses by default, and they need an invite: approving needs an Intent Cloud passkey, and the sign-up that makes one is invite-gated. An invite comes with the onboarding prompt (onboarding/claude-code.md), which sets up each step below with you in Claude Code. The demo needs no invite and no account.

What a real purchase needs:

  1. Your Intent Cloud passkey, made at the invite-gated sign-up. You approve every purchase with it on intent's confirm page.

  2. Your own Shop account, linked. Shop does not accept the gateway's own client yet (a formal registration is pending), so linking needs INTENT_SHOP_CLIENT_ID set explicitly to a client Shop accepts, such as Shop's public client for your own agent: INTENT_SHOP_CLIENT_ID=<client id> intent wallet link shop (from an agent's shell, which shows output only when a command ends: --start, then --finish; see one tap). Shop holds the card, the addresses and the budget; the gateway keeps only an encrypted token.

  3. An agent budget in the Shop app ("Allow agent to pay", with a limit). One tap pays from that budget only.

  4. The account key, which intent init makes once (<data dir>/account-key.json). There is one per developer: your first passkey approval pins it to you. To replace it today, move account-key.json aside and run intent init again.

What happens in one purchase:

  • Search. With Shop linked, find_offers runs in the gateway, through Shop. Nothing is sent to Intent Cloud for a search.

  • Checkout. create_cart creates the Shop checkout, reads it back, checks it, and submits it to Intent Cloud for passkey approval (contract 1.7.1). What leaves the gateway on that submit: the store, the item, the quantity, the totals and currency, the country and coarse postcode, a checkout reference hash, the completion mode, and two public keys (the account key and the purchase's completer key). A hand-off submit also carries Shop's checkout page link, which the log keeps only as its sha256.

  • Approval. You check the item, total and check code on the confirm page and approve with your passkey.

  • Payment. One tap pays from the Shop budget at once. When one tap cannot pay (the store refuses agent payment, or the budget is too low), the purchase goes to Shop's checkout page instead, and that hand-off needs a second approval: a new cart, approved again, then you pay on Shop's page.

Limits in the preview. Intent Cloud enforces a ceiling of $50 per order and $100 per week, and one for each other currency it lists. Suggested caps for your policy are $20 per order and $40 per week (intent policy add per-order-20, intent policy add weekly-40). Your policy can only lower the ceiling, never raise it.

Where it ships. The US, Canada, Australia, the UK, Ireland and the euro countries (Germany, France, the Netherlands, Spain, Italy, Belgium, Austria, Portugal and Finland), each in the currency the table Intent Cloud returns gives it. Outside the US, search needs the linked Shop wallet. Your policy stays in US dollars, and the gateway scales each limit by Intent Cloud's ceilings: $20 is CAD 28, AUD 30, GBP 16 or EUR 20. Shop agent payments outside the US are not yet checked, so a first order there may go to Shop's checkout page instead.

The Shop budget is the only hard stop. Any program running as you, your agent included, can read the Shop token and pay Shop directly, around the passkey, your policy, the ceiling and Pause. Keep the budget small; turning it off in the Shop app stops every agent payment.

See One-tap purchases for each step and what Shop holds.

How privacy is verified

You can check what left your machine instead of taking our word for it.

  • Disclosure log. The gateway appends every field it is about to send to a local hash chain before each request leaves for Intent Cloud, or for a linked Shop wallet. A send whose log append fails does not happen. Credentials, such as the Shop token, are logged only as their sha256.

  • Disclosure receipts. Intent Cloud returns a signed receipt over the digest of the bytes it received, which the gateway matches against the log. Shop signs no receipt: the log records the status Shop returned and a sha256 and size of its answer.

  • intent verify re-checks the hash chain, every receipt and every approval offline, and self-checks the installed package. Independent checks with your own tools (npm audit signatures, cosign verify) are listed in Verify.

  • intent evidence <approval handle> writes one purchase's evidence pack: the requests sent, their receipts, the passkey-signed approval and the outcome statements, which anyone can check offline with intent verify --evidence <file>.

What this does not cover: intent verify proves what the gateway sent, what Intent Cloud acknowledged receiving and what Shop returned. It makes no claim about what happens to that data afterwards. An evidence pack cannot prove offline that it holds every entry of its purchase; see the known risks.

Stopping purchases

intent pause stops every purchase that goes through intent and isn't paid yet. For a hard stop, also turn off agent payments in the Shop app.

The pause holds on your machine at once, then goes to Intent Cloud through the disclosure log. intent status says since when purchases are paused and which ones it stopped; the panel has the same Pause button and banner. Once Intent Cloud has acknowledged the pause, intent resume sends you to the confirm page's /account, where you resume with your passkey. Until then (for example with no account key on your machine, or no connection) the pause holds on your machine only, and intent resume lifts it there. Pause cannot stop a program that reads the Shop token and pays Shop directly; only turning off agent payments in the Shop app can.

What it does not do

  • It does not store or forward the buyer's name, postal address or card. Shop holds them in the buyer's Shop account; on a hand-off the buyer enters or confirms them on Shop's checkout page.

  • It holds no money: no custody, no crypto wallet. With one tap, the gateway sends no payment details; Shop charges the account's agent budget.

  • It cannot buy without a person. Every purchase needs one passkey-signed Approval, and a policy that turns approval off is rejected at load time.

  • It does not convert currencies. A purchase is in the ship-to country's currency, and its limits are scaled, never its prices.

Gateway policy and policy library

A gateway policy is a YAML file that decides what may leave the gateway and how much may be spent. It can only narrow the rules Intent Cloud enforces, never loosen them, including the preview ceiling of $50 per order and $100 per week. With no policy file, the bundled zip-only policy applies: the only ship-to detail that leaves is the country and a coarse postcode (in the US, the 5-digit ZIP).

# policy.yaml · can only narrow the rules Intent Cloud enforces
version: 1
approval: passkey          # required; anything else is rejected
share:
  ship_to: postcode_only   # a coarse postcode (a 5-digit ZIP), never a street or name
spend:
  per_order_usd: 20        # suggested for the preview
  per_week_usd: 40
merchants:
  block: [dropship.example]

The policy library holds thirteen reviewed policies, bundled with the gateway. intent policy add <name> narrows your policy with one and shows the change as a diff first; intent policy test <cases.yaml> runs test cases against it. See Gateway policy and Policy library.

Security and threat model

The threat model lists what the gateway protects, where its trust boundaries are, and what is out of scope. To report a vulnerability, see SECURITY.md. The rules this code is held to are listed in CLAUDE.md, and settled design decisions are in docs/adr/.

Licence

Apache-2.0. See LICENSE and NOTICE.

Available Tools

3 tools
create_cartA

Prepare a cart for the offer the user picked, using its offer_handle from find_offers. This does not buy anything: every purchase needs a person to approve it with a passkey, through the link or QR code in the result. Pass a quantity only if the user asked for one. US delivery only. The result ends with what this gateway sent to Intent Cloud and what it blocked.

NameRequiredDescriptionDefault
quantityNoHow many the user asked for (1 to 3). Defaults to 1.
offer_handleYesThe offer_handle of the offer the user picked, from find_offers.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses that nothing is purchased without a passkey approval, that approval happens out-of-band via a link/QR in the result, and that the response ends with what the gateway sent to Intent Cloud and what it blocked. These are exactly the behavioral facts an agent cannot get from structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the action and its input source, then layers the non-purchase guarantee, the conditional quantity rule, the delivery constraint, and the return content. Every sentence adds a distinct fact with no padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite no output schema, the description summarizes what the result contains (approval link/QR plus the gateway payload and blocked items), and covers prerequisites, locality limits, and the fact that approval is a separate human step. Nothing an agent needs to invoke this safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real semantic guidance beyond the schema: quantity should only be passed when the user explicitly asked for it, and offer_handle must come from find_offers. This is useful conditional nuance the pattern/range constraints don't convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Prepare a cart') and ties the input directly to its sibling by requiring the offer_handle from find_offers. It also immediately disambiguates from purchasing, so an agent can tell this apart from any buy/checkout tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear conditions: use the offer_handle returned by find_offers, pass quantity only if the user asked, and US delivery only. It does not explicitly name get_approval_status as the follow-up tool, leaving the post-creation workflow to be inferred from the mention of an approval link/QR.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_offersA

Find physical products that ship to a US address. Pass only what the user said: an exact product or a kind of product, any must-haves, their budget in US dollars and their 5-digit US ZIP code. Never guess a ZIP code or a budget. If the result lists missing details, ask the user only for those, then call again. US delivery only. The result ends with what this gateway sent to Intent Cloud and what it blocked.

NameRequiredDescriptionDefault
zipNoThe 5-digit US ZIP code the user said to ship to. Never guess it.
productNoAn exact product the user named. Give this or category.
categoryNoThe kind of product the user wants, such as running-shoes. Give this or product.
budget_usdNoThe most the user said they will spend, in US dollars. Never guess it.
must_havesNoFeatures the user said the product must have, in their words.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It discloses key behavioral traits: US-delivery-only constraint, that it ends with what was sent to Intent Cloud and what was blocked, and retry semantics for missing details. Doesn't cover auth requirements or rate limits, but the behavioral disclosure is substantial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose, then provides usage rules and behavioral notes. Mostly efficient, though the sentence about Intent Cloud and blocking could be tighter. Still, every sentence serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, but the description hints at return content (missing details list, what was sent to Intent Cloud, what was blocked). For a 5-param tool with no required params and no annotations, this does a good job covering the operational context, though more on return format would help.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 5 parameters thoroughly. The description reinforces key rules (never guess ZIP or budget, pass only what user said) but adds no syntax or format details beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (find) and resource (physical products) with clear scope constraint (ships to a US address). Distinguishes from siblings like create_cart and get_approval_status by being a discovery/search tool rather than a transactional or status tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear instructions on what to pass and when to retry (if result lists missing details, ask user only for those, then call again). Doesn't explicitly name sibling alternatives or state when NOT to use it, but the usage context is clearly conveyed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_approval_statusA

Check whether the person approved a purchase with their passkey, using the approval_handle from create_cart. Only a passkey approval the gateway verified counts as approved; tell the user what the result says. The result ends with what this gateway sent to Intent Cloud and what it blocked.

NameRequiredDescriptionDefault
approval_handleYesThe approval_handle that create_cart returned.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It adds useful semantics ('only a passkey approval the gateway verified counts as approved') and hints at return content, but says nothing about whether approval is asynchronous or must be polled, error/pending states, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the purpose and the required input provenance. The closing sentence about Intent Cloud and blocked items is slightly extraneous but still informative, so no significant waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema or annotations exist, so the description must cover behavior. It partially describes the result contents but omits the response shape, whether the call is idempotent/repeatable, and how to interpret non-approved outcomes – gaps for a verification-style tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema itself already documents the single parameter, including its pattern and that create_cart returns it. The description's mention of the handle merely repeats the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (check) and resource (whether the person approved a purchase with their passkey), and ties itself to create_cart as the source of the handle, which separates it from the sibling create_cart/find_offers tools. An agent can tell what it returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear sequencing context: use the approval_handle that create_cart returned, and relay the result to the user. It does not state when NOT to call it (e.g. before an approval exists) or name alternatives, so it falls short of the explicit when/when-not/alternative bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0-preview.3
    • First observedcreate_cart
    • First observedfind_offers
    • First observedget_approval_status

TDQS

A4.1/5.0

Scored across 3 tools

Disambiguation5/5

Each tool occupies a single, distinct step in one linear flow: searching offers, preparing a cart from a chosen offer, and checking passkey approval status. The handles involved (offer_handle vs approval_handle) further separate the tools so an agent cannot easily mix them up.

Naming Consistency5/5

All three names follow a clean verb_noun snake_case pattern: find_offers, create_cart, get_approval_status. No style drift or vague verbs.

Tool Count4/5

Three tools is on the lean side, but it matches the narrow purpose of a US product checkout gateway where one step leads deterministically to the next. Nothing extraneous, though it leaves little room for supplementary operations.

Completeness4/5

The find -> create cart -> approve lifecycle is fully covered end to end, including the human passkey gate. Minor gaps like updating quantity after cart creation or cancelling/expiring a cart are absent but can be worked around by asking the user.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to discover, check stock, and purchase products through your existing store APIs, with spend mandates, discount ceilings, and a full audit trail enforced in code.
    59,508 npm
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to search and compare products across multiple retailers, build carts, and propose purchases that only a human can authorise, with a self-hosted control panel.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI shopping agents to search products, check stock, apply promotions, manage cart sessions, and create cryptographically signed checkout sessions on e-commerce storefronts, while giving merchants analytics into agent intent and catalog demand gaps.
    MIT