@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.
- package/dist/cli.js +53 -12
- package/dist/cli.js.map +1 -1
- package/dist/fixtures/crm-server.js +46 -11
- package/dist/fixtures/crm-server.js.map +1 -1
- package/dist/fixtures/demo-agent.js +0 -0
- package/dist/index.js +53 -12
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
- package/server.json +2 -2
- package/LICENSE +0 -21
|
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-
|
|
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:
|
|
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
|
|
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: [
|
|
1638
|
-
|
|
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({
|
|
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-
|
|
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
|
|
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
|
|
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",
|
|
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
|
});
|