@aura-payments/mcp-server 1.1.0 → 1.2.0
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/bin.js +286 -2
- package/dist/bin.mjs +286 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +286 -2
- package/dist/index.mjs +286 -2
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -134,6 +134,22 @@ function registerEscrowResources(server) {
|
|
|
134
134
|
}
|
|
135
135
|
);
|
|
136
136
|
}
|
|
137
|
+
|
|
138
|
+
// src/resources/insights.ts
|
|
139
|
+
function registerInsightsResources(server, clientFactory = getClient) {
|
|
140
|
+
server.resource("insights-overview", "aura://insights/overview", async (uri) => {
|
|
141
|
+
const overview = await clientFactory().insights.overview();
|
|
142
|
+
return {
|
|
143
|
+
contents: [
|
|
144
|
+
{
|
|
145
|
+
uri: uri.href,
|
|
146
|
+
mimeType: "application/json",
|
|
147
|
+
text: JSON.stringify(overview, null, 2)
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
}
|
|
137
153
|
function registerMandateResources(server) {
|
|
138
154
|
server.resource(
|
|
139
155
|
"mandates-pending",
|
|
@@ -220,6 +236,42 @@ function registerWalletResources(server) {
|
|
|
220
236
|
}
|
|
221
237
|
);
|
|
222
238
|
}
|
|
239
|
+
var COLLECTION_LIMIT3 = 50;
|
|
240
|
+
var WithdrawalIdSchema = zod.z.string().uuid();
|
|
241
|
+
function registerWithdrawalResources(server, clientFactory = getClient) {
|
|
242
|
+
server.resource("withdrawals", "aura://withdrawals", async (uri) => {
|
|
243
|
+
const page = await clientFactory().withdrawals.list({ limit: COLLECTION_LIMIT3 });
|
|
244
|
+
return {
|
|
245
|
+
contents: [
|
|
246
|
+
{
|
|
247
|
+
uri: uri.href,
|
|
248
|
+
mimeType: "application/json",
|
|
249
|
+
text: JSON.stringify(page, null, 2)
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
};
|
|
253
|
+
});
|
|
254
|
+
server.resource(
|
|
255
|
+
"withdrawal",
|
|
256
|
+
new mcp_js.ResourceTemplate("aura://withdrawals/{id}", { list: void 0 }),
|
|
257
|
+
async (uri, { id }) => {
|
|
258
|
+
const parsed = WithdrawalIdSchema.safeParse(Array.isArray(id) ? id[0] : id);
|
|
259
|
+
if (!parsed.success) {
|
|
260
|
+
throw new Error(`Invalid withdrawal id in ${uri.href}: expected a UUID`);
|
|
261
|
+
}
|
|
262
|
+
const withdrawal = await clientFactory().withdrawals.get(parsed.data);
|
|
263
|
+
return {
|
|
264
|
+
contents: [
|
|
265
|
+
{
|
|
266
|
+
uri: uri.href,
|
|
267
|
+
mimeType: "application/json",
|
|
268
|
+
text: JSON.stringify(withdrawal, null, 2)
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
);
|
|
274
|
+
}
|
|
223
275
|
|
|
224
276
|
// src/annotations.ts
|
|
225
277
|
function readOnly(title) {
|
|
@@ -598,6 +650,118 @@ function registerEscrowTools(server) {
|
|
|
598
650
|
"aura_receive_and_split"
|
|
599
651
|
];
|
|
600
652
|
}
|
|
653
|
+
function validationError(error) {
|
|
654
|
+
const detail = error.issues.map((issue) => `${issue.path.join(".") || "(input)"}: ${issue.message}`).join("; ");
|
|
655
|
+
return toolError("VALIDATION_ERROR", detail);
|
|
656
|
+
}
|
|
657
|
+
function addCustomRangeIssues(ctx, field, selector, start, end) {
|
|
658
|
+
if (selector === "custom" && (start === void 0 || end === void 0)) {
|
|
659
|
+
ctx.addIssue({
|
|
660
|
+
code: zod.z.ZodIssueCode.custom,
|
|
661
|
+
path: [start === void 0 ? "start" : "end"],
|
|
662
|
+
message: `start and end are both required when ${field} is 'custom'`
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
if (start !== void 0 && end !== void 0 && Date.parse(start) > Date.parse(end)) {
|
|
666
|
+
ctx.addIssue({
|
|
667
|
+
code: zod.z.ZodIssueCode.custom,
|
|
668
|
+
path: ["end"],
|
|
669
|
+
message: "end must be at or after start"
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// src/tools/insights.ts
|
|
675
|
+
var PeriodSchema = zod.z.enum(["today", "7d", "30d", "90d", "custom"]);
|
|
676
|
+
var DateTimeSchema = zod.z.string().datetime();
|
|
677
|
+
var overviewShape = {
|
|
678
|
+
period: PeriodSchema.optional().describe(
|
|
679
|
+
"Window to report on (default 7d). 'custom' requires start and end."
|
|
680
|
+
),
|
|
681
|
+
start: DateTimeSchema.optional().describe("ISO 8601 datetime; required when period is custom"),
|
|
682
|
+
end: DateTimeSchema.optional().describe("ISO 8601 datetime; required when period is custom")
|
|
683
|
+
};
|
|
684
|
+
var InsightsOverviewInput = zod.z.object(overviewShape).superRefine(
|
|
685
|
+
(value, ctx) => addCustomRangeIssues(ctx, "period", value.period, value.start, value.end)
|
|
686
|
+
);
|
|
687
|
+
var auditShape = {
|
|
688
|
+
action: zod.z.string().min(1).optional().describe("Audit action name, e.g. escrow.released"),
|
|
689
|
+
actor: zod.z.enum(["user", "system", "api", "cron", "webhook"]).optional(),
|
|
690
|
+
resourceType: zod.z.string().min(1).optional().describe("Resource kind, e.g. escrow"),
|
|
691
|
+
// `.min(1)`, not `.uuid()`: the route accepts any string here
|
|
692
|
+
// (`resourceId: z.string().optional()`, insights/audit/route.ts:26) and the
|
|
693
|
+
// audit log records ids from several subsystems, not all of them UUIDs.
|
|
694
|
+
resourceId: zod.z.string().min(1).optional().describe("Id of the audited resource"),
|
|
695
|
+
range: PeriodSchema.optional().describe(
|
|
696
|
+
"Window to query (default 30d). 'custom' requires start and end."
|
|
697
|
+
),
|
|
698
|
+
start: DateTimeSchema.optional().describe("ISO 8601 datetime; required when range is custom"),
|
|
699
|
+
end: DateTimeSchema.optional().describe("ISO 8601 datetime; required when range is custom"),
|
|
700
|
+
page: zod.z.number().int().min(1).optional().describe("1-based page number (default 1)"),
|
|
701
|
+
limit: zod.z.number().int().min(1).max(100).optional().describe("Page size, 1-100 (default 50)")
|
|
702
|
+
};
|
|
703
|
+
var InsightsAuditInput = zod.z.object(auditShape).superRefine(
|
|
704
|
+
(value, ctx) => addCustomRangeIssues(ctx, "range", value.range, value.start, value.end)
|
|
705
|
+
);
|
|
706
|
+
function registerInsightsTools(server, clientFactory = getClient) {
|
|
707
|
+
server.tool(
|
|
708
|
+
"aura_insights_overview",
|
|
709
|
+
"Revenue, transaction count, active escrows and commissions for a period, each with its change against the previous period, plus sparkline and success-rate charts.",
|
|
710
|
+
overviewShape,
|
|
711
|
+
readOnly("Insights Overview"),
|
|
712
|
+
async (args) => {
|
|
713
|
+
const parsed = InsightsOverviewInput.safeParse(args);
|
|
714
|
+
if (!parsed.success) return validationError(parsed.error);
|
|
715
|
+
const { period, start, end } = parsed.data;
|
|
716
|
+
return withToolErrorHandling(
|
|
717
|
+
async () => clientFactory().insights.overview(period, start, end)
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
);
|
|
721
|
+
server.tool(
|
|
722
|
+
"aura_insights_forecast",
|
|
723
|
+
"Project a metric forward over a horizon using the requested algorithm. Requires a Growth or higher plan \u2014 lower tiers return feature_not_available.",
|
|
724
|
+
{
|
|
725
|
+
metric: zod.z.enum([
|
|
726
|
+
"revenue",
|
|
727
|
+
"transaction_count",
|
|
728
|
+
"escrow_count",
|
|
729
|
+
"commission",
|
|
730
|
+
"avg_transaction_value"
|
|
731
|
+
]),
|
|
732
|
+
algorithm: zod.z.enum([
|
|
733
|
+
"linear_regression",
|
|
734
|
+
"moving_average",
|
|
735
|
+
"exponential_smoothing",
|
|
736
|
+
"arima",
|
|
737
|
+
"prophet",
|
|
738
|
+
"ensemble"
|
|
739
|
+
]).optional(),
|
|
740
|
+
period: zod.z.enum(["daily", "weekly", "monthly"]).optional().describe("Granularity of each projected point"),
|
|
741
|
+
horizon: zod.z.number().int().min(1).max(365).optional().describe("Number of periods to project"),
|
|
742
|
+
// Known platform quirk: the route parses this with `z.coerce.boolean()`
|
|
743
|
+
// on a query string, where any non-empty value — including "false" —
|
|
744
|
+
// coerces to true. Passing false therefore does not currently suppress
|
|
745
|
+
// history; that is a platform-side fix, not one to paper over here.
|
|
746
|
+
includeHistory: zod.z.boolean().optional().describe("Include the historical series alongside the projection"),
|
|
747
|
+
historyPeriods: zod.z.number().int().min(1).max(365).optional()
|
|
748
|
+
},
|
|
749
|
+
readOnly("Insights Forecast"),
|
|
750
|
+
async (args) => withToolErrorHandling(async () => clientFactory().insights.forecast(args))
|
|
751
|
+
);
|
|
752
|
+
server.tool(
|
|
753
|
+
"aura_insights_audit",
|
|
754
|
+
"Query the account audit log by action, actor, resource and date range. Paginated, most recent first.",
|
|
755
|
+
auditShape,
|
|
756
|
+
readOnly("Insights Audit"),
|
|
757
|
+
async (args) => {
|
|
758
|
+
const parsed = InsightsAuditInput.safeParse(args);
|
|
759
|
+
if (!parsed.success) return validationError(parsed.error);
|
|
760
|
+
return withToolErrorHandling(async () => clientFactory().insights.audit(parsed.data));
|
|
761
|
+
}
|
|
762
|
+
);
|
|
763
|
+
return ["aura_insights_overview", "aura_insights_forecast", "aura_insights_audit"];
|
|
764
|
+
}
|
|
601
765
|
function registerMandateTools(server) {
|
|
602
766
|
server.tool(
|
|
603
767
|
"aura_list_mandates",
|
|
@@ -666,6 +830,18 @@ function registerMandateTools(server) {
|
|
|
666
830
|
"aura_reject_mandate"
|
|
667
831
|
];
|
|
668
832
|
}
|
|
833
|
+
|
|
834
|
+
// src/tools/treasury.ts
|
|
835
|
+
function registerTreasuryTools(server, clientFactory = getClient) {
|
|
836
|
+
server.tool(
|
|
837
|
+
"aura_treasury_optimize",
|
|
838
|
+
"Analyze treasury balances, active escrows and pending payouts, and return an AI recommendation on how to rebalance. Read-only: it recommends, it does not move funds. Requires a Growth or higher plan \u2014 lower tiers return feature_not_available.",
|
|
839
|
+
{},
|
|
840
|
+
readOnly("Treasury Optimize"),
|
|
841
|
+
async () => withToolErrorHandling(async () => clientFactory().treasury.optimize())
|
|
842
|
+
);
|
|
843
|
+
return ["aura_treasury_optimize"];
|
|
844
|
+
}
|
|
669
845
|
var TestnetChainSchema = zod.z.enum(["ARC", "ARB", "BASE"]);
|
|
670
846
|
function walletCreateEnabled() {
|
|
671
847
|
const v = (process.env.AURA_MCP_ALLOW_WALLET_CREATE ?? "").trim().toLowerCase();
|
|
@@ -801,10 +977,113 @@ function registerWebhookTools(server) {
|
|
|
801
977
|
"aura_delete_webhook_config"
|
|
802
978
|
];
|
|
803
979
|
}
|
|
980
|
+
var ChainSchema3 = zod.z.enum(["ARC", "ETH", "BASE", "ARB", "MATIC"]);
|
|
981
|
+
var AmountSchema = zod.z.string().regex(
|
|
982
|
+
/^\d+(\.\d{1,6})?$/,
|
|
983
|
+
'Amount must be a number string with up to 6 decimal places, e.g. "100.00"'
|
|
984
|
+
);
|
|
985
|
+
var EvmAddressSchema = zod.z.string().regex(
|
|
986
|
+
/^0x[a-fA-F0-9]{40}$/,
|
|
987
|
+
"Must be an EVM address: 0x followed by 40 hexadecimal characters"
|
|
988
|
+
);
|
|
989
|
+
var ExchangeSchema = zod.z.enum(["binance", "coinbase", "kraken", "other"]);
|
|
990
|
+
var FeeConfigSchema = zod.z.enum(["FREE", "GAS_ONLY", "STANDARD"]);
|
|
991
|
+
var StatusSchema = zod.z.enum(["pending", "submitted", "confirmed", "failed", "cancelled"]);
|
|
992
|
+
var WithdrawalIdSchema2 = zod.z.string().uuid("Withdrawal id must be a UUID");
|
|
993
|
+
var estimateShape = {
|
|
994
|
+
// `.min(1)`, not `.uuid()`: the route accepts any non-empty string here
|
|
995
|
+
// (`walletId: z.string().min(1)`, estimate/route.ts:56). Requiring a UUID
|
|
996
|
+
// would make this tool reject wallet ids the platform itself accepts.
|
|
997
|
+
walletId: zod.z.string().min(1).describe("Source wallet id to debit"),
|
|
998
|
+
amount: AmountSchema.describe('USDC amount as a string, e.g. "100.00"'),
|
|
999
|
+
destinationType: zod.z.enum(["exchange", "wallet"]).describe("Where the funds land. 'exchange' also requires `exchange`."),
|
|
1000
|
+
destinationAddress: EvmAddressSchema.describe("Destination EVM address"),
|
|
1001
|
+
chain: ChainSchema3.describe("Chain the funds are delivered on"),
|
|
1002
|
+
exchange: ExchangeSchema.optional().describe(
|
|
1003
|
+
"Required when destinationType is 'exchange'"
|
|
1004
|
+
),
|
|
1005
|
+
sourceChain: ChainSchema3.optional().describe(
|
|
1006
|
+
"Chain the funds start on. Differs from `chain` for a bridged withdrawal; defaults to ARC."
|
|
1007
|
+
),
|
|
1008
|
+
feeConfig: FeeConfigSchema.optional()
|
|
1009
|
+
};
|
|
1010
|
+
var EstimateWithdrawalInput = zod.z.object(estimateShape).superRefine((value, ctx) => {
|
|
1011
|
+
if (value.destinationType === "exchange" && value.exchange === void 0) {
|
|
1012
|
+
ctx.addIssue({
|
|
1013
|
+
code: zod.z.ZodIssueCode.custom,
|
|
1014
|
+
path: ["exchange"],
|
|
1015
|
+
message: "exchange is required when destinationType is 'exchange'"
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
});
|
|
1019
|
+
function registerWithdrawalTools(server, clientFactory = getClient) {
|
|
1020
|
+
server.tool(
|
|
1021
|
+
"aura_get_withdrawal",
|
|
1022
|
+
"Get a single withdrawal by id: status, amount, fees, destination, chain and transaction hash.",
|
|
1023
|
+
{ withdrawalId: WithdrawalIdSchema2.describe("The withdrawal id (UUID)") },
|
|
1024
|
+
readOnly("Get Withdrawal"),
|
|
1025
|
+
async ({ withdrawalId }) => withToolErrorHandling(async () => clientFactory().withdrawals.get(withdrawalId))
|
|
1026
|
+
);
|
|
1027
|
+
server.tool(
|
|
1028
|
+
"aura_list_withdrawals",
|
|
1029
|
+
"List withdrawals for the account, most recent first. Filter by status, chain and date range.",
|
|
1030
|
+
{
|
|
1031
|
+
limit: zod.z.number().int().min(1).max(100).optional().describe("Page size, 1-100 (default 50)"),
|
|
1032
|
+
offset: zod.z.number().int().min(0).optional().describe("Rows to skip (default 0)"),
|
|
1033
|
+
status: StatusSchema.optional(),
|
|
1034
|
+
chain: ChainSchema3.optional(),
|
|
1035
|
+
fromDate: zod.z.string().datetime().optional().describe("ISO 8601 datetime, inclusive lower bound"),
|
|
1036
|
+
toDate: zod.z.string().datetime().optional().describe("ISO 8601 datetime, inclusive upper bound")
|
|
1037
|
+
},
|
|
1038
|
+
readOnly("List Withdrawals"),
|
|
1039
|
+
async (args) => withToolErrorHandling(async () => clientFactory().withdrawals.list(args))
|
|
1040
|
+
);
|
|
1041
|
+
server.tool(
|
|
1042
|
+
"aura_estimate_withdrawal",
|
|
1043
|
+
"Preview the fees, net amount and confirmation time for a withdrawal WITHOUT creating it. Moves no funds. Use this before quoting a payout to a user.",
|
|
1044
|
+
estimateShape,
|
|
1045
|
+
readOnly("Estimate Withdrawal"),
|
|
1046
|
+
async (args) => {
|
|
1047
|
+
const parsed = EstimateWithdrawalInput.safeParse(args);
|
|
1048
|
+
if (!parsed.success) return validationError(parsed.error);
|
|
1049
|
+
return withToolErrorHandling(
|
|
1050
|
+
async () => clientFactory().withdrawals.estimate(parsed.data)
|
|
1051
|
+
);
|
|
1052
|
+
}
|
|
1053
|
+
);
|
|
1054
|
+
server.tool(
|
|
1055
|
+
"aura_get_withdrawal_limits",
|
|
1056
|
+
"Get the account KYC-tier withdrawal limits and how much of the daily and monthly allowance is still available.",
|
|
1057
|
+
{},
|
|
1058
|
+
readOnly("Get Withdrawal Limits"),
|
|
1059
|
+
async () => withToolErrorHandling(async () => clientFactory().withdrawals.limits())
|
|
1060
|
+
);
|
|
1061
|
+
server.tool(
|
|
1062
|
+
"aura_validate_withdrawal_address",
|
|
1063
|
+
"Check that a destination address is well-formed and usable on a chain, and preview the fee when an amount is given. Moves no funds.",
|
|
1064
|
+
{
|
|
1065
|
+
address: EvmAddressSchema.describe("Destination EVM address to check"),
|
|
1066
|
+
chain: ChainSchema3,
|
|
1067
|
+
amount: AmountSchema.optional().describe(
|
|
1068
|
+
"Optional \u2014 when supplied the response includes a fee preview"
|
|
1069
|
+
),
|
|
1070
|
+
feeConfig: FeeConfigSchema.optional()
|
|
1071
|
+
},
|
|
1072
|
+
readOnly("Validate Withdrawal Address"),
|
|
1073
|
+
async (args) => withToolErrorHandling(async () => clientFactory().withdrawals.validate(args))
|
|
1074
|
+
);
|
|
1075
|
+
return [
|
|
1076
|
+
"aura_get_withdrawal",
|
|
1077
|
+
"aura_list_withdrawals",
|
|
1078
|
+
"aura_estimate_withdrawal",
|
|
1079
|
+
"aura_get_withdrawal_limits",
|
|
1080
|
+
"aura_validate_withdrawal_address"
|
|
1081
|
+
];
|
|
1082
|
+
}
|
|
804
1083
|
|
|
805
1084
|
// src/index.ts
|
|
806
1085
|
var SERVER_NAME = "aura-payments";
|
|
807
|
-
var SERVER_VERSION = "1.
|
|
1086
|
+
var SERVER_VERSION = "1.2.0";
|
|
808
1087
|
var toolManifests = /* @__PURE__ */ new WeakMap();
|
|
809
1088
|
function getRegisteredToolNames(server) {
|
|
810
1089
|
return toolManifests.get(server) ?? [];
|
|
@@ -819,13 +1098,18 @@ function createServer(options = {}) {
|
|
|
819
1098
|
...registerAgentTools(server),
|
|
820
1099
|
...registerMandateTools(server),
|
|
821
1100
|
...registerWalletTools(server),
|
|
822
|
-
...registerWebhookTools(server)
|
|
1101
|
+
...registerWebhookTools(server),
|
|
1102
|
+
...registerWithdrawalTools(server),
|
|
1103
|
+
...registerTreasuryTools(server),
|
|
1104
|
+
...registerInsightsTools(server)
|
|
823
1105
|
];
|
|
824
1106
|
toolManifests.set(server, Object.freeze(toolNames));
|
|
825
1107
|
registerAgentResources(server);
|
|
826
1108
|
registerMandateResources(server);
|
|
827
1109
|
registerEscrowResources(server);
|
|
828
1110
|
registerWalletResources(server);
|
|
1111
|
+
registerWithdrawalResources(server);
|
|
1112
|
+
registerInsightsResources(server);
|
|
829
1113
|
return server;
|
|
830
1114
|
}
|
|
831
1115
|
|
package/dist/bin.mjs
CHANGED
|
@@ -132,6 +132,22 @@ function registerEscrowResources(server) {
|
|
|
132
132
|
}
|
|
133
133
|
);
|
|
134
134
|
}
|
|
135
|
+
|
|
136
|
+
// src/resources/insights.ts
|
|
137
|
+
function registerInsightsResources(server, clientFactory = getClient) {
|
|
138
|
+
server.resource("insights-overview", "aura://insights/overview", async (uri) => {
|
|
139
|
+
const overview = await clientFactory().insights.overview();
|
|
140
|
+
return {
|
|
141
|
+
contents: [
|
|
142
|
+
{
|
|
143
|
+
uri: uri.href,
|
|
144
|
+
mimeType: "application/json",
|
|
145
|
+
text: JSON.stringify(overview, null, 2)
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
}
|
|
135
151
|
function registerMandateResources(server) {
|
|
136
152
|
server.resource(
|
|
137
153
|
"mandates-pending",
|
|
@@ -218,6 +234,42 @@ function registerWalletResources(server) {
|
|
|
218
234
|
}
|
|
219
235
|
);
|
|
220
236
|
}
|
|
237
|
+
var COLLECTION_LIMIT3 = 50;
|
|
238
|
+
var WithdrawalIdSchema = z.string().uuid();
|
|
239
|
+
function registerWithdrawalResources(server, clientFactory = getClient) {
|
|
240
|
+
server.resource("withdrawals", "aura://withdrawals", async (uri) => {
|
|
241
|
+
const page = await clientFactory().withdrawals.list({ limit: COLLECTION_LIMIT3 });
|
|
242
|
+
return {
|
|
243
|
+
contents: [
|
|
244
|
+
{
|
|
245
|
+
uri: uri.href,
|
|
246
|
+
mimeType: "application/json",
|
|
247
|
+
text: JSON.stringify(page, null, 2)
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
server.resource(
|
|
253
|
+
"withdrawal",
|
|
254
|
+
new ResourceTemplate("aura://withdrawals/{id}", { list: void 0 }),
|
|
255
|
+
async (uri, { id }) => {
|
|
256
|
+
const parsed = WithdrawalIdSchema.safeParse(Array.isArray(id) ? id[0] : id);
|
|
257
|
+
if (!parsed.success) {
|
|
258
|
+
throw new Error(`Invalid withdrawal id in ${uri.href}: expected a UUID`);
|
|
259
|
+
}
|
|
260
|
+
const withdrawal = await clientFactory().withdrawals.get(parsed.data);
|
|
261
|
+
return {
|
|
262
|
+
contents: [
|
|
263
|
+
{
|
|
264
|
+
uri: uri.href,
|
|
265
|
+
mimeType: "application/json",
|
|
266
|
+
text: JSON.stringify(withdrawal, null, 2)
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
);
|
|
272
|
+
}
|
|
221
273
|
|
|
222
274
|
// src/annotations.ts
|
|
223
275
|
function readOnly(title) {
|
|
@@ -596,6 +648,118 @@ function registerEscrowTools(server) {
|
|
|
596
648
|
"aura_receive_and_split"
|
|
597
649
|
];
|
|
598
650
|
}
|
|
651
|
+
function validationError(error) {
|
|
652
|
+
const detail = error.issues.map((issue) => `${issue.path.join(".") || "(input)"}: ${issue.message}`).join("; ");
|
|
653
|
+
return toolError("VALIDATION_ERROR", detail);
|
|
654
|
+
}
|
|
655
|
+
function addCustomRangeIssues(ctx, field, selector, start, end) {
|
|
656
|
+
if (selector === "custom" && (start === void 0 || end === void 0)) {
|
|
657
|
+
ctx.addIssue({
|
|
658
|
+
code: z.ZodIssueCode.custom,
|
|
659
|
+
path: [start === void 0 ? "start" : "end"],
|
|
660
|
+
message: `start and end are both required when ${field} is 'custom'`
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
if (start !== void 0 && end !== void 0 && Date.parse(start) > Date.parse(end)) {
|
|
664
|
+
ctx.addIssue({
|
|
665
|
+
code: z.ZodIssueCode.custom,
|
|
666
|
+
path: ["end"],
|
|
667
|
+
message: "end must be at or after start"
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// src/tools/insights.ts
|
|
673
|
+
var PeriodSchema = z.enum(["today", "7d", "30d", "90d", "custom"]);
|
|
674
|
+
var DateTimeSchema = z.string().datetime();
|
|
675
|
+
var overviewShape = {
|
|
676
|
+
period: PeriodSchema.optional().describe(
|
|
677
|
+
"Window to report on (default 7d). 'custom' requires start and end."
|
|
678
|
+
),
|
|
679
|
+
start: DateTimeSchema.optional().describe("ISO 8601 datetime; required when period is custom"),
|
|
680
|
+
end: DateTimeSchema.optional().describe("ISO 8601 datetime; required when period is custom")
|
|
681
|
+
};
|
|
682
|
+
var InsightsOverviewInput = z.object(overviewShape).superRefine(
|
|
683
|
+
(value, ctx) => addCustomRangeIssues(ctx, "period", value.period, value.start, value.end)
|
|
684
|
+
);
|
|
685
|
+
var auditShape = {
|
|
686
|
+
action: z.string().min(1).optional().describe("Audit action name, e.g. escrow.released"),
|
|
687
|
+
actor: z.enum(["user", "system", "api", "cron", "webhook"]).optional(),
|
|
688
|
+
resourceType: z.string().min(1).optional().describe("Resource kind, e.g. escrow"),
|
|
689
|
+
// `.min(1)`, not `.uuid()`: the route accepts any string here
|
|
690
|
+
// (`resourceId: z.string().optional()`, insights/audit/route.ts:26) and the
|
|
691
|
+
// audit log records ids from several subsystems, not all of them UUIDs.
|
|
692
|
+
resourceId: z.string().min(1).optional().describe("Id of the audited resource"),
|
|
693
|
+
range: PeriodSchema.optional().describe(
|
|
694
|
+
"Window to query (default 30d). 'custom' requires start and end."
|
|
695
|
+
),
|
|
696
|
+
start: DateTimeSchema.optional().describe("ISO 8601 datetime; required when range is custom"),
|
|
697
|
+
end: DateTimeSchema.optional().describe("ISO 8601 datetime; required when range is custom"),
|
|
698
|
+
page: z.number().int().min(1).optional().describe("1-based page number (default 1)"),
|
|
699
|
+
limit: z.number().int().min(1).max(100).optional().describe("Page size, 1-100 (default 50)")
|
|
700
|
+
};
|
|
701
|
+
var InsightsAuditInput = z.object(auditShape).superRefine(
|
|
702
|
+
(value, ctx) => addCustomRangeIssues(ctx, "range", value.range, value.start, value.end)
|
|
703
|
+
);
|
|
704
|
+
function registerInsightsTools(server, clientFactory = getClient) {
|
|
705
|
+
server.tool(
|
|
706
|
+
"aura_insights_overview",
|
|
707
|
+
"Revenue, transaction count, active escrows and commissions for a period, each with its change against the previous period, plus sparkline and success-rate charts.",
|
|
708
|
+
overviewShape,
|
|
709
|
+
readOnly("Insights Overview"),
|
|
710
|
+
async (args) => {
|
|
711
|
+
const parsed = InsightsOverviewInput.safeParse(args);
|
|
712
|
+
if (!parsed.success) return validationError(parsed.error);
|
|
713
|
+
const { period, start, end } = parsed.data;
|
|
714
|
+
return withToolErrorHandling(
|
|
715
|
+
async () => clientFactory().insights.overview(period, start, end)
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
);
|
|
719
|
+
server.tool(
|
|
720
|
+
"aura_insights_forecast",
|
|
721
|
+
"Project a metric forward over a horizon using the requested algorithm. Requires a Growth or higher plan \u2014 lower tiers return feature_not_available.",
|
|
722
|
+
{
|
|
723
|
+
metric: z.enum([
|
|
724
|
+
"revenue",
|
|
725
|
+
"transaction_count",
|
|
726
|
+
"escrow_count",
|
|
727
|
+
"commission",
|
|
728
|
+
"avg_transaction_value"
|
|
729
|
+
]),
|
|
730
|
+
algorithm: z.enum([
|
|
731
|
+
"linear_regression",
|
|
732
|
+
"moving_average",
|
|
733
|
+
"exponential_smoothing",
|
|
734
|
+
"arima",
|
|
735
|
+
"prophet",
|
|
736
|
+
"ensemble"
|
|
737
|
+
]).optional(),
|
|
738
|
+
period: z.enum(["daily", "weekly", "monthly"]).optional().describe("Granularity of each projected point"),
|
|
739
|
+
horizon: z.number().int().min(1).max(365).optional().describe("Number of periods to project"),
|
|
740
|
+
// Known platform quirk: the route parses this with `z.coerce.boolean()`
|
|
741
|
+
// on a query string, where any non-empty value — including "false" —
|
|
742
|
+
// coerces to true. Passing false therefore does not currently suppress
|
|
743
|
+
// history; that is a platform-side fix, not one to paper over here.
|
|
744
|
+
includeHistory: z.boolean().optional().describe("Include the historical series alongside the projection"),
|
|
745
|
+
historyPeriods: z.number().int().min(1).max(365).optional()
|
|
746
|
+
},
|
|
747
|
+
readOnly("Insights Forecast"),
|
|
748
|
+
async (args) => withToolErrorHandling(async () => clientFactory().insights.forecast(args))
|
|
749
|
+
);
|
|
750
|
+
server.tool(
|
|
751
|
+
"aura_insights_audit",
|
|
752
|
+
"Query the account audit log by action, actor, resource and date range. Paginated, most recent first.",
|
|
753
|
+
auditShape,
|
|
754
|
+
readOnly("Insights Audit"),
|
|
755
|
+
async (args) => {
|
|
756
|
+
const parsed = InsightsAuditInput.safeParse(args);
|
|
757
|
+
if (!parsed.success) return validationError(parsed.error);
|
|
758
|
+
return withToolErrorHandling(async () => clientFactory().insights.audit(parsed.data));
|
|
759
|
+
}
|
|
760
|
+
);
|
|
761
|
+
return ["aura_insights_overview", "aura_insights_forecast", "aura_insights_audit"];
|
|
762
|
+
}
|
|
599
763
|
function registerMandateTools(server) {
|
|
600
764
|
server.tool(
|
|
601
765
|
"aura_list_mandates",
|
|
@@ -664,6 +828,18 @@ function registerMandateTools(server) {
|
|
|
664
828
|
"aura_reject_mandate"
|
|
665
829
|
];
|
|
666
830
|
}
|
|
831
|
+
|
|
832
|
+
// src/tools/treasury.ts
|
|
833
|
+
function registerTreasuryTools(server, clientFactory = getClient) {
|
|
834
|
+
server.tool(
|
|
835
|
+
"aura_treasury_optimize",
|
|
836
|
+
"Analyze treasury balances, active escrows and pending payouts, and return an AI recommendation on how to rebalance. Read-only: it recommends, it does not move funds. Requires a Growth or higher plan \u2014 lower tiers return feature_not_available.",
|
|
837
|
+
{},
|
|
838
|
+
readOnly("Treasury Optimize"),
|
|
839
|
+
async () => withToolErrorHandling(async () => clientFactory().treasury.optimize())
|
|
840
|
+
);
|
|
841
|
+
return ["aura_treasury_optimize"];
|
|
842
|
+
}
|
|
667
843
|
var TestnetChainSchema = z.enum(["ARC", "ARB", "BASE"]);
|
|
668
844
|
function walletCreateEnabled() {
|
|
669
845
|
const v = (process.env.AURA_MCP_ALLOW_WALLET_CREATE ?? "").trim().toLowerCase();
|
|
@@ -799,10 +975,113 @@ function registerWebhookTools(server) {
|
|
|
799
975
|
"aura_delete_webhook_config"
|
|
800
976
|
];
|
|
801
977
|
}
|
|
978
|
+
var ChainSchema3 = z.enum(["ARC", "ETH", "BASE", "ARB", "MATIC"]);
|
|
979
|
+
var AmountSchema = z.string().regex(
|
|
980
|
+
/^\d+(\.\d{1,6})?$/,
|
|
981
|
+
'Amount must be a number string with up to 6 decimal places, e.g. "100.00"'
|
|
982
|
+
);
|
|
983
|
+
var EvmAddressSchema = z.string().regex(
|
|
984
|
+
/^0x[a-fA-F0-9]{40}$/,
|
|
985
|
+
"Must be an EVM address: 0x followed by 40 hexadecimal characters"
|
|
986
|
+
);
|
|
987
|
+
var ExchangeSchema = z.enum(["binance", "coinbase", "kraken", "other"]);
|
|
988
|
+
var FeeConfigSchema = z.enum(["FREE", "GAS_ONLY", "STANDARD"]);
|
|
989
|
+
var StatusSchema = z.enum(["pending", "submitted", "confirmed", "failed", "cancelled"]);
|
|
990
|
+
var WithdrawalIdSchema2 = z.string().uuid("Withdrawal id must be a UUID");
|
|
991
|
+
var estimateShape = {
|
|
992
|
+
// `.min(1)`, not `.uuid()`: the route accepts any non-empty string here
|
|
993
|
+
// (`walletId: z.string().min(1)`, estimate/route.ts:56). Requiring a UUID
|
|
994
|
+
// would make this tool reject wallet ids the platform itself accepts.
|
|
995
|
+
walletId: z.string().min(1).describe("Source wallet id to debit"),
|
|
996
|
+
amount: AmountSchema.describe('USDC amount as a string, e.g. "100.00"'),
|
|
997
|
+
destinationType: z.enum(["exchange", "wallet"]).describe("Where the funds land. 'exchange' also requires `exchange`."),
|
|
998
|
+
destinationAddress: EvmAddressSchema.describe("Destination EVM address"),
|
|
999
|
+
chain: ChainSchema3.describe("Chain the funds are delivered on"),
|
|
1000
|
+
exchange: ExchangeSchema.optional().describe(
|
|
1001
|
+
"Required when destinationType is 'exchange'"
|
|
1002
|
+
),
|
|
1003
|
+
sourceChain: ChainSchema3.optional().describe(
|
|
1004
|
+
"Chain the funds start on. Differs from `chain` for a bridged withdrawal; defaults to ARC."
|
|
1005
|
+
),
|
|
1006
|
+
feeConfig: FeeConfigSchema.optional()
|
|
1007
|
+
};
|
|
1008
|
+
var EstimateWithdrawalInput = z.object(estimateShape).superRefine((value, ctx) => {
|
|
1009
|
+
if (value.destinationType === "exchange" && value.exchange === void 0) {
|
|
1010
|
+
ctx.addIssue({
|
|
1011
|
+
code: z.ZodIssueCode.custom,
|
|
1012
|
+
path: ["exchange"],
|
|
1013
|
+
message: "exchange is required when destinationType is 'exchange'"
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
function registerWithdrawalTools(server, clientFactory = getClient) {
|
|
1018
|
+
server.tool(
|
|
1019
|
+
"aura_get_withdrawal",
|
|
1020
|
+
"Get a single withdrawal by id: status, amount, fees, destination, chain and transaction hash.",
|
|
1021
|
+
{ withdrawalId: WithdrawalIdSchema2.describe("The withdrawal id (UUID)") },
|
|
1022
|
+
readOnly("Get Withdrawal"),
|
|
1023
|
+
async ({ withdrawalId }) => withToolErrorHandling(async () => clientFactory().withdrawals.get(withdrawalId))
|
|
1024
|
+
);
|
|
1025
|
+
server.tool(
|
|
1026
|
+
"aura_list_withdrawals",
|
|
1027
|
+
"List withdrawals for the account, most recent first. Filter by status, chain and date range.",
|
|
1028
|
+
{
|
|
1029
|
+
limit: z.number().int().min(1).max(100).optional().describe("Page size, 1-100 (default 50)"),
|
|
1030
|
+
offset: z.number().int().min(0).optional().describe("Rows to skip (default 0)"),
|
|
1031
|
+
status: StatusSchema.optional(),
|
|
1032
|
+
chain: ChainSchema3.optional(),
|
|
1033
|
+
fromDate: z.string().datetime().optional().describe("ISO 8601 datetime, inclusive lower bound"),
|
|
1034
|
+
toDate: z.string().datetime().optional().describe("ISO 8601 datetime, inclusive upper bound")
|
|
1035
|
+
},
|
|
1036
|
+
readOnly("List Withdrawals"),
|
|
1037
|
+
async (args) => withToolErrorHandling(async () => clientFactory().withdrawals.list(args))
|
|
1038
|
+
);
|
|
1039
|
+
server.tool(
|
|
1040
|
+
"aura_estimate_withdrawal",
|
|
1041
|
+
"Preview the fees, net amount and confirmation time for a withdrawal WITHOUT creating it. Moves no funds. Use this before quoting a payout to a user.",
|
|
1042
|
+
estimateShape,
|
|
1043
|
+
readOnly("Estimate Withdrawal"),
|
|
1044
|
+
async (args) => {
|
|
1045
|
+
const parsed = EstimateWithdrawalInput.safeParse(args);
|
|
1046
|
+
if (!parsed.success) return validationError(parsed.error);
|
|
1047
|
+
return withToolErrorHandling(
|
|
1048
|
+
async () => clientFactory().withdrawals.estimate(parsed.data)
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
);
|
|
1052
|
+
server.tool(
|
|
1053
|
+
"aura_get_withdrawal_limits",
|
|
1054
|
+
"Get the account KYC-tier withdrawal limits and how much of the daily and monthly allowance is still available.",
|
|
1055
|
+
{},
|
|
1056
|
+
readOnly("Get Withdrawal Limits"),
|
|
1057
|
+
async () => withToolErrorHandling(async () => clientFactory().withdrawals.limits())
|
|
1058
|
+
);
|
|
1059
|
+
server.tool(
|
|
1060
|
+
"aura_validate_withdrawal_address",
|
|
1061
|
+
"Check that a destination address is well-formed and usable on a chain, and preview the fee when an amount is given. Moves no funds.",
|
|
1062
|
+
{
|
|
1063
|
+
address: EvmAddressSchema.describe("Destination EVM address to check"),
|
|
1064
|
+
chain: ChainSchema3,
|
|
1065
|
+
amount: AmountSchema.optional().describe(
|
|
1066
|
+
"Optional \u2014 when supplied the response includes a fee preview"
|
|
1067
|
+
),
|
|
1068
|
+
feeConfig: FeeConfigSchema.optional()
|
|
1069
|
+
},
|
|
1070
|
+
readOnly("Validate Withdrawal Address"),
|
|
1071
|
+
async (args) => withToolErrorHandling(async () => clientFactory().withdrawals.validate(args))
|
|
1072
|
+
);
|
|
1073
|
+
return [
|
|
1074
|
+
"aura_get_withdrawal",
|
|
1075
|
+
"aura_list_withdrawals",
|
|
1076
|
+
"aura_estimate_withdrawal",
|
|
1077
|
+
"aura_get_withdrawal_limits",
|
|
1078
|
+
"aura_validate_withdrawal_address"
|
|
1079
|
+
];
|
|
1080
|
+
}
|
|
802
1081
|
|
|
803
1082
|
// src/index.ts
|
|
804
1083
|
var SERVER_NAME = "aura-payments";
|
|
805
|
-
var SERVER_VERSION = "1.
|
|
1084
|
+
var SERVER_VERSION = "1.2.0";
|
|
806
1085
|
var toolManifests = /* @__PURE__ */ new WeakMap();
|
|
807
1086
|
function getRegisteredToolNames(server) {
|
|
808
1087
|
return toolManifests.get(server) ?? [];
|
|
@@ -817,13 +1096,18 @@ function createServer(options = {}) {
|
|
|
817
1096
|
...registerAgentTools(server),
|
|
818
1097
|
...registerMandateTools(server),
|
|
819
1098
|
...registerWalletTools(server),
|
|
820
|
-
...registerWebhookTools(server)
|
|
1099
|
+
...registerWebhookTools(server),
|
|
1100
|
+
...registerWithdrawalTools(server),
|
|
1101
|
+
...registerTreasuryTools(server),
|
|
1102
|
+
...registerInsightsTools(server)
|
|
821
1103
|
];
|
|
822
1104
|
toolManifests.set(server, Object.freeze(toolNames));
|
|
823
1105
|
registerAgentResources(server);
|
|
824
1106
|
registerMandateResources(server);
|
|
825
1107
|
registerEscrowResources(server);
|
|
826
1108
|
registerWalletResources(server);
|
|
1109
|
+
registerWithdrawalResources(server);
|
|
1110
|
+
registerInsightsResources(server);
|
|
827
1111
|
return server;
|
|
828
1112
|
}
|
|
829
1113
|
|
package/dist/index.d.mts
CHANGED
|
@@ -96,7 +96,7 @@ declare function getClient(): AuraClient;
|
|
|
96
96
|
*/
|
|
97
97
|
|
|
98
98
|
declare const SERVER_NAME = "aura-payments";
|
|
99
|
-
declare const SERVER_VERSION = "1.
|
|
99
|
+
declare const SERVER_VERSION = "1.2.0";
|
|
100
100
|
interface CreateServerOptions {
|
|
101
101
|
name?: string;
|
|
102
102
|
version?: string;
|