shabaaspay-mcp-server 1.0.5 → 1.0.7

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.
@@ -59,6 +59,39 @@ export declare class ShabaasApiClient {
59
59
  amount: string | number;
60
60
  description?: string;
61
61
  }, options?: RequestAuthOptions): Promise<ApiResponse>;
62
+ initiateDirectDebitPublic(data: {
63
+ amount: string | number;
64
+ name: string;
65
+ consent_received: boolean | string;
66
+ bsb: string | number;
67
+ account_number: string | number;
68
+ phone_number?: string;
69
+ notes?: string;
70
+ destination?: unknown;
71
+ }, options?: RequestAuthOptions): Promise<ApiResponse>;
72
+ updateBilateralAgreement(data: {
73
+ id?: string;
74
+ phone_number?: string;
75
+ maximum_amount: string | number;
76
+ frequency: string;
77
+ agreement_type?: string;
78
+ number_of_transactions_permitted: number;
79
+ }, options?: RequestAuthOptions): Promise<ApiResponse>;
80
+ generateInvoice(data: {
81
+ uuid: string;
82
+ phone_number?: string;
83
+ invoice: {
84
+ amount: string | number;
85
+ description: string;
86
+ bill_to: string;
87
+ address: string;
88
+ receiver_abn: string;
89
+ ref_no: string;
90
+ gst_included: boolean;
91
+ gst_does_not_apply?: boolean;
92
+ email?: string;
93
+ };
94
+ }, options?: RequestAuthOptions): Promise<ApiResponse>;
62
95
  getPaymentLink(data: {
63
96
  amount: string;
64
97
  reference?: string;
@@ -213,6 +213,49 @@ class ShabaasApiClient {
213
213
  return response.data;
214
214
  }, options?.requestUuid);
215
215
  }
216
+ async initiateDirectDebitPublic(data, options) {
217
+ return await this.withAuthRetry(async (token) => {
218
+ const amount = normalizeAmount(data.amount);
219
+ const response = await this.client.post('/api/public/payment_initiation/direct_debit', {
220
+ direct_debit: {
221
+ name: data.name,
222
+ amount,
223
+ consent_received: data.consent_received,
224
+ bsb: data.bsb,
225
+ account_number: data.account_number,
226
+ phone_number: data.phone_number,
227
+ notes: data.notes,
228
+ },
229
+ destination: data.destination,
230
+ }, {
231
+ headers: {
232
+ Authorization: token,
233
+ },
234
+ });
235
+ return response.data;
236
+ }, options?.requestUuid);
237
+ }
238
+ async updateBilateralAgreement(data, options) {
239
+ return await this.withAuthRetry(async (token) => {
240
+ const response = await this.client.patch('/api/public/payment_agreement/bilateral', {
241
+ payment_agreement: {
242
+ id: data.id,
243
+ phone_number: data.phone_number,
244
+ maximum_amount: data.maximum_amount,
245
+ frequency: data.frequency,
246
+ agreement_type: data.agreement_type,
247
+ number_of_transactions_permitted: data.number_of_transactions_permitted,
248
+ },
249
+ }, { headers: { Authorization: token } });
250
+ return response.data;
251
+ }, options?.requestUuid);
252
+ }
253
+ async generateInvoice(data, options) {
254
+ return await this.withAuthRetry(async (token) => {
255
+ const response = await this.client.post('/api/public/generate_invoice', data, { headers: { Authorization: token } });
256
+ return response.data;
257
+ }, options?.requestUuid);
258
+ }
216
259
  async getPaymentLink(data, options) {
217
260
  return await this.withAuthRetry(async (token) => {
218
261
  const response = await this.client.post('/api/get_url', data, {
@@ -274,6 +274,111 @@ async function listTools(env) {
274
274
  ],
275
275
  },
276
276
  },
277
+ {
278
+ name: 'initiate_direct_debit',
279
+ description: 'Initiate a direct debit payment with account details and consent.',
280
+ ...sharedExecution,
281
+ openapi_operation: { method: 'post', path: '/api/public/payment_initiation/direct_debit' },
282
+ output_openapi_schema_ref: '#/components/schemas/SuccessPaymentInitiationResponse',
283
+ required_arguments: ['name', 'amount', 'consent_received', 'bsb', 'account_number'],
284
+ optional_arguments: ['phone_number', 'notes', 'destination', 'include_raw'],
285
+ argument_hints: {
286
+ consent_received: 'Must be true / "true".',
287
+ },
288
+ argument_schema: {
289
+ name: { type: 'string' },
290
+ amount: { oneOf: [{ type: 'number', exclusiveMinimum: 0 }, { type: 'string', pattern: '^\\d+(\\.\\d{1,2})?$' }] },
291
+ consent_received: { oneOf: [{ type: 'boolean' }, { type: 'string', enum: ['true', 'false'] }] },
292
+ bsb: { oneOf: [{ type: 'string' }, { type: 'number' }] },
293
+ account_number: { oneOf: [{ type: 'string' }, { type: 'number' }] },
294
+ },
295
+ example: {
296
+ tool: 'initiate_direct_debit',
297
+ arguments: { name: 'John Citizen', amount: '10.00', consent_received: true, bsb: '062000', account_number: '12345678' },
298
+ },
299
+ decision_guidance: {
300
+ when_to_use: 'Use to create a direct debit payment initiation from account details.',
301
+ preconditions: ['name, amount, consent_received, bsb, account_number'],
302
+ retryable_errors: ['AUTH_MISSING_OR_INVALID'],
303
+ non_retryable_errors: ['INVALID_REQUEST', 'BUSINESS_RULE_FAILURE'],
304
+ next_best_tool_on_failure: 'get_payment_initiation',
305
+ },
306
+ idempotency_notes: 'Creates a new payment initiation and is non-idempotent without caller deduplication.',
307
+ error_contract: [
308
+ { status: 400, code: 'INVALID_REQUEST', when: 'Malformed direct_debit payload or missing required fields' },
309
+ { status: 401, code: 'AUTH_MISSING_OR_INVALID', when: 'Session/API key missing or invalid' },
310
+ { status: 422, code: 'BUSINESS_RULE_FAILURE', when: 'Consent/amount/cooldown or provider validation failed' },
311
+ ],
312
+ },
313
+ {
314
+ name: 'update_bilateral_agreement',
315
+ description: 'Update bilateral parameters for a payment agreement.',
316
+ ...sharedExecution,
317
+ openapi_operation: { method: 'patch', path: '/api/public/payment_agreement/bilateral' },
318
+ output_openapi_schema_ref: '#/components/schemas/SuccessPaymentAgreementResponse',
319
+ required_arguments: ['maximum_amount', 'frequency', 'number_of_transactions_permitted'],
320
+ optional_arguments: ['id', 'phone_number', 'agreement_type', 'include_raw'],
321
+ argument_hints: {
322
+ frequency: 'Use supported stored codes like ADHO, DAIL, FRTN, INDA, MIAN, MNTH, QURT, WEEK, YEAR.',
323
+ },
324
+ argument_schema: {
325
+ id: { type: 'string' },
326
+ phone_number: { type: 'string' },
327
+ maximum_amount: { oneOf: [{ type: 'string' }, { type: 'number' }] },
328
+ frequency: { type: 'string' },
329
+ number_of_transactions_permitted: { type: 'integer', minimum: 1 },
330
+ },
331
+ example: {
332
+ tool: 'update_bilateral_agreement',
333
+ arguments: { id: '2882PA20251227045450257', maximum_amount: '100.00', frequency: 'MNTH', number_of_transactions_permitted: 2 },
334
+ },
335
+ decision_guidance: {
336
+ when_to_use: 'Use to amend bilateral parameters on an existing payment agreement.',
337
+ preconditions: ['id or phone_number, maximum_amount, frequency, number_of_transactions_permitted'],
338
+ retryable_errors: ['AUTH_MISSING_OR_INVALID'],
339
+ non_retryable_errors: ['RESOURCE_NOT_FOUND', 'VALIDATION_OR_BUSINESS_RULE'],
340
+ next_best_tool_on_failure: 'get_payment_agreement',
341
+ },
342
+ idempotency_notes: 'Updates agreement settings and is non-idempotent under concurrent updates.',
343
+ error_contract: [
344
+ { status: 400, code: 'INVALID_REQUEST', when: 'Malformed bilateral amend payload' },
345
+ { status: 401, code: 'AUTH_MISSING_OR_INVALID', when: 'Session/API key missing or invalid' },
346
+ { status: 404, code: 'RESOURCE_NOT_FOUND', when: 'Payment agreement not found' },
347
+ { status: 422, code: 'VALIDATION_OR_BUSINESS_RULE', when: 'Amount/rule validation failed' },
348
+ ],
349
+ },
350
+ {
351
+ name: 'generate_invoice',
352
+ description: 'Generate checkout URL for invoice flow.',
353
+ ...sharedExecution,
354
+ openapi_operation: { method: 'post', path: '/api/public/generate_invoice' },
355
+ output_openapi_schema_ref: 'inline: { message, data: { checkout_url } }',
356
+ required_arguments: ['uuid', 'invoice'],
357
+ optional_arguments: ['phone_number', 'include_raw'],
358
+ argument_hints: {
359
+ uuid: 'Merchant checkout username.',
360
+ },
361
+ example: {
362
+ tool: 'generate_invoice',
363
+ arguments: {
364
+ uuid: 'merchant_slug_or_secret',
365
+ invoice: { amount: '50.00', description: 'Invoice 1001', bill_to: 'Customer', address: 'Address', receiver_abn: 'ABN', ref_no: '1001', gst_included: true },
366
+ },
367
+ },
368
+ decision_guidance: {
369
+ when_to_use: 'Use to generate invoice checkout URL for external collection flow.',
370
+ preconditions: ['uuid and invoice payload'],
371
+ retryable_errors: ['AUTH_MISSING_OR_INVALID'],
372
+ non_retryable_errors: ['INVALID_REQUEST', 'VALIDATION_OR_BUSINESS_RULE'],
373
+ next_best_tool_on_failure: null,
374
+ },
375
+ idempotency_notes: 'Creates a new invoice checkout URL/session per call; treat as non-idempotent.',
376
+ error_contract: [
377
+ { status: 400, code: 'INVALID_REQUEST', when: 'Invalid uuid or invoice payload shape' },
378
+ { status: 401, code: 'AUTH_MISSING_OR_INVALID', when: 'Session/API key missing or invalid' },
379
+ { status: 422, code: 'VALIDATION_OR_BUSINESS_RULE', when: 'Invoice validation/business rule failure' },
380
+ ],
381
+ },
277
382
  ];
278
383
  if (!prod) {
279
384
  toolsList.push({
@@ -49,24 +49,39 @@ function buildAllowedToolsList(policy, env) {
49
49
  const allTools = [
50
50
  {
51
51
  name: 'get_payment_agreement',
52
- description: `Retrieve payment agreement details with AI insights.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
52
+ description: 'Retrieve payment agreement details with AI insights.',
53
53
  inputSchema: httpMcpToolSchema(index_js_2.GetPaymentAgreementInputSchema),
54
54
  },
55
55
  {
56
56
  name: 'create_payment_agreement',
57
- description: `Create a new payment agreement.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
57
+ description: 'Create a new payment agreement.',
58
58
  inputSchema: httpMcpToolSchema(index_js_2.CreatePaymentAgreementInputSchema),
59
59
  },
60
60
  {
61
61
  name: 'initiate_payment',
62
- description: `Initiate a payment against an agreement.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
62
+ description: 'Initiate a payment against an agreement.',
63
63
  inputSchema: httpMcpToolSchema(index_js_2.InitiatePaymentInputSchema),
64
64
  },
65
65
  {
66
66
  name: 'get_payment_initiation',
67
- description: `Retrieve payment initiation by ID.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
67
+ description: 'Retrieve payment initiation by ID.',
68
68
  inputSchema: httpMcpToolSchema(index_js_2.GetPaymentInitiationInputSchema),
69
69
  },
70
+ {
71
+ name: 'initiate_direct_debit',
72
+ description: 'Initiate direct debit using account details and consent.',
73
+ inputSchema: httpMcpToolSchema(index_js_2.InitiateDirectDebitInputSchema),
74
+ },
75
+ {
76
+ name: 'update_bilateral_agreement',
77
+ description: 'Update bilateral configuration of a payment agreement.',
78
+ inputSchema: httpMcpToolSchema(index_js_2.UpdateBilateralAgreementInputSchema),
79
+ },
80
+ {
81
+ name: 'generate_invoice',
82
+ description: 'Generate invoice checkout URL for external invoice flow.',
83
+ inputSchema: httpMcpToolSchema(index_js_2.GenerateInvoiceInputSchema),
84
+ },
70
85
  ...(env.SHABAAS_ENVIRONMENT === 'production'
71
86
  ? []
72
87
  : [{
@@ -3,6 +3,4 @@
3
3
  * Remote HTTP clients authenticate via the connection (OAuth / Authorization header);
4
4
  * omitting `authorization` from published inputSchema avoids agents prompting users for keys.
5
5
  */
6
- /** Appended to tool descriptions for streamable HTTP ListTools so agents do not prompt for API keys. */
7
- export declare const HTTP_MCP_SESSION_AUTH_HINT = " Remote MCP (HTTP): session is authenticated via OAuth or Authorization header\u2014do not ask the user for an API key.";
8
6
  export declare function stripAuthorizationFieldFromJsonSchema(schema: unknown): unknown;
@@ -5,10 +5,7 @@
5
5
  * omitting `authorization` from published inputSchema avoids agents prompting users for keys.
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.HTTP_MCP_SESSION_AUTH_HINT = void 0;
9
8
  exports.stripAuthorizationFieldFromJsonSchema = stripAuthorizationFieldFromJsonSchema;
10
- /** Appended to tool descriptions for streamable HTTP ListTools so agents do not prompt for API keys. */
11
- exports.HTTP_MCP_SESSION_AUTH_HINT = ' Remote MCP (HTTP): session is authenticated via OAuth or Authorization header—do not ask the user for an API key.';
12
9
  function stripAuthorizationFieldFromJsonSchema(schema) {
13
10
  if (!schema || typeof schema !== 'object')
14
11
  return schema;
@@ -32,7 +32,7 @@ function buildServerCard(env) {
32
32
  const tools = [
33
33
  {
34
34
  name: 'get_payment_agreement',
35
- description: `Retrieve payment agreement details with AI insights.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
35
+ description: 'Retrieve payment agreement details with AI insights.',
36
36
  inputSchema: toStrictObjectSchema((0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(index_js_1.GetPaymentAgreementInputSchema))),
37
37
  metadata: {
38
38
  schemaVersion: '2026-04-15',
@@ -50,7 +50,7 @@ function buildServerCard(env) {
50
50
  },
51
51
  {
52
52
  name: 'create_payment_agreement',
53
- description: `Create a new payment agreement.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
53
+ description: 'Create a new payment agreement.',
54
54
  inputSchema: withCreatePaymentAgreementConditionals(toStrictObjectSchema((0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(index_js_1.CreatePaymentAgreementInputSchema)))),
55
55
  metadata: {
56
56
  schemaVersion: '2026-04-15',
@@ -69,7 +69,7 @@ function buildServerCard(env) {
69
69
  },
70
70
  {
71
71
  name: 'initiate_payment',
72
- description: `Initiate a payment against an agreement.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
72
+ description: 'Initiate a payment against an agreement.',
73
73
  inputSchema: toStrictObjectSchema((0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(index_js_1.InitiatePaymentInputSchema))),
74
74
  metadata: {
75
75
  schemaVersion: '2026-04-15',
@@ -88,7 +88,7 @@ function buildServerCard(env) {
88
88
  },
89
89
  {
90
90
  name: 'get_payment_initiation',
91
- description: `Retrieve payment initiation by ID.${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
91
+ description: 'Retrieve payment initiation by ID.',
92
92
  inputSchema: toStrictObjectSchema((0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(index_js_1.GetPaymentInitiationInputSchema))),
93
93
  metadata: {
94
94
  schemaVersion: '2026-04-15',
@@ -104,12 +104,51 @@ function buildServerCard(env) {
104
104
  },
105
105
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
106
106
  },
107
+ {
108
+ name: 'initiate_direct_debit',
109
+ description: 'Initiate direct debit using account details and explicit consent.',
110
+ inputSchema: toStrictObjectSchema((0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(index_js_1.InitiateDirectDebitInputSchema))),
111
+ metadata: {
112
+ schemaVersion: '2026-04-15',
113
+ requiredArguments: ['name', 'amount', 'consent_received', 'bsb', 'account_number'],
114
+ optionalArguments: ['phone_number', 'notes', 'destination', 'include_raw'],
115
+ openapiOperation: { method: 'post', path: '/api/public/payment_initiation/direct_debit' },
116
+ outputSchemaRef: '#/components/schemas/SuccessPaymentInitiationResponse',
117
+ },
118
+ annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
119
+ },
120
+ {
121
+ name: 'update_bilateral_agreement',
122
+ description: 'Update bilateral terms for an existing payment agreement.',
123
+ inputSchema: toStrictObjectSchema((0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(index_js_1.UpdateBilateralAgreementInputSchema))),
124
+ metadata: {
125
+ schemaVersion: '2026-04-15',
126
+ requiredArguments: ['maximum_amount', 'frequency', 'number_of_transactions_permitted'],
127
+ optionalArguments: ['id', 'phone_number', 'agreement_type', 'include_raw'],
128
+ openapiOperation: { method: 'patch', path: '/api/public/payment_agreement/bilateral' },
129
+ outputSchemaRef: '#/components/schemas/SuccessPaymentAgreementResponse',
130
+ },
131
+ annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
132
+ },
133
+ {
134
+ name: 'generate_invoice',
135
+ description: 'Generate external invoice checkout URL.',
136
+ inputSchema: toStrictObjectSchema((0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(index_js_1.GenerateInvoiceInputSchema))),
137
+ metadata: {
138
+ schemaVersion: '2026-04-15',
139
+ requiredArguments: ['uuid', 'invoice'],
140
+ optionalArguments: ['phone_number', 'include_raw'],
141
+ openapiOperation: { method: 'post', path: '/api/public/generate_invoice' },
142
+ outputSchemaRef: 'inline: { message, data: { checkout_url } }',
143
+ },
144
+ annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
145
+ },
107
146
  ];
108
147
  const isProduction = env.SHABAAS_ENVIRONMENT === 'production';
109
148
  if (!isProduction) {
110
149
  tools.push({
111
150
  name: 'get_auth_token',
112
- description: `Get ShaBaas API authorization token (non-production helper).${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
151
+ description: 'Get ShaBaas API authorization token (non-production helper).',
113
152
  inputSchema: {
114
153
  type: 'object',
115
154
  additionalProperties: false,
@@ -170,6 +209,37 @@ function buildServerCard(env) {
170
209
  { name: 'payment_initiation_id', description: 'Optional initiation ID', required: false },
171
210
  ],
172
211
  },
212
+ {
213
+ name: 'initiate_direct_debit',
214
+ description: 'Draft direct debit parameters, then call initiate_direct_debit with validated account and consent fields.',
215
+ arguments: [
216
+ { name: 'name', description: 'Account holder name', required: true },
217
+ { name: 'amount', description: 'Debit amount (e.g. 10.00)', required: true },
218
+ { name: 'consent_received', description: 'Must be true', required: true },
219
+ { name: 'bsb', description: 'Payer BSB', required: true },
220
+ { name: 'account_number', description: 'Payer account number', required: true },
221
+ ],
222
+ },
223
+ {
224
+ name: 'update_bilateral_agreement',
225
+ description: 'Prepare bilateral amendment fields and call update_bilateral_agreement for an existing payment agreement.',
226
+ arguments: [
227
+ { name: 'id', description: 'Payment agreement id (or use phone_number)', required: false },
228
+ { name: 'phone_number', description: 'Alternative payer lookup', required: false },
229
+ { name: 'maximum_amount', description: 'Updated maximum amount', required: true },
230
+ { name: 'frequency', description: 'Frequency code (e.g. WEEK, MNTH)', required: true },
231
+ { name: 'number_of_transactions_permitted', description: 'Allowed transaction count', required: true },
232
+ ],
233
+ },
234
+ {
235
+ name: 'generate_invoice',
236
+ description: 'Draft invoice payload and call generate_invoice to get an external checkout URL.',
237
+ arguments: [
238
+ { name: 'uuid', description: 'Merchant checkout username or secret', required: true },
239
+ { name: 'invoice', description: 'Invoice object with amount and description', required: true },
240
+ { name: 'phone_number', description: 'Optional customer phone', required: false },
241
+ ],
242
+ },
173
243
  ],
174
244
  metadata: {
175
245
  schemaVersion: '2026-04-15',
@@ -15,3 +15,6 @@ export declare function createPaymentAgreement(args: any, baseUrl: string, env:
15
15
  export declare function initiatePayment(args: any, baseUrl: string, env: Env, bearer: string, requestId: string): Promise<Response>;
16
16
  /** get_payment_initiation: GET initiation status by ID */
17
17
  export declare function getPaymentInitiation(args: any, baseUrl: string, env: Env, bearer: string): Promise<Response>;
18
+ export declare function initiateDirectDebit(args: any, baseUrl: string, env: Env, bearer: string, requestId: string): Promise<Response>;
19
+ export declare function updateBilateralAgreement(args: any, baseUrl: string, env: Env, bearer: string): Promise<Response>;
20
+ export declare function generateInvoice(args: any, baseUrl: string, env: Env, bearer: string): Promise<Response>;
@@ -11,6 +11,9 @@ exports.getPaymentAgreement = getPaymentAgreement;
11
11
  exports.createPaymentAgreement = createPaymentAgreement;
12
12
  exports.initiatePayment = initiatePayment;
13
13
  exports.getPaymentInitiation = getPaymentInitiation;
14
+ exports.initiateDirectDebit = initiateDirectDebit;
15
+ exports.updateBilateralAgreement = updateBilateralAgreement;
16
+ exports.generateInvoice = generateInvoice;
14
17
  const shabaas_api_client_js_1 = require("../shabaas-api-client.js");
15
18
  const utils_js_1 = require("../utils.js");
16
19
  const index_js_1 = require("../../enricher/index.js");
@@ -304,3 +307,134 @@ async function getPaymentInitiation(args, baseUrl, env, bearer) {
304
307
  return (0, utils_js_1.jsonResponse)({ success: false, error: 'Not found', message: 'Payment initiation not found.' }, 404, env);
305
308
  }
306
309
  }
310
+ async function initiateDirectDebit(args, baseUrl, env, bearer, requestId) {
311
+ const amountNum = Number(args.amount);
312
+ if (!Number.isFinite(amountNum) || amountNum <= 0) {
313
+ return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({ error: 'Invalid amount', message: 'Amount must be greater than zero' }, 400, env), requestId);
314
+ }
315
+ if (!args.name || !args.bsb || !args.account_number) {
316
+ return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({ error: 'Invalid request', message: 'name, bsb, and account_number are required' }, 400, env), requestId);
317
+ }
318
+ const consent = args.consent_received === true || String(args.consent_received).toLowerCase() === 'true';
319
+ if (!consent) {
320
+ return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({ error: 'Invalid request', message: 'consent_received must be true' }, 400, env), requestId);
321
+ }
322
+ try {
323
+ const startTime = Date.now();
324
+ const includeRaw = args.include_raw === true;
325
+ const response = await fetch(`${baseUrl}/api/public/payment_initiation/direct_debit`, {
326
+ method: 'POST',
327
+ headers: { 'Authorization': bearer, 'Content-Type': 'application/json', 'X-Shabaas-Client': 'mcp' },
328
+ body: JSON.stringify({
329
+ direct_debit: {
330
+ name: args.name,
331
+ amount: amountNum,
332
+ consent_received: true,
333
+ bsb: args.bsb,
334
+ account_number: args.account_number,
335
+ phone_number: args.phone_number,
336
+ notes: args.notes,
337
+ },
338
+ destination: args.destination,
339
+ }),
340
+ });
341
+ const data = await response.json();
342
+ if (!response.ok) {
343
+ return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({ success: false, error: data.error_code || 'Request failed', message: data.message || 'Failed to initiate direct debit', data: data.data }, response.status, env), requestId);
344
+ }
345
+ return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({
346
+ success: true,
347
+ timestamp: new Date().toISOString(),
348
+ data: data.data,
349
+ metadata: {
350
+ requestId: `req_${Date.now()}`,
351
+ processingTime: Date.now() - startTime,
352
+ environment: env.SHABAAS_ENVIRONMENT === 'production' ? 'production' : 'sandbox',
353
+ },
354
+ insights: { status: data.data?.status || 'submitted', canProceed: true, nextActions: ['get_payment_initiation'] },
355
+ summary: 'Direct debit request submitted successfully.',
356
+ ...(includeRaw ? { raw: data } : {}),
357
+ }, response.status, env), requestId);
358
+ }
359
+ catch (error) {
360
+ return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({ error: 'Request failed', message: error.message || 'An error occurred' }, 500, env), requestId);
361
+ }
362
+ }
363
+ async function updateBilateralAgreement(args, baseUrl, env, bearer) {
364
+ if (!args.id && !args.phone_number) {
365
+ return (0, utils_js_1.jsonResponse)({ error: 'Invalid request', message: 'Either id or phone_number is required' }, 400, env);
366
+ }
367
+ try {
368
+ const startTime = Date.now();
369
+ const includeRaw = args.include_raw === true;
370
+ const response = await fetch(`${baseUrl}/api/public/payment_agreement/bilateral`, {
371
+ method: 'PATCH',
372
+ headers: { 'Authorization': bearer, 'Content-Type': 'application/json', 'X-Shabaas-Client': 'mcp' },
373
+ body: JSON.stringify({
374
+ payment_agreement: {
375
+ id: args.id,
376
+ phone_number: args.phone_number,
377
+ maximum_amount: args.maximum_amount,
378
+ frequency: args.frequency,
379
+ agreement_type: args.agreement_type,
380
+ number_of_transactions_permitted: args.number_of_transactions_permitted,
381
+ },
382
+ }),
383
+ });
384
+ const data = await response.json();
385
+ if (!response.ok) {
386
+ return (0, utils_js_1.jsonResponse)({ success: false, error: data.error_code || 'Request failed', message: data.message || 'Failed to update bilateral agreement', data: data.data }, response.status, env);
387
+ }
388
+ return (0, utils_js_1.jsonResponse)({
389
+ success: true,
390
+ timestamp: new Date().toISOString(),
391
+ data: data.data,
392
+ metadata: {
393
+ requestId: `req_${Date.now()}`,
394
+ processingTime: Date.now() - startTime,
395
+ environment: env.SHABAAS_ENVIRONMENT === 'production' ? 'production' : 'sandbox',
396
+ },
397
+ insights: { status: 'updated', canProceed: true, nextActions: ['get_payment_agreement'] },
398
+ summary: 'Bilateral agreement update submitted successfully.',
399
+ ...(includeRaw ? { raw: data } : {}),
400
+ }, response.status, env);
401
+ }
402
+ catch (error) {
403
+ return (0, utils_js_1.jsonResponse)({ error: 'Request failed', message: error.message || 'An error occurred' }, 500, env);
404
+ }
405
+ }
406
+ async function generateInvoice(args, baseUrl, env, bearer) {
407
+ try {
408
+ const startTime = Date.now();
409
+ const includeRaw = args.include_raw === true;
410
+ const response = await fetch(`${baseUrl}/api/public/generate_invoice`, {
411
+ method: 'POST',
412
+ headers: { 'Authorization': bearer, 'Content-Type': 'application/json', 'X-Shabaas-Client': 'mcp' },
413
+ body: JSON.stringify({
414
+ uuid: args.uuid,
415
+ phone_number: args.phone_number,
416
+ invoice: args.invoice,
417
+ }),
418
+ });
419
+ const data = await response.json();
420
+ if (!response.ok) {
421
+ return (0, utils_js_1.jsonResponse)({ success: false, error: data.error_code || 'Request failed', message: data.message || 'Failed to generate invoice', data: data.data }, response.status, env);
422
+ }
423
+ return (0, utils_js_1.jsonResponse)({
424
+ success: true,
425
+ timestamp: new Date().toISOString(),
426
+ data: data.data,
427
+ metadata: {
428
+ requestId: `req_${Date.now()}`,
429
+ processingTime: Date.now() - startTime,
430
+ environment: env.SHABAAS_ENVIRONMENT === 'production' ? 'production' : 'sandbox',
431
+ },
432
+ insights: { status: 'created', canProceed: true, nextActions: ['generate_invoice'] },
433
+ summary: 'Invoice checkout URL generated successfully.',
434
+ ...(includeRaw ? { raw: data } : {}),
435
+ }, response.status, env);
436
+ }
437
+ catch (error) {
438
+ return (0, utils_js_1.jsonResponse)({ error: 'Request failed', message: error.message || 'An error occurred' }, 500, env);
439
+ }
440
+ }
@@ -24,7 +24,13 @@ const AUTH_REQUIRED_HTTP_MESSAGE = 'No API key on this MCP session. For remote H
24
24
  const AUTH_REQUIRED_INVALID_KEY_MESSAGE = 'API key was rejected or could not be exchanged for a session token. For HTTP MCP, fix the Authorization header or OAuth token; for stdio, pass a valid "authorization" in tool arguments.';
25
25
  /** True if tool performs a write (create, initiate) - needs extra validation */
26
26
  function isWriteTool(toolName) {
27
- return toolName === 'create_payment_agreement' || toolName === 'initiate_payment';
27
+ return [
28
+ 'create_payment_agreement',
29
+ 'initiate_payment',
30
+ 'initiate_direct_debit',
31
+ 'update_bilateral_agreement',
32
+ 'generate_invoice',
33
+ ].includes(toolName);
28
34
  }
29
35
  /** Validate write tool args (e.g. amount > 0 for initiate_payment) */
30
36
  function validateWriteConstraints(toolName, args, env, requestId) {
@@ -36,6 +42,12 @@ function validateWriteConstraints(toolName, args, env, requestId) {
36
42
  return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({ error: 'Invalid amount', message: 'Amount must be greater than zero' }, 400, env), requestId);
37
43
  }
38
44
  }
45
+ if (toolName === 'initiate_direct_debit') {
46
+ const amountNum = Number(args?.amount);
47
+ if (!Number.isFinite(amountNum) || amountNum <= 0) {
48
+ return (0, utils_js_1.withRequestId)((0, utils_js_1.jsonResponse)({ error: 'Invalid amount', message: 'Amount must be greater than zero' }, 400, env), requestId);
49
+ }
50
+ }
39
51
  return undefined;
40
52
  }
41
53
  /**
@@ -112,6 +124,15 @@ async function runToolInvocation(toolName, args, env, policy, authToken, request
112
124
  case 'get_payment_initiation':
113
125
  resp = await (0, implementations_js_1.getPaymentInitiation)(args, baseUrl, env, bearer);
114
126
  break;
127
+ case 'initiate_direct_debit':
128
+ resp = await (0, implementations_js_1.initiateDirectDebit)(args, baseUrl, env, bearer, requestId);
129
+ break;
130
+ case 'update_bilateral_agreement':
131
+ resp = await (0, implementations_js_1.updateBilateralAgreement)(args, baseUrl, env, bearer);
132
+ break;
133
+ case 'generate_invoice':
134
+ resp = await (0, implementations_js_1.generateInvoice)(args, baseUrl, env, bearer);
135
+ break;
115
136
  default:
116
137
  return {
117
138
  status: 404,
@@ -474,7 +474,7 @@ class HttpMcpServer {
474
474
  this.mcpServer.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
475
475
  const toolsList = Object.values(this.tools).map(tool => ({
476
476
  name: tool.name,
477
- description: `${tool.description ?? ''}${schema_helpers_js_1.HTTP_MCP_SESSION_AUTH_HINT}`,
477
+ description: tool.description ?? '',
478
478
  inputSchema: (0, schema_helpers_js_1.stripAuthorizationFieldFromJsonSchema)((0, zod_to_json_schema_1.zodToJsonSchema)(tool.inputSchema)),
479
479
  }));
480
480
  console.log(`[HTTP][MCP] Listing ${toolsList.length} tools`);
@@ -0,0 +1,16 @@
1
+ import { ShabaasApiClient } from '../api/client.js';
2
+ import { Config } from '../config/index.js';
3
+ export declare function createCapabilityPromptTools(_apiClient: ShabaasApiClient, config: Config): {
4
+ get_capability_prompts: {
5
+ name: string;
6
+ description: string;
7
+ inputSchema: import("zod").ZodObject<{
8
+ capability: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodEnum<["all", "direct_debit", "bilateral_api", "invoice_generation", "collections_api"]>>>;
9
+ }, "strip", import("zod").ZodTypeAny, {
10
+ capability: "all" | "direct_debit" | "bilateral_api" | "invoice_generation" | "collections_api";
11
+ }, {
12
+ capability?: "all" | "direct_debit" | "bilateral_api" | "invoice_generation" | "collections_api" | undefined;
13
+ }>;
14
+ execute: (args: unknown) => Promise<import("../types/index.js").StandardResponse<unknown>>;
15
+ };
16
+ };