@agentwares/agentguard 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
package/dist/index.js CHANGED
@@ -1574,7 +1574,7 @@ function createDownstreamServer(runtime, opts = {}) {
1574
1574
  return server;
1575
1575
  }
1576
1576
 
1577
- // ../../packages/mcp-kit/dist/chunk-NF4BQXVM.js
1577
+ // ../../packages/mcp-kit/dist/chunk-7LRFDQNC.js
1578
1578
  import { completable } from "@modelcontextprotocol/sdk/server/completable.js";
1579
1579
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
1580
1580
  import {
@@ -1586,6 +1586,18 @@ import {
1586
1586
  import { z } from "zod";
1587
1587
 
1588
1588
  // ../../packages/x402/dist/index.js
1589
+ var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
1590
+ var USDC_DECIMALS = 6;
1591
+ var USDC_EIP712_DOMAIN = { name: "USD Coin", version: "2" };
1592
+ function toAtomicUnits(amountUsd, decimals = USDC_DECIMALS) {
1593
+ const trimmed = amountUsd.trim();
1594
+ if (!/^\d+(\.\d+)?$/.test(trimmed)) throw new Error(`not a decimal amount: ${amountUsd}`);
1595
+ const [whole = "0", fraction = ""] = trimmed.split(".");
1596
+ if (fraction.length > decimals) {
1597
+ throw new Error(`${amountUsd} has more than ${decimals} decimal places`);
1598
+ }
1599
+ return `${whole}${fraction.padEnd(decimals, "0")}`.replace(/^0+(?=\d)/, "");
1600
+ }
1589
1601
  var DEFAULT_X402_NETWORK = "eip155:8453";
1590
1602
  var X402_HEADER = "X-Payment-Requirements";
1591
1603
  var X402_REQUIRED_HEADER = "PAYMENT-REQUIRED";
@@ -1601,13 +1613,18 @@ function buildPaymentRequired(opts) {
1601
1613
  if (opts.payTo) {
1602
1614
  accepts.push({
1603
1615
  rail: "x402",
1616
+ scheme: "exact",
1604
1617
  amountUsd,
1618
+ amount: toAtomicUnits(amountUsd, opts.assetDecimals),
1605
1619
  resource: opts.resource,
1606
1620
  description: opts.description,
1621
+ mimeType: "application/json",
1607
1622
  network: opts.network ?? DEFAULT_X402_NETWORK,
1608
- asset: "USDC",
1623
+ asset: opts.asset ?? USDC_BASE,
1624
+ extra: opts.assetDomain ?? USDC_EIP712_DOMAIN,
1609
1625
  payTo: opts.payTo,
1610
- maxTimeoutSeconds: 300
1626
+ maxTimeoutSeconds: 300,
1627
+ ...opts.bazaar ? { bazaar: opts.bazaar } : {}
1611
1628
  });
1612
1629
  }
1613
1630
  if (creditsPayTo) {
@@ -1625,7 +1642,11 @@ function buildPaymentRequired(opts) {
1625
1642
  }
1626
1643
  const live = opts.live === true;
1627
1644
  const selfServe = opts.selfServe;
1628
- const liveFix = selfServe ? `Free first: retry with sample=true \u2014 no key, no payment. To pay: POST ${selfServe.keysUrl} (no auth, no signup) returns a key and a Stripe Checkout URL. Funding that key needs a person to complete the Checkout page in a browser; if you are running unattended, surface the URL to your operator rather than retrying. Once funded, send Authorization: Bearer <key>, plus Idempotency-Key so a repeated call is charged once.` : "Retry with a PAYMENT header satisfying one of `accepts`, or send an API key with credit balance.";
1645
+ const x402Rail = accepts.find((a) => a.rail === "x402" && a.payTo);
1646
+ const usdcFix = x402Rail ? `Pay in USDC with no account and no human: take the \`accepts\` entry with \`rail: "x402"\`, sign an EIP-3009 transferWithAuthorization for ${x402Rail.amountUsd} USDC to ${x402Rail.payTo} on ${x402Rail.network}, and retry with it base64 in the X-PAYMENT header. The facilitator submits the transfer, so you need USDC and no gas. ` : "";
1647
+ const sampleFix = opts.sampleMode ? "Free first: retry with sample=true \u2014 no key, no payment. " : "";
1648
+ const cardFix = selfServe ? `Or pay by card: POST ${selfServe.keysUrl} (no auth, no signup) returns a key and a Stripe Checkout URL. Funding that key needs a person at a browser; if you are running unattended, surface the URL to your operator rather than retrying, or use the USDC rail above. Once funded, send Authorization: Bearer <key>, plus Idempotency-Key so a repeated call is charged once.` : "";
1649
+ const liveFix = usdcFix || cardFix ? `${sampleFix}${usdcFix}${cardFix}`.trim() : "Retry with a PAYMENT header satisfying one of `accepts`, or send an API key with credit balance.";
1629
1650
  const body = {
1630
1651
  code: "PAYMENT_REQUIRED",
1631
1652
  cause: live ? `This call costs $${amountUsd}. No valid payment or credit was presented.` : `This call costs $${amountUsd}. Pay-per-call (x402 / Stripe MPP) is coming soon; use an API key with prepaid credits.`,
@@ -1634,10 +1655,19 @@ function buildPaymentRequired(opts) {
1634
1655
  priceUsd: opts.priceUsd,
1635
1656
  accepts,
1636
1657
  comingSoon: !live,
1637
- alternatives: ["api_key_credits", "sample_mode"],
1638
- ...selfServe ? { selfServe } : {}
1658
+ alternatives: [
1659
+ ...creditsPayTo ? ["api_key_credits"] : [],
1660
+ ...opts.sampleMode ? ["sample_mode"] : []
1661
+ ],
1662
+ ...selfServe ? { selfServe } : {},
1663
+ ...opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}
1639
1664
  };
1640
- const encoded = JSON.stringify({ x402Version: 2, accepts, resource: opts.resource });
1665
+ const encoded = JSON.stringify({
1666
+ x402Version: 2,
1667
+ accepts,
1668
+ resource: opts.resource,
1669
+ ...opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}
1670
+ });
1641
1671
  const headers = {
1642
1672
  "Content-Type": "application/json",
1643
1673
  "WWW-Authenticate": `Payment realm="agentwares", methods="x402 prepaid_credits", price="${amountUsd} USD"`,
@@ -1658,7 +1688,7 @@ var StubVerifier = class {
1658
1688
  }
1659
1689
  };
1660
1690
 
1661
- // ../../packages/mcp-kit/dist/chunk-NF4BQXVM.js
1691
+ // ../../packages/mcp-kit/dist/chunk-7LRFDQNC.js
1662
1692
  import { z as z2 } from "zod";
1663
1693
  import { z as z3 } from "zod";
1664
1694
  import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -2130,21 +2160,26 @@ function withPayment(tool, opts) {
2130
2160
  if (auth.ok) return tool.handler(record, { ...ctx, userId: auth.userId });
2131
2161
  reason = auth.reason;
2132
2162
  }
2163
+ const resource = ctx.resourceUrl ?? tool.name;
2133
2164
  const required = buildPaymentRequired({
2134
- resource: tool.name,
2165
+ resource,
2135
2166
  priceUsd: opts.priceUsd,
2136
2167
  live: opts.live,
2137
2168
  description: opts.description,
2138
2169
  payTo: opts.payTo,
2139
2170
  creditsPayTo: opts.creditsPayTo,
2140
2171
  signupUrl: opts.signupUrl,
2141
- selfServe: opts.selfServe
2172
+ selfServe: opts.selfServe,
2173
+ // withPayment always adds a free `sample` flag to the tool's input schema
2174
+ sampleMode: true,
2175
+ ...opts.bazaar ? { bazaar: opts.bazaar } : {}
2142
2176
  });
2143
2177
  const advertised = required.body.accepts.find((a) => a.rail === "prepaid_credits") ?? required.body.accepts[0];
2144
2178
  const requirement = advertised ?? {
2145
2179
  rail: "prepaid_credits",
2146
2180
  amountUsd: String(required.body.priceUsd),
2147
- resource: tool.name
2181
+ resource,
2182
+ ...opts.description ? { description: opts.description } : {}
2148
2183
  };
2149
2184
  const verified = await verifier.verify(
2150
2185
  new Request(`https://mcp.local/${tool.name}`, { headers: ctx.headers }),
@@ -3334,6 +3369,7 @@ function readServers(file) {
3334
3369
  return servers;
3335
3370
  }
3336
3371
  var PROXY_SERVER_NAME = "agentguard";
3372
+ var PROXY_PACKAGE = "@agentwares/agentguard";
3337
3373
  function isProxyEntry(entry) {
3338
3374
  return (entry.args ?? []).some((a) => a === "agentguard" || /(^|\/)agentguard(\.js)?$/.test(a)) && (entry.args ?? []).includes("proxy");
3339
3375
  }
@@ -3377,7 +3413,7 @@ function backupPath(file) {
3377
3413
  return `${file.path}.agentguard-backup`;
3378
3414
  }
3379
3415
  function proxyEntry(file, policyPath, opts = {}) {
3380
- const args = ["-y", "agentguard", "proxy", "--config", policyPath];
3416
+ const args = ["-y", PROXY_PACKAGE, "proxy", "--config", policyPath];
3381
3417
  if (opts.agent) args.push("--agent", opts.agent);
3382
3418
  const entry = { command: "npx", args };
3383
3419
  if (file.serversKey === "servers") entry.type = "stdio";
@@ -3725,6 +3761,11 @@ async function initCommand(args, io) {
3725
3761
  }
3726
3762
  if (flagBool(args, "rewrite") !== false) {
3727
3763
  for (const c of chosen) {
3764
+ if (resolve3(c.path) === resolve3(policyPath)) {
3765
+ throw new Error(
3766
+ `refusing: ${rel(c.path)} is both the policy file (--config) and a client config. Rewriting it would replace the policy with the proxy entry and leave the proxy pointing at itself. Use --config for the policy path and --client for the client's config, or let --config default to agentguard.yaml.`
3767
+ );
3768
+ }
3728
3769
  const { backup, replaced } = rewriteClientConfig(c, policyPath, {
3729
3770
  agent: flagString(args, "agent")
3730
3771
  });