{"_id":"@agenttax/mppx","name":"@agenttax/mppx","dist-tags":{"latest":"1.1.0"},"versions":{"1.1.0":{"name":"@agenttax/mppx","version":"1.1.0","description":"Tax middleware for MPP machine payments — sales tax + capital gains for AI agent transactions","main":"dist/index.js","types":"dist/index.d.ts","type":"module","scripts":{"build":"tsc","test":"vitest run","test:watch":"vitest"},"keywords":["mpp","tax","machine-payments","ai-agents","sales-tax","capital-gains","x402","agenttax"],"author":{"name":"Agentic Tax Solutions LLC"},"license":"MIT","homepage":"https://agenttax.io","repository":{"type":"git","url":"git+https://github.com/AgentTax/agenttax-mppx.git"},"peerDependencies":{"mppx":">=0.4.0"},"dependencies":{"geoip-lite":"^1.4.10"},"devDependencies":{"@types/geoip-lite":"^1.4.4","@types/node":"^25.5.0","mppx":"^0.4.8","typescript":"^5.7.0","vitest":"^3.0.0"},"engines":{"node":">=18"},"gitHead":"c58700e74f44ad9feec6031ef0cba121f4268df5","_id":"@agenttax/mppx@1.1.0","bugs":{"url":"https://github.com/AgentTax/agenttax-mppx/issues"},"_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-7Tk3NjuRVPDKUhLZoSgz5vf49xkW3oeE1ahBMDfJoSoNBjgeYB02k24N7DoTiirgZRUntrdGR8uS7BoK80XSxw==","shasum":"dd52b02e8f9f28e2463b7696da442575e2e410d8","tarball":"https://registry.npmjs.org/@agenttax/mppx/-/mppx-1.1.0.tgz","fileCount":23,"unpackedSize":67572,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDra6jP0nGwdD0wyloZFtszBR2SttapC2awjz/PVVVt2QIhAJP185cYTOoqTMwyCUhYeXqVBoIuagiMTo9OXgZrmdgu"}]},"_npmUser":{"name":"agenttaxdev","email":"Beardsley@Agenttax.io"},"directories":{},"maintainers":[{"name":"agenttaxdev","email":"Beardsley@Agenttax.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mppx_1.1.0_1777076026747_0.6698343174649448"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-25T00:13:46.676Z","1.1.0":"2026-04-25T00:13:46.904Z","modified":"2026-04-25T00:13:47.086Z"},"maintainers":[{"name":"agenttaxdev","email":"Beardsley@Agenttax.io"}],"description":"Tax middleware for MPP machine payments — sales tax + capital gains for AI agent transactions","homepage":"https://agenttax.io","keywords":["mpp","tax","machine-payments","ai-agents","sales-tax","capital-gains","x402","agenttax"],"repository":{"type":"git","url":"git+https://github.com/AgentTax/agenttax-mppx.git"},"author":{"name":"Agentic Tax Solutions LLC"},"bugs":{"url":"https://github.com/AgentTax/agenttax-mppx/issues"},"license":"MIT","readme":"# @agenttax/mppx\n\nTax middleware for MPP (Machine Payments Protocol). Makes any machine payment endpoint tax-compliant with one line of code.\n\n## Why\n\nMPP enables AI agents to pay for services programmatically. But every transaction is a taxable digital service in most US states — and nobody is calculating that tax. This middleware fills the gap.\n\n## Install\n\n```\nnpm install @agenttax/mppx\n```\n\n## Quick Start\n\n```ts\nimport { Mppx, tempo } from 'mppx/express'\nimport { agentTax } from '@agenttax/mppx'\n\nconst mppx = Mppx.create({\n  secretKey: process.env.MPP_SECRET_KEY,\n  methods: [tempo({ recipient: '0x...', currency: USDC })],\n})\n\nconst tax = agentTax({\n  apiKey: process.env.AGENTTAX_API_KEY,\n  transactionType: 'compute',\n  workType: 'compute',\n})\n\n// Replace mppx.charge() with tax.charge()\napp.get('/api/gpu-hour',\n  tax.charge(mppx, { amount: '1.00', description: 'GPU compute hour' }),\n  (req, res) => { res.json({ result: '...' }) }\n)\n```\n\nThe middleware:\n1. Detects buyer jurisdiction (IP geolocation + optional X-Buyer-State header)\n2. Calls AgentTax API to calculate sales tax\n3. Adjusts the 402 challenge to the tax-inclusive amount\n4. Attaches an X-Tax-Receipt header to the response\n\n## Auto-Split Tax to Separate Wallet\n\n```ts\nconst tax = agentTax({\n  apiKey: process.env.AGENTTAX_API_KEY,\n  transactionType: 'compute',\n  taxReserveWallet: '0x...your-tax-reserve',\n})\n```\n\nTax portion automatically routes to a separate wallet via MPP splits. Both wallets belong to the merchant. AgentTax never touches the money.\n\n## Capital Gains Tracking\n\n```ts\nconst tax = agentTax({\n  apiKey: process.env.AGENTTAX_API_KEY,\n  transactionType: 'compute',\n  asset: {\n    symbol: 'GPU_HOUR',\n    trackGains: true,\n    accountingMethod: 'fifo',\n    residentState: 'TX',\n  },\n})\n```\n\nEvery payment logged as a trade. Sell-side responses include realized gain/loss.\n\n## Buyer Headers (Optional)\n\nBuyers can self-report jurisdiction for higher accuracy:\n\n- `X-Buyer-State: TX` — 2-letter state code\n- `X-Buyer-Zip: 78701` — 5-digit zip for local rates\n\nThe middleware cross-verifies against IP and flags mismatches. Datacenter/VPN IPs are detected and flagged automatically.\n\n## When AgentTax Is Unreachable\n\nBy default, if the AgentTax API can't be reached, the middleware **rejects the charge with HTTP 503**. This is the conservative default — charging base-amount-only with no tax receipt is a compliance gap. Your caller sees the error and can retry.\n\nYou can opt into legacy fail-open behavior with `onTaxUnavailable: 'allow'`. **Read the warning below before doing this.**\n\n### ⚠ Warning on `onTaxUnavailable: 'allow'` (fail-open)\n\nSetting `onTaxUnavailable: 'allow'` causes the middleware to proceed with a **$0-tax receipt** when the AgentTax API is unreachable. The charge still completes; the buyer is undercharged; you have no calculation trail for that transaction.\n\nUse this setting only if **both** are true:\n\n1. Your flow is demonstrably non-taxable in every jurisdiction you reach (e.g. SKUs limited to no-sales-tax states, or an exempt-sale-only platform).\n2. You have a **separate compliance control** outside this middleware — an independent tax engine, a manual review queue, or a documented legal opinion that $0 tax is correct for every possible buyer you can reach.\n\nEvery fail-open invocation now emits:\n\n- A `console.warn` line prefixed `[agenttax/mppx] FAIL-OPEN:` containing a structured JSON payload with timestamp, buyer state/ZIP, base amount, transaction type, and counterparty ID.\n- An optional `onFailOpenAudit(entry)` callback you provide in config — use it to ship the event to Sentry, Datadog, a DB audit table, or anywhere else your retention policy requires.\n\n```ts\nconst tax = agentTax({\n  apiKey: process.env.AGENTTAX_API_KEY,\n  transactionType: 'compute',\n  onTaxUnavailable: 'allow',            // opt-in; read warning above\n  onFailOpenAudit: (entry) => {\n    await db.query(\n      'INSERT INTO fail_open_audit(event, ts, state, amount, counterparty, tx_type) VALUES ($1,$2,$3,$4,$5,$6)',\n      [entry.event, entry.timestamp, entry.buyer_state, entry.base_amount, entry.counterparty_id, entry.transaction_type]\n    );\n  },\n});\n```\n\nIf you run with `'allow'` and no `onFailOpenAudit` sink, you still get the stderr line — but shipping those to a proper audit store (not just Vercel function logs, which rotate) is on you.\n\n## Configuration\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `apiKey` | string | required | AgentTax API key |\n| `transactionType` | string | required | compute, saas, api_access, etc. |\n| `workType` | string | inferred | compute, research, content, consulting, trading |\n| `role` | string | 'seller' | 'seller' or 'buyer' |\n| `isB2B` | boolean | false | B2B transaction flag |\n| `defaultState` | string | - | Fallback state when jurisdiction can't be determined |\n| `taxReserveWallet` | string | - | 0x address for auto-split tax to separate wallet |\n| `asset.symbol` | string | - | Asset identifier for capital gains tracking |\n| `asset.trackGains` | boolean | false | Enable trade logging |\n| `asset.accountingMethod` | string | 'fifo' | fifo, lifo, or specific_id |\n| `asset.residentState` | string | - | State for capital gains rate |\n| `baseUrl` | string | https://agenttax.io | AgentTax API base URL |\n| `counterpartyIdFrom` | string | 'source' | How to derive counterparty ID: ip, source, or header |\n| `onTaxUnavailable` | string | 'reject' | 'reject' (503 on API outage) or 'allow' (fail-open, logs audit; see warning above) |\n| `onFailOpenAudit` | function | - | Optional callback `(entry) => void` invoked for every fail-open. Use to ship to your audit store. |\n\n## Get an API Key\n\n```bash\ncurl -X POST https://agenttax.io/api/v1/auth/signup \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"you@example.com\", \"password\": \"securepass\", \"agent_name\": \"my-agent\"}'\n```\n\nFree tier: 100 calls/month. Save the `api_key.key` from the response — it's only shown once.\n\n## Links\n\n- [AgentTax](https://agenttax.io)\n- [MPP Protocol](https://mpp.dev)\n- [Agent Integration Guide](https://agenttax.io/api/v1/agents)\n- [MCP Server](https://github.com/AgentTax/agenttax-mcp)\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-73529c7c3806d340ddd49aad236936e2"}