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