@rapay/mcp-server 1.1.4

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/README.md ADDED
@@ -0,0 +1,277 @@
1
+ # Ra Pay MCP Server
2
+
3
+ MCP (Model Context Protocol) server for AI agent payment automation. Enables Claude Desktop, Claude API, and ChatGPT to execute payments via Ra Pay CLI.
4
+
5
+ **Status:** Perplexity Security Review APPROVED (98% confidence)
6
+
7
+ ## Features
8
+
9
+ - 6 MVP tools for payment operations
10
+ - Subprocess isolation (credentials never leave keyring)
11
+ - Response sanitization (prevents prompt injection)
12
+ - Rate limiting (1 payment/min, 10 queries/min)
13
+ - Audit logging
14
+
15
+ ## Installation
16
+
17
+ ### Prerequisites
18
+
19
+ - Node.js 18+
20
+ - Ra Pay CLI installed and authenticated (`ra link-bank`)
21
+
22
+ ### Setup
23
+
24
+ ```bash
25
+ cd rapay/mcp-server
26
+ npm install
27
+ npm run build
28
+ ```
29
+
30
+ ### Claude Desktop Configuration
31
+
32
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
33
+
34
+ ```json
35
+ {
36
+ "mcpServers": {
37
+ "rapay": {
38
+ "command": "node",
39
+ "args": ["/Users/yourname/rapay/mcp-server/dist/index.js"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "rapay": {
51
+ "command": "node",
52
+ "args": ["C:\\Users\\yourname\\rapay\\mcp-server\\dist\\index.js"]
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ **With custom CLI path:**
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "rapay": {
64
+ "command": "node",
65
+ "args": ["/path/to/rapay/mcp-server/dist/index.js"],
66
+ "env": {
67
+ "RAPAY_CLI_PATH": "/custom/path/to/ra"
68
+ }
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ After adding, restart Claude Desktop. You should see "rapay" in the MCP servers list.
75
+
76
+ ## Tools
77
+
78
+ ### Payment Operations (SENSITIVE)
79
+
80
+ | Tool | Description |
81
+ |------|-------------|
82
+ | `ra_send` | Execute a payment transaction |
83
+ | `ra_subscribe` | Create a subscription for a customer |
84
+ | `ra_refund` | Open Stripe Dashboard for refunds |
85
+
86
+ ### Query Operations
87
+
88
+ | Tool | Description |
89
+ |------|-------------|
90
+ | `ra_balance` | Check available balance |
91
+ | `ra_history` | Get transaction history |
92
+ | `ra_whoami` | Check account status |
93
+
94
+ ## Security
95
+
96
+ ### Subprocess Isolation
97
+
98
+ MCP server spawns Ra Pay CLI as subprocess. Credentials remain in OS keyring - MCP server never sees them directly.
99
+
100
+ ### Response Sanitization
101
+
102
+ All CLI output is sanitized to prevent prompt injection:
103
+ - ANSI escape sequences removed
104
+ - System markers filtered (`[SYSTEM]`, `[USER]`, etc.)
105
+ - Control characters stripped
106
+
107
+ ### Rate Limiting
108
+
109
+ Defense-in-depth layer at MCP level:
110
+
111
+ | Tool | Limit |
112
+ |------|-------|
113
+ | `ra_send` | 1 per 60 seconds |
114
+ | `ra_subscribe` | 1 per 60 seconds |
115
+ | `ra_refund` | 5 per 60 seconds |
116
+ | `ra_balance` | 10 per 60 seconds |
117
+ | `ra_history` | 10 per 60 seconds |
118
+ | `ra_whoami` | 20 per 60 seconds |
119
+
120
+ Note: Backend also enforces velocity controls (account-tier daily limits).
121
+
122
+ ## Privacy & Data Storage
123
+
124
+ Ra Pay is designed as a "dumb pipe" to Stripe:
125
+
126
+ **What Ra Pay stores:**
127
+ - Your user ID
128
+ - Your Stripe account ID (encrypted)
129
+ - Action logs: "payment sent", "balance checked" (no amounts)
130
+ - Transaction audit trail with Stripe transfer IDs
131
+
132
+ **What Ra Pay does NOT store:**
133
+ - Your payment amounts
134
+ - Recipient details
135
+ - Payment descriptions
136
+ - Your account balance
137
+ - Any personally identifiable information (Stripe handles KYC)
138
+
139
+ **What MCP server adds:**
140
+ - Client type tracking ("called via Claude Desktop")
141
+ - Tool call audit logs (same privacy level as above)
142
+ - No new PII storage
143
+
144
+ ## Configuration
145
+
146
+ ### Environment Variables
147
+
148
+ | Variable | Description | Default |
149
+ |----------|-------------|---------|
150
+ | `RAPAY_CLI_PATH` | Path to Ra Pay CLI executable | `ra` |
151
+
152
+ ### Audit Logging
153
+
154
+ Logs are written to `~/.rapay/mcp-audit.log` with 7-day retention:
155
+ - Tool name, timestamp, duration
156
+ - Result (success/error/rate_limited)
157
+ - Sanitized inputs (amounts redacted, emails masked)
158
+
159
+ ## Error Handling
160
+
161
+ ### Error Codes
162
+
163
+ | Code | Description | Retryable |
164
+ |------|-------------|-----------|
165
+ | `RATE_LIMIT_EXCEEDED` | MCP rate limit hit | No (wait) |
166
+ | `CLI_NOT_FOUND` | Ra Pay CLI not installed | No |
167
+ | `TOS_ACCEPTANCE_REQUIRED` | ToS not accepted | No |
168
+ | `ACCOUNT_NOT_LINKED` | Stripe account not linked | No |
169
+ | `VELOCITY_EXCEEDED` | Daily limit exceeded | No |
170
+ | `TIMEOUT` | Request timed out | Yes |
171
+ | `NETWORK_ERROR` | Network connectivity issue | Yes |
172
+ | `EXECUTION_FAILED` | Generic CLI error | No |
173
+
174
+ ### Rate Limit Error
175
+
176
+ ```json
177
+ {
178
+ "error": "rate_limit_exceeded",
179
+ "code": "RATE_LIMIT_EXCEEDED",
180
+ "message": "Too many requests. Please wait 60 seconds.",
181
+ "retry_after_seconds": 60,
182
+ "retryable": false
183
+ }
184
+ ```
185
+
186
+ ### CLI Not Found Error
187
+
188
+ ```json
189
+ {
190
+ "error": "cli_not_found",
191
+ "code": "CLI_NOT_FOUND",
192
+ "message": "Ra Pay CLI not found. Please install it first.",
193
+ "retryable": false
194
+ }
195
+ ```
196
+
197
+ ### ToS Required Error
198
+
199
+ ```json
200
+ {
201
+ "error": "tos_required",
202
+ "code": "TOS_ACCEPTANCE_REQUIRED",
203
+ "message": "Terms of Service must be accepted. Run 'ra accept-tos' first.",
204
+ "retryable": false
205
+ }
206
+ ```
207
+
208
+ ### For Claude API Callers: Exponential Backoff
209
+
210
+ If you receive `RATE_LIMIT_EXCEEDED`, implement exponential backoff:
211
+
212
+ ```typescript
213
+ const maxRetries = 3;
214
+ let delay = 60; // seconds
215
+
216
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
217
+ try {
218
+ return await mcp.callTool('ra_send', params);
219
+ } catch (error) {
220
+ if (error.code === 'RATE_LIMIT_EXCEEDED') {
221
+ console.log(`Rate limited. Waiting ${delay}s before retry...`);
222
+ await sleep(delay * 1000);
223
+ delay *= 2; // exponential backoff
224
+ } else {
225
+ throw error;
226
+ }
227
+ }
228
+ }
229
+
230
+ // DO NOT:
231
+ // - Retry immediately (wastes time, still rate limited)
232
+ // - Retry more than 3 times (indicates genuine rate limit)
233
+ // - Ignore retry_after_seconds field
234
+ ```
235
+
236
+ Note: MCP rate limiting is client-side defense-in-depth. Backend also enforces velocity controls per account tier.
237
+
238
+ ## Data Flow
239
+
240
+ ```
241
+ You (Claude Desktop/API)
242
+ |
243
+ v
244
+ MCP Server (this package)
245
+ | - Logs tool calls (no amounts/PII)
246
+ | - Rate limits requests
247
+ | - Sanitizes responses
248
+ v
249
+ Ra Pay CLI (subprocess)
250
+ | - Credentials in OS keyring
251
+ | - Adds replay protection
252
+ v
253
+ Ra Pay Backend
254
+ | - Validates requests
255
+ | - Enforces velocity limits
256
+ v
257
+ Stripe API
258
+ | - Owns all PII
259
+ | - Processes payments
260
+ v
261
+ Recipient's Bank
262
+ ```
263
+
264
+ All sensitive data flows directly to Stripe. Ra Pay only records that an action occurred.
265
+
266
+ ## Development
267
+
268
+ ```bash
269
+ npm run dev # Watch mode
270
+ npm run build # Build
271
+ npm run lint # Lint
272
+ npm run test # Test
273
+ ```
274
+
275
+ ## License
276
+
277
+ MIT
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Ra Pay MCP Server - Audit Logging
3
+ *
4
+ * Local audit logging for MCP tool calls.
5
+ * Logs to ~/.rapay/mcp-audit.log (7-day retention per plan)
6
+ *
7
+ * @see MCP-SERVER-PLAN.md - Audit Logging Scope
8
+ */
9
+ /**
10
+ * Audit log entry structure (matches Perplexity-approved format)
11
+ */
12
+ export interface AuditLogEntry {
13
+ timestamp: string;
14
+ tool_name: string;
15
+ user_id: string;
16
+ inputs: Record<string, unknown>;
17
+ result: "success" | "error" | "rate_limited";
18
+ duration_ms: number;
19
+ client_type: string;
20
+ error_code?: string;
21
+ error_message?: string;
22
+ }
23
+ /**
24
+ * Write an audit log entry
25
+ *
26
+ * @param entry - Audit log entry to write
27
+ */
28
+ export declare function writeAuditLog(entry: AuditLogEntry): Promise<void>;
29
+ /**
30
+ * Create an audit log entry for a tool call
31
+ *
32
+ * @param toolName - Name of the tool called
33
+ * @param inputs - Tool input arguments (sanitized)
34
+ * @param startTime - Start time of the call
35
+ * @param result - Result of the call
36
+ * @param errorInfo - Optional error information
37
+ */
38
+ export declare function createAuditEntry(toolName: string, inputs: Record<string, unknown>, startTime: number, result: "success" | "error" | "rate_limited", errorInfo?: {
39
+ code?: string;
40
+ message?: string;
41
+ }): AuditLogEntry;
42
+ /**
43
+ * Clean up old audit logs (7-day retention)
44
+ * Call periodically to prevent unbounded log growth
45
+ */
46
+ export declare function cleanupOldLogs(): Promise<void>;
47
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,cAAc,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA+BD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,cAAc,EAC5C,SAAS,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,aAAa,CAsBf;AAuDD;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAepD"}
package/dist/audit.js ADDED
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Ra Pay MCP Server - Audit Logging
3
+ *
4
+ * Local audit logging for MCP tool calls.
5
+ * Logs to ~/.rapay/mcp-audit.log (7-day retention per plan)
6
+ *
7
+ * @see MCP-SERVER-PLAN.md - Audit Logging Scope
8
+ */
9
+ import { appendFile, mkdir, stat } from "fs/promises";
10
+ import { homedir } from "os";
11
+ import { join } from "path";
12
+ /**
13
+ * Get the audit log directory path
14
+ */
15
+ function getAuditLogDir() {
16
+ return join(homedir(), ".rapay");
17
+ }
18
+ /**
19
+ * Get the audit log file path
20
+ */
21
+ function getAuditLogPath() {
22
+ return join(getAuditLogDir(), "mcp-audit.log");
23
+ }
24
+ /**
25
+ * Ensure audit log directory exists
26
+ */
27
+ async function ensureAuditDir() {
28
+ const dir = getAuditLogDir();
29
+ try {
30
+ await mkdir(dir, { recursive: true });
31
+ }
32
+ catch (error) {
33
+ // Directory already exists, ignore
34
+ if (error.code !== "EEXIST") {
35
+ throw error;
36
+ }
37
+ }
38
+ }
39
+ /**
40
+ * Write an audit log entry
41
+ *
42
+ * @param entry - Audit log entry to write
43
+ */
44
+ export async function writeAuditLog(entry) {
45
+ try {
46
+ await ensureAuditDir();
47
+ // Format as JSON line (one entry per line)
48
+ const logLine = JSON.stringify(entry) + "\n";
49
+ await appendFile(getAuditLogPath(), logLine, { encoding: "utf-8" });
50
+ // Also log to stderr for debugging
51
+ console.error(`[AUDIT] ${entry.timestamp} tool=${entry.tool_name} result=${entry.result} duration=${entry.duration_ms}ms`);
52
+ }
53
+ catch (error) {
54
+ // Log error but don't fail the request
55
+ console.error("[AUDIT] Failed to write audit log:", error);
56
+ }
57
+ }
58
+ /**
59
+ * Create an audit log entry for a tool call
60
+ *
61
+ * @param toolName - Name of the tool called
62
+ * @param inputs - Tool input arguments (sanitized)
63
+ * @param startTime - Start time of the call
64
+ * @param result - Result of the call
65
+ * @param errorInfo - Optional error information
66
+ */
67
+ export function createAuditEntry(toolName, inputs, startTime, result, errorInfo) {
68
+ const endTime = Date.now();
69
+ // Sanitize inputs - remove sensitive data
70
+ const sanitizedInputs = sanitizeInputsForAudit(inputs);
71
+ const entry = {
72
+ timestamp: new Date().toISOString(),
73
+ tool_name: toolName,
74
+ user_id: "local", // MCP server doesn't have user context; CLI has it
75
+ inputs: sanitizedInputs,
76
+ result,
77
+ duration_ms: endTime - startTime,
78
+ client_type: "mcp-server",
79
+ };
80
+ if (errorInfo) {
81
+ entry.error_code = errorInfo.code;
82
+ entry.error_message = errorInfo.message;
83
+ }
84
+ return entry;
85
+ }
86
+ /**
87
+ * Sanitize inputs for audit logging
88
+ * Removes/masks sensitive data per privacy model
89
+ *
90
+ * @param inputs - Raw input arguments
91
+ * @returns Sanitized inputs safe for logging
92
+ */
93
+ function sanitizeInputsForAudit(inputs) {
94
+ const sanitized = {};
95
+ for (const [key, value] of Object.entries(inputs)) {
96
+ // Skip null/undefined
97
+ if (value == null)
98
+ continue;
99
+ // Mask email addresses
100
+ if (key === "customer_email" && typeof value === "string") {
101
+ sanitized[key] = maskEmail(value);
102
+ continue;
103
+ }
104
+ // Don't log amounts (privacy - dumb pipe model)
105
+ if (key === "amount") {
106
+ sanitized[key] = "[redacted]";
107
+ continue;
108
+ }
109
+ // Don't log business purpose details (privacy)
110
+ if (key === "business_purpose" && typeof value === "string") {
111
+ sanitized[key] = `[${value.length} chars]`;
112
+ continue;
113
+ }
114
+ // Log other fields as-is (recipient_id, price_id, limit, etc.)
115
+ sanitized[key] = value;
116
+ }
117
+ return sanitized;
118
+ }
119
+ /**
120
+ * Mask email address for logging
121
+ * john.doe@example.com -> j***@example.com
122
+ */
123
+ function maskEmail(email) {
124
+ const [local, domain] = email.split("@");
125
+ if (!domain)
126
+ return "[invalid-email]";
127
+ const maskedLocal = local.length > 0 ? local[0] + "***" : "***";
128
+ return `${maskedLocal}@${domain}`;
129
+ }
130
+ /**
131
+ * Clean up old audit logs (7-day retention)
132
+ * Call periodically to prevent unbounded log growth
133
+ */
134
+ export async function cleanupOldLogs() {
135
+ try {
136
+ const logPath = getAuditLogPath();
137
+ const stats = await stat(logPath);
138
+ const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
139
+ if (stats.mtimeMs < sevenDaysAgo) {
140
+ // Log file is older than 7 days
141
+ // In production, would rotate/archive; for MVP, just note it
142
+ console.error(`[AUDIT] Log file older than 7 days, consider rotation to ${logPath}.old`);
143
+ }
144
+ }
145
+ catch (error) {
146
+ // File doesn't exist or other error, ignore
147
+ }
148
+ }
149
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Ra Pay MCP Server - Tool Handlers
3
+ *
4
+ * Subprocess isolation layer: MCP spawns CLI, never sees credentials.
5
+ * Credentials stored in file with restricted permissions (~/.rapay/config.toml, mode 0600).
6
+ * Only CLI accesses them. Note: File storage used for Windows/MSYS2 compatibility (v1.3.0+).
7
+ *
8
+ * @see MCP-SERVER-PLAN.md - Security Requirements
9
+ */
10
+ /**
11
+ * Rate limit error response (matches Perplexity-approved format)
12
+ */
13
+ export interface RateLimitError {
14
+ error: "rate_limit_exceeded";
15
+ code: "RATE_LIMIT_EXCEEDED";
16
+ message: string;
17
+ retry_after_seconds: number;
18
+ retryable: false;
19
+ }
20
+ /**
21
+ * Tool argument types
22
+ */
23
+ export interface SendArgs {
24
+ amount: number;
25
+ recipient_id: string;
26
+ business_purpose: string;
27
+ user_confirmed?: boolean;
28
+ }
29
+ export interface SubscribeArgs {
30
+ price_id: string;
31
+ customer_email: string;
32
+ }
33
+ export interface HistoryArgs {
34
+ limit?: number;
35
+ }
36
+ export type ToolArgs = SendArgs | SubscribeArgs | HistoryArgs | Record<string, never>;
37
+ /**
38
+ * Execute a tool and return the result
39
+ *
40
+ * @param toolName - Name of the MCP tool to execute
41
+ * @param args - Tool arguments
42
+ * @returns Sanitized CLI output or error
43
+ */
44
+ export declare function handleToolCall(toolName: string, args: ToolArgs): Promise<string>;
45
+ //# sourceMappingURL=handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAqGH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,KAAK,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,aAAa,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AA+FtF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,MAAM,CAAC,CA+EjB"}