@agentwares/agentguard 0.1.3 → 0.1.5
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
package/dist/cli.js
CHANGED
|
@@ -937,7 +937,7 @@ import {
|
|
|
937
937
|
} from "@agentwares/agentguard-core/node";
|
|
938
938
|
import { existsSync as exists, readFileSync as readFileSync2 } from "fs";
|
|
939
939
|
|
|
940
|
-
// ../../packages/mcp-kit/dist/chunk-
|
|
940
|
+
// ../../packages/mcp-kit/dist/chunk-7LRFDQNC.js
|
|
941
941
|
import { completable } from "@modelcontextprotocol/sdk/server/completable.js";
|
|
942
942
|
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
943
943
|
import {
|
|
@@ -949,6 +949,18 @@ import {
|
|
|
949
949
|
import { z } from "zod";
|
|
950
950
|
|
|
951
951
|
// ../../packages/x402/dist/index.js
|
|
952
|
+
var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
953
|
+
var USDC_DECIMALS = 6;
|
|
954
|
+
var USDC_EIP712_DOMAIN = { name: "USD Coin", version: "2" };
|
|
955
|
+
function toAtomicUnits(amountUsd, decimals = USDC_DECIMALS) {
|
|
956
|
+
const trimmed = amountUsd.trim();
|
|
957
|
+
if (!/^\d+(\.\d+)?$/.test(trimmed)) throw new Error(`not a decimal amount: ${amountUsd}`);
|
|
958
|
+
const [whole = "0", fraction = ""] = trimmed.split(".");
|
|
959
|
+
if (fraction.length > decimals) {
|
|
960
|
+
throw new Error(`${amountUsd} has more than ${decimals} decimal places`);
|
|
961
|
+
}
|
|
962
|
+
return `${whole}${fraction.padEnd(decimals, "0")}`.replace(/^0+(?=\d)/, "");
|
|
963
|
+
}
|
|
952
964
|
var DEFAULT_X402_NETWORK = "eip155:8453";
|
|
953
965
|
var X402_HEADER = "X-Payment-Requirements";
|
|
954
966
|
var X402_REQUIRED_HEADER = "PAYMENT-REQUIRED";
|
|
@@ -964,13 +976,18 @@ function buildPaymentRequired(opts) {
|
|
|
964
976
|
if (opts.payTo) {
|
|
965
977
|
accepts.push({
|
|
966
978
|
rail: "x402",
|
|
979
|
+
scheme: "exact",
|
|
967
980
|
amountUsd,
|
|
981
|
+
amount: toAtomicUnits(amountUsd, opts.assetDecimals),
|
|
968
982
|
resource: opts.resource,
|
|
969
983
|
description: opts.description,
|
|
984
|
+
mimeType: "application/json",
|
|
970
985
|
network: opts.network ?? DEFAULT_X402_NETWORK,
|
|
971
|
-
asset:
|
|
986
|
+
asset: opts.asset ?? USDC_BASE,
|
|
987
|
+
extra: opts.assetDomain ?? USDC_EIP712_DOMAIN,
|
|
972
988
|
payTo: opts.payTo,
|
|
973
|
-
maxTimeoutSeconds: 300
|
|
989
|
+
maxTimeoutSeconds: 300,
|
|
990
|
+
...opts.bazaar ? { bazaar: opts.bazaar } : {}
|
|
974
991
|
});
|
|
975
992
|
}
|
|
976
993
|
if (creditsPayTo) {
|
|
@@ -988,7 +1005,11 @@ function buildPaymentRequired(opts) {
|
|
|
988
1005
|
}
|
|
989
1006
|
const live = opts.live === true;
|
|
990
1007
|
const selfServe = opts.selfServe;
|
|
991
|
-
const
|
|
1008
|
+
const x402Rail = accepts.find((a) => a.rail === "x402" && a.payTo);
|
|
1009
|
+
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. ` : "";
|
|
1010
|
+
const sampleFix = opts.sampleMode ? "Free first: retry with sample=true \u2014 no key, no payment. " : "";
|
|
1011
|
+
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.` : "";
|
|
1012
|
+
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.";
|
|
992
1013
|
const body = {
|
|
993
1014
|
code: "PAYMENT_REQUIRED",
|
|
994
1015
|
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.`,
|
|
@@ -997,10 +1018,19 @@ function buildPaymentRequired(opts) {
|
|
|
997
1018
|
priceUsd: opts.priceUsd,
|
|
998
1019
|
accepts,
|
|
999
1020
|
comingSoon: !live,
|
|
1000
|
-
alternatives: [
|
|
1001
|
-
|
|
1021
|
+
alternatives: [
|
|
1022
|
+
...creditsPayTo ? ["api_key_credits"] : [],
|
|
1023
|
+
...opts.sampleMode ? ["sample_mode"] : []
|
|
1024
|
+
],
|
|
1025
|
+
...selfServe ? { selfServe } : {},
|
|
1026
|
+
...opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}
|
|
1002
1027
|
};
|
|
1003
|
-
const encoded = JSON.stringify({
|
|
1028
|
+
const encoded = JSON.stringify({
|
|
1029
|
+
x402Version: 2,
|
|
1030
|
+
accepts,
|
|
1031
|
+
resource: opts.resource,
|
|
1032
|
+
...opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}
|
|
1033
|
+
});
|
|
1004
1034
|
const headers = {
|
|
1005
1035
|
"Content-Type": "application/json",
|
|
1006
1036
|
"WWW-Authenticate": `Payment realm="agentwares", methods="x402 prepaid_credits", price="${amountUsd} USD"`,
|
|
@@ -1021,7 +1051,7 @@ var StubVerifier = class {
|
|
|
1021
1051
|
}
|
|
1022
1052
|
};
|
|
1023
1053
|
|
|
1024
|
-
// ../../packages/mcp-kit/dist/chunk-
|
|
1054
|
+
// ../../packages/mcp-kit/dist/chunk-7LRFDQNC.js
|
|
1025
1055
|
import { z as z2 } from "zod";
|
|
1026
1056
|
import { z as z3 } from "zod";
|
|
1027
1057
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -1493,21 +1523,26 @@ function withPayment(tool, opts) {
|
|
|
1493
1523
|
if (auth.ok) return tool.handler(record, { ...ctx, userId: auth.userId });
|
|
1494
1524
|
reason = auth.reason;
|
|
1495
1525
|
}
|
|
1526
|
+
const resource = ctx.resourceUrl ?? tool.name;
|
|
1496
1527
|
const required = buildPaymentRequired({
|
|
1497
|
-
resource
|
|
1528
|
+
resource,
|
|
1498
1529
|
priceUsd: opts.priceUsd,
|
|
1499
1530
|
live: opts.live,
|
|
1500
1531
|
description: opts.description,
|
|
1501
1532
|
payTo: opts.payTo,
|
|
1502
1533
|
creditsPayTo: opts.creditsPayTo,
|
|
1503
1534
|
signupUrl: opts.signupUrl,
|
|
1504
|
-
selfServe: opts.selfServe
|
|
1535
|
+
selfServe: opts.selfServe,
|
|
1536
|
+
// withPayment always adds a free `sample` flag to the tool's input schema
|
|
1537
|
+
sampleMode: true,
|
|
1538
|
+
...opts.bazaar ? { bazaar: opts.bazaar } : {}
|
|
1505
1539
|
});
|
|
1506
1540
|
const advertised = required.body.accepts.find((a) => a.rail === "prepaid_credits") ?? required.body.accepts[0];
|
|
1507
1541
|
const requirement = advertised ?? {
|
|
1508
1542
|
rail: "prepaid_credits",
|
|
1509
1543
|
amountUsd: String(required.body.priceUsd),
|
|
1510
|
-
resource
|
|
1544
|
+
resource,
|
|
1545
|
+
...opts.description ? { description: opts.description } : {}
|
|
1511
1546
|
};
|
|
1512
1547
|
const verified = await verifier.verify(
|
|
1513
1548
|
new Request(`https://mcp.local/${tool.name}`, { headers: ctx.headers }),
|
|
@@ -2740,6 +2775,7 @@ function readServers(file) {
|
|
|
2740
2775
|
return servers;
|
|
2741
2776
|
}
|
|
2742
2777
|
var PROXY_SERVER_NAME = "agentguard";
|
|
2778
|
+
var PROXY_PACKAGE = "@agentwares/agentguard";
|
|
2743
2779
|
function isProxyEntry(entry) {
|
|
2744
2780
|
return (entry.args ?? []).some((a) => a === "agentguard" || /(^|\/)agentguard(\.js)?$/.test(a)) && (entry.args ?? []).includes("proxy");
|
|
2745
2781
|
}
|
|
@@ -2783,7 +2819,7 @@ function backupPath(file) {
|
|
|
2783
2819
|
return `${file.path}.agentguard-backup`;
|
|
2784
2820
|
}
|
|
2785
2821
|
function proxyEntry(file, policyPath, opts = {}) {
|
|
2786
|
-
const args = ["-y",
|
|
2822
|
+
const args = ["-y", PROXY_PACKAGE, "proxy", "--config", policyPath];
|
|
2787
2823
|
if (opts.agent) args.push("--agent", opts.agent);
|
|
2788
2824
|
const entry = { command: "npx", args };
|
|
2789
2825
|
if (file.serversKey === "servers") entry.type = "stdio";
|
|
@@ -3836,6 +3872,11 @@ async function initCommand(args, io) {
|
|
|
3836
3872
|
}
|
|
3837
3873
|
if (flagBool(args, "rewrite") !== false) {
|
|
3838
3874
|
for (const c of chosen) {
|
|
3875
|
+
if (resolve3(c.path) === resolve3(policyPath)) {
|
|
3876
|
+
throw new Error(
|
|
3877
|
+
`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.`
|
|
3878
|
+
);
|
|
3879
|
+
}
|
|
3839
3880
|
const { backup, replaced } = rewriteClientConfig(c, policyPath, {
|
|
3840
3881
|
agent: flagString(args, "agent")
|
|
3841
3882
|
});
|