# Distribution

How the SDK, wallet MCP, gateway and service MCPs ship and where they run.

**Testnet demo setup**
This page covers the agent-pay testnet service integration. To use the hosted wallet and bundled shopping tools, add the single public URL in [Connect an AI agent](/en/docs/agents/). The service registration and hosting steps below are for developers adding their own service. Arrange registry access and testnet setup with [business@pouchi.app](mailto:business@pouchi.app) before deploying.

This page lists how each component ships, and who runs it where. Addresses are placeholders (`example.com`).
The chain is Maroo Testnet (`chainId 450815`).

## At a glance

| Component | Built by | Ships as | Runs at |
|---|---|---|---|
| `@shard-lab/nc-waas-react`, `@shard-lab/nc-waas-sdk` | Pouchi | GitHub Packages (now), npm (after public release) | Customer app (browser, server) |
| `@shard-lab/agentpay-service-kit`, `@shard-lab/create-agentpay-service` | Pouchi | GitHub Packages (now), npm (after public release) | Each service's server |
| Wallet MCP (`apps/remote-mcp`) | Pouchi | Docker image (`APP=remote-mcp`) | Hosted by Pouchi. Users add one URL |
| Gateway (`apps/gateway`) | Pouchi tenant | Docker image (`APP=gateway`) | Tenant server (same network as the wallet MCP) |
| Service MCPs (shop, finance, new services) | Each service | The service's own Docker image | Hosted by each service |
| Developer docs (`apps/docs`) | Pouchi | Static files (`dist/`) | Static hosting (CDN) |

## 1. SDK packages

For now they are published only to GitHub Packages in the shard-lab org. Installing needs a `read:packages` token.

```ini
# .npmrc (token from an environment variable only)
@shard-lab:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NC_WAAS_PACKAGES_TOKEN}
```

| Repository | Staging command | Output |
|---|---|---|
| nc-waas | `npm run packages:github:stage -- --pack` | `artifacts/github-packages/` (react, sdk, protocol, client-vault) |
| agent-pay | `npm run packages:github:stage -- --pack` | `artifacts/github-packages/` (service-kit, create-agentpay-service) |

- Neither script publishes. They check names, the version (`0.1.0`), `file:` dependencies, imports from outside the repository and secret patterns, then run `npm pack --dry-run`.
- Publishing is done with `npm publish` in each staging directory after a separate approval.
- Moving to public npm: drop `publishConfig.registry` and remove the `.npmrc` instructions from the docs. Package names stay the same.

## 2. Wallet MCP hosting

Public users add the hosted URL from the agent guide. The Docker commands below describe repository hosting. The public connection uses OAuth dynamic client registration and authorization code with PKCE.
The wallet MCP holds no keys. Payments are approved only on the Pouchi approval screen.

```sh
docker build --build-arg APP=remote-mcp -t agentpay-wallet-mcp .
docker run -d -p 9410:9410 -v wallet-mcp-state:/app/.local --env-file wallet-mcp.env agentpay-wallet-mcp
```

| Variable | Example | Notes |
|---|---|---|
| `REMOTE_MCP_PUBLIC_URL` | `https://wallet-mcp.example.com` | Base for the OAuth issuer and resource URL. https required |
| `AGENT_PAY_WAAS_URL` | `https://api.example.com` | Pouchi API |
| `AGENT_PAY_GATEWAY_URL` | `http://gateway:9401` | Gateway (internal network) |
| `AGENT_PAY_TENANT_ID` | `tenant_agent_pay` | Tenant |
| `AGENT_PAY_CHAIN_ID`, `AGENT_PAY_RPC_URL` | `450815`, `https://rpc-testnet.maroo.io` | Chain |
| `REGISTRY_PATH` | `/app/registry/shops.tkrw.json` | Registered services |
| `REMOTE_MCP_ALLOWED_ORIGINS` | (empty) | Only when a browser calls it directly |

- State (user connections, token hashes) is stored in `/app/.local`. Mount a volume, and move it to a database before running more than one instance.
- Proxies in front must not buffer SSE (pass the `X-Accel-Buffering: no` response through, read timeout 300 seconds or more).

## 3. Gateway (tenant)

```sh
docker build --build-arg APP=gateway -t agentpay-gateway .
docker run -d -p 9401:9401 -v gateway-state:/app/.local --env-file gateway.env agentpay-gateway
```

| Variable | Notes |
|---|---|
| `WAAS_URL`, `WAAS_USER_WEB_URL` | Pouchi API and the user approval screen |
| `APPROVAL_SURFACE=waas-web` | Every approval on the Pouchi screen |
| `TENANT_ID`, `CHAIN_ID`, `CHAIN_RPC_URL`, `REGISTRY_PATH` | Tenant, chain, registry |
| `GATEWAY_PUBLIC_URL`, `REMOTE_MCP_URL` | Public URL, wallet MCP URL |
| `TENANT_SIGNER_PRIVATE_KEY` | Tenant delegate key. Signs runs of delegations where the tenant is the delegate. Injected from a secret manager. Never in the image or the repository |
| `MANDATE_CREDENTIAL_KEY_FILE` | Master key file for service credentials. Changing it invalidates every service credential |
| `OWNER_CALL_CREDENTIAL_FILE` | Tenant Client Credential that turns a one-time purchase into one transaction (optional) |

## 4. Service MCPs (each service)

Each service builds and hosts its own. Start from the template.

```sh
npm init @shard-lab/agentpay-service acme-news -- --name "Acme News"
cd acme-news && npm install && npm test
docker build --secret id=npmrc,src=$HOME/.npmrc \
  --secret id=packages_token,env=NC_WAAS_PACKAGES_TOKEN -t acme-news-mcp .
docker run -d -p 8080:8080 --env-file .env acme-news-mcp
```

| Variable | Notes |
|---|---|
| `SERVICE_ID`, `SERVICE_NAME` | The id registered with the tenant, and the display name |
| `PUBLIC_URL` | Must match the registered origin exactly (`https://acme.example.com`) |
| `AGENTPAY_GATEWAY_URL` | Tenant gateway (when there are later charges) |
| `PAYMENT_TOKEN_ADDRESS`, `MERCHANT_CONTRACT_ADDRESS` | Payment token and service contract (both registered with the tenant) |

### App registration requirements

1. Service: `id`, `name`, `origin`, whether later charges are allowed (`merchantCharges`)
2. Contracts: the addresses the service requests mandates for. Pin the code hash, and also register them in the Pouchi tenant console so approval screens show their names.
3. Deployed origin: `AGENTPAY_SERVICE_ORIGINS="acme-news=https://acme.example.com"` on the gateway and the wallet MCP

Until it is registered, the wallet does not accept intents from that origin. A service can request mandates only for its own registered contracts.

### Service requirements

- Serve `/intents/<id>` and `/agentpay/mandates` from the same origin over https (the kit handles this).
- Store received mandate credentials encrypted. Each can be used only for its one mandate; give it back with `release` when the user cancels.
- The service MCP does not need login, because it only builds quotes and intents.

## 5. Agent app configuration

The public endpoint in [Connect an AI agent](/en/docs/agents/) includes the wallet and `shop_*` tools in one URL. No second shopping MCP is needed. The configurations below are for a developer hosting a custom wallet/service setup; replace every example.com address with a registered deployment. Custom service MCPs only quote and build intents, so they do not require wallet sign-in.

**Hermes** (`~/.hermes/config.yaml`)

```yaml
mcp_servers:
  agentpay:
    url: "https://wallet-mcp.example.com/mcp"
    auth: oauth
    oauth: { flow: device }   # or browser
    timeout: 300              # wait while the user approves
  acme:
    url: "https://acme.example.com/mcp"
    timeout: 120
```

**Claude Code**

```sh
claude mcp add --transport http agentpay https://wallet-mcp.example.com/mcp
claude mcp add --transport http acme https://acme.example.com/mcp
```

**Claude desktop, claude.ai**: add a custom connector under Connectors in settings and enter the URL. The OAuth login window opens on first use.

**Cursor** (`~/.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "agentpay": { "url": "https://wallet-mcp.example.com/mcp" },
    "acme": { "url": "https://acme.example.com/mcp" }
  }
}
```

For a payments-only agent, we recommend not turning on shell, file or web tools as well (agent-pay `tools/hermes/config.example.yaml`).

## 6. Developer docs

```sh
cd apps/docs && npm ci && npm run build   # static files in dist/
```

The docs build produces static files in `dist/`. The product landing page is built separately in `apps/brand`. There are no external scripts or trackers.

## Remaining before deployment

- Move wallet MCP and gateway state from files to a database (multiple instances)
- Replace `TENANT_SIGNER_PRIVATE_KEY` with KMS signing
- Move service registration from the registry file to the tenant console API
- Create the agent-pay remote (GitHub) repository and approve package publishing
