@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 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.1.0";
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.1.0";
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.1.0";
99
+ declare const SERVER_VERSION = "1.2.0";
100
100
  interface CreateServerOptions {
101
101
  name?: string;
102
102
  version?: string;