paybot-mcp 0.2.1 → 0.3.1
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/LICENSE +189 -189
- package/README.md +193 -109
- package/dist/denial-guidance.d.ts +95 -0
- package/dist/denial-guidance.d.ts.map +1 -0
- package/dist/denial-guidance.js +122 -0
- package/dist/denial-guidance.js.map +1 -0
- package/dist/server.d.ts +9 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +397 -13
- package/dist/server.js.map +1 -1
- package/package.json +93 -87
package/README.md
CHANGED
|
@@ -1,109 +1,193 @@
|
|
|
1
|
-
# paybot-mcp
|
|
2
|
-
|
|
3
|
-
MCP server for [PayBot](https://paybotcore.com) — payment tools for AI agents via the Model Context Protocol.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install paybot-mcp paybot-sdk
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage with Claude Desktop
|
|
12
|
-
|
|
13
|
-
Add to `claude_desktop_config.json`:
|
|
14
|
-
|
|
15
|
-
```json
|
|
16
|
-
{
|
|
17
|
-
"mcpServers": {
|
|
18
|
-
"paybot": {
|
|
19
|
-
"command": "npx",
|
|
20
|
-
"args": ["paybot-mcp"],
|
|
21
|
-
"env": {
|
|
22
|
-
"PAYBOT_API_KEY": "pb_...",
|
|
23
|
-
"PAYBOT_FACILITATOR_URL": "https://
|
|
24
|
-
"PAYBOT_BOT_ID": "my-agent"
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Usage with Claude Code
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"mcpServers": {
|
|
36
|
-
"paybot": {
|
|
37
|
-
"command": "npx",
|
|
38
|
-
"args": ["paybot-mcp"],
|
|
39
|
-
"env": {
|
|
40
|
-
"PAYBOT_API_KEY": "pb_...",
|
|
41
|
-
"PAYBOT_BOT_ID": "my-agent"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Environment Variables
|
|
49
|
-
|
|
50
|
-
| Variable | Description | Default |
|
|
51
|
-
|----------|-------------|---------|
|
|
52
|
-
| `PAYBOT_API_KEY` | PayBot API key | (required) |
|
|
53
|
-
| `PAYBOT_FACILITATOR_URL` | Facilitator server URL | `
|
|
54
|
-
| `PAYBOT_BOT_ID` | Default bot identifier | `mcp-agent` |
|
|
55
|
-
| `PAYBOT_WALLET_KEY` | Wallet private key for real payments | (optional) |
|
|
56
|
-
|
|
57
|
-
## Available Tools
|
|
58
|
-
|
|
59
|
-
| Tool | Description |
|
|
60
|
-
|------|-------------|
|
|
61
|
-
| `paybot_pay` | Make a USDC
|
|
62
|
-
| `paybot_balance` | Check trust level, spending limits, and remaining budget |
|
|
63
|
-
| `paybot_history` | View recent payment history and audit events |
|
|
64
|
-
| `paybot_register` | Register a new bot with the facilitator |
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
1
|
+
# paybot-mcp
|
|
2
|
+
|
|
3
|
+
MCP server for [PayBot](https://paybotcore.com) — payment tools for AI agents via the Model Context Protocol.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install paybot-mcp paybot-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage with Claude Desktop
|
|
12
|
+
|
|
13
|
+
Add to `claude_desktop_config.json`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"mcpServers": {
|
|
18
|
+
"paybot": {
|
|
19
|
+
"command": "npx",
|
|
20
|
+
"args": ["paybot-mcp"],
|
|
21
|
+
"env": {
|
|
22
|
+
"PAYBOT_API_KEY": "pb_...",
|
|
23
|
+
"PAYBOT_FACILITATOR_URL": "https://api.paybotcore.com",
|
|
24
|
+
"PAYBOT_BOT_ID": "my-agent"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage with Claude Code
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"mcpServers": {
|
|
36
|
+
"paybot": {
|
|
37
|
+
"command": "npx",
|
|
38
|
+
"args": ["paybot-mcp"],
|
|
39
|
+
"env": {
|
|
40
|
+
"PAYBOT_API_KEY": "pb_...",
|
|
41
|
+
"PAYBOT_BOT_ID": "my-agent"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Environment Variables
|
|
49
|
+
|
|
50
|
+
| Variable | Description | Default |
|
|
51
|
+
|----------|-------------|---------|
|
|
52
|
+
| `PAYBOT_API_KEY` | PayBot API key | (required) |
|
|
53
|
+
| `PAYBOT_FACILITATOR_URL` | Facilitator server URL | `https://api.paybotcore.com` |
|
|
54
|
+
| `PAYBOT_BOT_ID` | Default bot identifier | `mcp-agent` |
|
|
55
|
+
| `PAYBOT_WALLET_KEY` | Wallet private key for real payments | (optional) |
|
|
56
|
+
|
|
57
|
+
## Available Tools
|
|
58
|
+
|
|
59
|
+
| Tool | Description |
|
|
60
|
+
|------|-------------|
|
|
61
|
+
| `paybot_pay` | Make a payment (USDC by default; supports alternate tokens + idempotency) |
|
|
62
|
+
| `paybot_balance` | Check trust level, spending limits, and remaining budget |
|
|
63
|
+
| `paybot_history` | View recent payment history and audit events |
|
|
64
|
+
| `paybot_register` | Register a new bot with the facilitator (optional idempotency key) |
|
|
65
|
+
| `paybot_list_networks_and_tokens` | Discover supported networks and tokens (offline, no API key) |
|
|
66
|
+
| `paybot_health_extended` | Extended facilitator health (status/version/uptime + extras) |
|
|
67
|
+
| `paybot_set_spending_limit` | Set per-transaction / daily / hourly limits and a recipient allowlist |
|
|
68
|
+
| `paybot_commission_inspect` | Inspect commission summary and a filterable ledger |
|
|
69
|
+
| `paybot_pool_create` | Create an in-process bot pool with an optional shared treasury |
|
|
70
|
+
| `paybot_pool_allocate` | Add a bot to a pool, optionally paying as it through the treasury |
|
|
71
|
+
| `paybot_pool_revoke` | Remove a bot from a pool |
|
|
72
|
+
| `paybot_pool_status` | Report pool treasury and per-bot spend counters |
|
|
73
|
+
|
|
74
|
+
### paybot_pay
|
|
75
|
+
|
|
76
|
+
| Param | Type | Notes |
|
|
77
|
+
|-------|------|-------|
|
|
78
|
+
| `amount` | string | Amount in USD (e.g., `"0.05"`) |
|
|
79
|
+
| `recipient` | string | Recipient wallet address (`0x...`) |
|
|
80
|
+
| `resource` | string | URL or description of what you're paying for |
|
|
81
|
+
| `botId?` | string | Bot identifier (defaults to env) |
|
|
82
|
+
| `network?` | string | Network CAIP-2 ID (default: Base Sepolia) |
|
|
83
|
+
| `token?` | string | Token ticker (default `USDC`); e.g. `USDC`, `EURC`, `DAI` |
|
|
84
|
+
| `idempotencyKey?` | string | Repeat call with the same key returns the cached result |
|
|
85
|
+
|
|
86
|
+
### paybot_balance
|
|
87
|
+
|
|
88
|
+
| Param | Type | Notes |
|
|
89
|
+
|-------|------|-------|
|
|
90
|
+
| `botId?` | string | Bot identifier (defaults to env) |
|
|
91
|
+
|
|
92
|
+
### paybot_history
|
|
93
|
+
|
|
94
|
+
| Param | Type | Notes |
|
|
95
|
+
|-------|------|-------|
|
|
96
|
+
| `botId?` | string | Bot identifier (defaults to env) |
|
|
97
|
+
| `limit?` | number | Max events to return (default: 10) |
|
|
98
|
+
|
|
99
|
+
### paybot_register
|
|
100
|
+
|
|
101
|
+
| Param | Type | Notes |
|
|
102
|
+
|-------|------|-------|
|
|
103
|
+
| `botId` | string | Unique bot identifier |
|
|
104
|
+
| `trustLevel?` | number | Initial trust level 0-5 (default: 1) |
|
|
105
|
+
| `idempotencyKey?` | string | Repeat register with the same key returns the cached result |
|
|
106
|
+
|
|
107
|
+
### paybot_list_networks_and_tokens
|
|
108
|
+
|
|
109
|
+
Read-only discovery. Requires no API key and makes zero network calls. Surfaces
|
|
110
|
+
only the **public** open-core registry — operator-private mainnet addresses are
|
|
111
|
+
never shown (e.g. EURC advertises its Base Sepolia testnet deployment only).
|
|
112
|
+
|
|
113
|
+
_No parameters._
|
|
114
|
+
|
|
115
|
+
### paybot_health_extended
|
|
116
|
+
|
|
117
|
+
| Param | Type | Notes |
|
|
118
|
+
|-------|------|-------|
|
|
119
|
+
| `botId?` | string | Bot identifier (defaults to env) |
|
|
120
|
+
|
|
121
|
+
Returns `status`, `version`, `uptime`, `timestamp`, plus any extra fields the
|
|
122
|
+
facilitator reports.
|
|
123
|
+
|
|
124
|
+
### paybot_set_spending_limit
|
|
125
|
+
|
|
126
|
+
Tightens an agent's own limits. The facilitator enforces the operator ceiling
|
|
127
|
+
and may reject attempts to loosen beyond policy.
|
|
128
|
+
|
|
129
|
+
| Param | Type | Notes |
|
|
130
|
+
|-------|------|-------|
|
|
131
|
+
| `botId?` | string | Bot identifier (defaults to env) |
|
|
132
|
+
| `maxTransactionUsd?` | number | Max USD per transaction |
|
|
133
|
+
| `maxDailySpendUsd?` | number | Max USD spend per day |
|
|
134
|
+
| `maxTransactionsPerHour?` | number | Max transactions per hour |
|
|
135
|
+
| `allowedRecipients?` | string[] | Allowlist of recipient addresses |
|
|
136
|
+
|
|
137
|
+
### paybot_commission_inspect
|
|
138
|
+
|
|
139
|
+
| Param | Type | Notes |
|
|
140
|
+
|-------|------|-------|
|
|
141
|
+
| `botId?` | string | Bot identifier (defaults to env) |
|
|
142
|
+
| `status?` | enum | Filter ledger by `pending` \| `forwarded` \| `deferred` |
|
|
143
|
+
| `startDate?` | string | Ledger start date (ISO 8601) |
|
|
144
|
+
| `endDate?` | string | Ledger end date (ISO 8601) |
|
|
145
|
+
| `limit?` | number | Max ledger entries (default: 50) |
|
|
146
|
+
| `offset?` | number | Ledger pagination offset |
|
|
147
|
+
|
|
148
|
+
### paybot_pool_create
|
|
149
|
+
|
|
150
|
+
Creates an in-process bot pool for this MCP session. Treasury accounting is
|
|
151
|
+
in-memory; the facilitator remains the authoritative limit.
|
|
152
|
+
|
|
153
|
+
| Param | Type | Notes |
|
|
154
|
+
|-------|------|-------|
|
|
155
|
+
| `poolId` | string | Identifier for this pool (used by allocate/revoke/status) |
|
|
156
|
+
| `sharedDailyLimitUsd?` | number | Optional shared daily spend cap across all bots |
|
|
157
|
+
|
|
158
|
+
### paybot_pool_allocate
|
|
159
|
+
|
|
160
|
+
| Param | Type | Notes |
|
|
161
|
+
|-------|------|-------|
|
|
162
|
+
| `poolId` | string | Pool identifier |
|
|
163
|
+
| `botId` | string | Bot identifier to add to the pool |
|
|
164
|
+
| `trustLevel?` | number | Initial trust level 0-5 |
|
|
165
|
+
| `pay?` | object | Optional `{ amount, recipient, resource, network?, token? }` to pay as this bot |
|
|
166
|
+
|
|
167
|
+
### paybot_pool_revoke
|
|
168
|
+
|
|
169
|
+
| Param | Type | Notes |
|
|
170
|
+
|-------|------|-------|
|
|
171
|
+
| `poolId` | string | Pool identifier |
|
|
172
|
+
| `botId` | string | Bot identifier to remove |
|
|
173
|
+
|
|
174
|
+
### paybot_pool_status
|
|
175
|
+
|
|
176
|
+
| Param | Type | Notes |
|
|
177
|
+
|-------|------|-------|
|
|
178
|
+
| `poolId` | string | Pool identifier |
|
|
179
|
+
|
|
180
|
+
## Programmatic Usage
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { createMcpServer } from 'paybot-mcp/server';
|
|
184
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
185
|
+
|
|
186
|
+
const server = createMcpServer();
|
|
187
|
+
const transport = new StdioServerTransport();
|
|
188
|
+
await server.connect(transport);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
[Apache 2.0](LICENSE)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module denial-guidance
|
|
3
|
+
*
|
|
4
|
+
* Plain-language operator guidance for PayBot policy denials.
|
|
5
|
+
*
|
|
6
|
+
* When `paybot_pay` (or any policy-gated tool) is denied by core, the SDK
|
|
7
|
+
* returns a machine `errorCode` (e.g. `DAILY_LIMIT_EXCEEDED`). On its own that
|
|
8
|
+
* code is actionable only to someone who already knows the policy model. This
|
|
9
|
+
* module maps each known policy code to a single plain-language sentence
|
|
10
|
+
* telling the agent (and the human reading its log) what to do about it — so a
|
|
11
|
+
* trust/limit/policy denial is actionable without opening core's logs.
|
|
12
|
+
*
|
|
13
|
+
* Scope: guidance is offered ONLY for codes that core treats as policy
|
|
14
|
+
* decisions (the SDK's {@link POLICY_ERROR_CODES} set). Non-policy failures
|
|
15
|
+
* (network, facilitator unreachable, signing) carry no guidance — fabricating
|
|
16
|
+
* a "what to do" line for an infrastructure error would be misleading.
|
|
17
|
+
*
|
|
18
|
+
* Dependencies: none at runtime. The policy code set mirrors the SDK's
|
|
19
|
+
* `POLICY_ERROR_CODES`; see {@link POLICY_ERROR_CODES} note below.
|
|
20
|
+
* Used by: src/server.ts (`paybot_pay` denial path).
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Codes core treats as policy decisions (trust / AML / limit / envelope).
|
|
24
|
+
*
|
|
25
|
+
* This mirrors paybot-sdk's internal `POLICY_ERROR_CODES`. The SDK defines the
|
|
26
|
+
* set in its `errors` module but does NOT re-export it from the package root
|
|
27
|
+
* (paybot-sdk@0.4.0 only re-exports the error classes such as
|
|
28
|
+
* `PayBotPolicyError`). Rather than reach into an un-exported submodule, the
|
|
29
|
+
* MCP keeps a local copy of this small, stable set — decoupling the tool from
|
|
30
|
+
* the SDK's internal module layout. Keep in sync if the SDK adds policy codes.
|
|
31
|
+
*/
|
|
32
|
+
export declare const POLICY_ERROR_CODES: ReadonlySet<string>;
|
|
33
|
+
/**
|
|
34
|
+
* One-line, no-hype action for each known policy code. Keys MUST be a subset of
|
|
35
|
+
* {@link POLICY_ERROR_CODES}; a code that is in the set but missing here falls
|
|
36
|
+
* back to {@link GENERIC_POLICY_GUIDANCE} (still actionable, never silent).
|
|
37
|
+
*
|
|
38
|
+
* Company voice: direct, technical, no marketing language, ≤1 sentence.
|
|
39
|
+
*/
|
|
40
|
+
export declare const POLICY_GUIDANCE: Readonly<Record<string, string>>;
|
|
41
|
+
/**
|
|
42
|
+
* Fallback guidance for a policy code that core flags but this map does not yet
|
|
43
|
+
* cover (e.g. a future SDK policy code). Keeps a denial actionable and never
|
|
44
|
+
* silently omits the code — it just cannot offer a code-specific next step.
|
|
45
|
+
*/
|
|
46
|
+
export declare const GENERIC_POLICY_GUIDANCE = "This payment was blocked by a spending policy; review the bot's limits and trust level with paybot_balance, then adjust with paybot_set_spending_limit.";
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the plain-language guidance line for a denial error code.
|
|
49
|
+
*
|
|
50
|
+
* Returns guidance ONLY for policy codes (members of the SDK's
|
|
51
|
+
* {@link POLICY_ERROR_CODES}). Known codes get their mapped sentence; a policy
|
|
52
|
+
* code with no explicit mapping gets {@link GENERIC_POLICY_GUIDANCE}. Any code
|
|
53
|
+
* that is not a policy code — and a missing/undefined code — returns `null`, so
|
|
54
|
+
* the caller surfaces the SDK's own error text without fabricating advice.
|
|
55
|
+
*
|
|
56
|
+
* @param errorCode - Machine code from the SDK `PaymentResult.errorCode`, or
|
|
57
|
+
* undefined when the SDK did not provide one.
|
|
58
|
+
* @returns A one-line guidance string for policy denials, otherwise `null`.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* policyGuidance('DAILY_LIMIT_EXCEEDED')
|
|
62
|
+
* // → 'Raise the per-day limit with paybot_set_spending_limit, ...'
|
|
63
|
+
* policyGuidance('NETWORK_ERROR')
|
|
64
|
+
* // → null (non-policy failure: no guidance)
|
|
65
|
+
*/
|
|
66
|
+
export declare function policyGuidance(errorCode: string | undefined): string | null;
|
|
67
|
+
/**
|
|
68
|
+
* Build the full denial response text for a failed `PaymentResult`.
|
|
69
|
+
*
|
|
70
|
+
* Surfaces the machine `errorCode` and the human `errorDetails` (when present)
|
|
71
|
+
* in addition to the SDK's `error` message, then appends a plain-language
|
|
72
|
+
* guidance line for policy denials. Mirrors the in-repo reference pattern in
|
|
73
|
+
* `paybot_pool_allocate`, which already surfaces `errorCode` on the flagship
|
|
74
|
+
* tool's behalf.
|
|
75
|
+
*
|
|
76
|
+
* Behaviour by case:
|
|
77
|
+
* - Policy denial with a known code → message + `Code:` + `Details:` (if any) + guidance.
|
|
78
|
+
* - Policy denial with an unmapped policy code → as above with generic guidance.
|
|
79
|
+
* - Non-policy failure with a real SDK code → message + `Code:` (+ details), NO guidance.
|
|
80
|
+
* - Non-policy failure with no code → message only (unchanged legacy text), NO invented code.
|
|
81
|
+
*
|
|
82
|
+
* @param result - The failed payment result (`success: false`). Only `error`,
|
|
83
|
+
* `errorCode`, and `errorDetails` are read.
|
|
84
|
+
* @returns The multi-line denial text for the MCP tool response.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* formatDenial({ error: 'Daily limit exceeded', errorCode: 'DAILY_LIMIT_EXCEEDED' })
|
|
88
|
+
* // → 'Payment failed: Daily limit exceeded\nCode: DAILY_LIMIT_EXCEEDED\nGuidance: Raise the per-day limit ...'
|
|
89
|
+
*/
|
|
90
|
+
export declare function formatDenial(result: {
|
|
91
|
+
error?: string;
|
|
92
|
+
errorCode?: string;
|
|
93
|
+
errorDetails?: Record<string, unknown>;
|
|
94
|
+
}): string;
|
|
95
|
+
//# sourceMappingURL=denial-guidance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"denial-guidance.d.ts","sourceRoot":"","sources":["../src/denial-guidance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAKjD,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS3D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,4JACwH,CAAC;AAE7J;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAQ3E;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,GAAG,MAAM,CAiBT"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module denial-guidance
|
|
3
|
+
*
|
|
4
|
+
* Plain-language operator guidance for PayBot policy denials.
|
|
5
|
+
*
|
|
6
|
+
* When `paybot_pay` (or any policy-gated tool) is denied by core, the SDK
|
|
7
|
+
* returns a machine `errorCode` (e.g. `DAILY_LIMIT_EXCEEDED`). On its own that
|
|
8
|
+
* code is actionable only to someone who already knows the policy model. This
|
|
9
|
+
* module maps each known policy code to a single plain-language sentence
|
|
10
|
+
* telling the agent (and the human reading its log) what to do about it — so a
|
|
11
|
+
* trust/limit/policy denial is actionable without opening core's logs.
|
|
12
|
+
*
|
|
13
|
+
* Scope: guidance is offered ONLY for codes that core treats as policy
|
|
14
|
+
* decisions (the SDK's {@link POLICY_ERROR_CODES} set). Non-policy failures
|
|
15
|
+
* (network, facilitator unreachable, signing) carry no guidance — fabricating
|
|
16
|
+
* a "what to do" line for an infrastructure error would be misleading.
|
|
17
|
+
*
|
|
18
|
+
* Dependencies: none at runtime. The policy code set mirrors the SDK's
|
|
19
|
+
* `POLICY_ERROR_CODES`; see {@link POLICY_ERROR_CODES} note below.
|
|
20
|
+
* Used by: src/server.ts (`paybot_pay` denial path).
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Codes core treats as policy decisions (trust / AML / limit / envelope).
|
|
24
|
+
*
|
|
25
|
+
* This mirrors paybot-sdk's internal `POLICY_ERROR_CODES`. The SDK defines the
|
|
26
|
+
* set in its `errors` module but does NOT re-export it from the package root
|
|
27
|
+
* (paybot-sdk@0.4.0 only re-exports the error classes such as
|
|
28
|
+
* `PayBotPolicyError`). Rather than reach into an un-exported submodule, the
|
|
29
|
+
* MCP keeps a local copy of this small, stable set — decoupling the tool from
|
|
30
|
+
* the SDK's internal module layout. Keep in sync if the SDK adds policy codes.
|
|
31
|
+
*/
|
|
32
|
+
export const POLICY_ERROR_CODES = new Set([
|
|
33
|
+
'TRUST_VIOLATION',
|
|
34
|
+
'AML_BLOCKED',
|
|
35
|
+
'DAILY_LIMIT_EXCEEDED',
|
|
36
|
+
'SPENDING_ENVELOPE',
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* One-line, no-hype action for each known policy code. Keys MUST be a subset of
|
|
40
|
+
* {@link POLICY_ERROR_CODES}; a code that is in the set but missing here falls
|
|
41
|
+
* back to {@link GENERIC_POLICY_GUIDANCE} (still actionable, never silent).
|
|
42
|
+
*
|
|
43
|
+
* Company voice: direct, technical, no marketing language, ≤1 sentence.
|
|
44
|
+
*/
|
|
45
|
+
export const POLICY_GUIDANCE = Object.freeze({
|
|
46
|
+
DAILY_LIMIT_EXCEEDED: 'Raise the per-day limit with paybot_set_spending_limit, or wait for the daily window to reset.',
|
|
47
|
+
TRUST_VIOLATION: 'This bot\'s trust level is too low for this payment; raise its trust level or route the payment through a higher-trust bot.',
|
|
48
|
+
AML_BLOCKED: 'The recipient or amount was flagged by AML screening; verify the recipient address and amount, and escalate to an operator if it is expected.',
|
|
49
|
+
SPENDING_ENVELOPE: 'The payment falls outside this bot\'s allowed spending envelope; widen the envelope with paybot_set_spending_limit or use an in-envelope recipient/amount.',
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Fallback guidance for a policy code that core flags but this map does not yet
|
|
53
|
+
* cover (e.g. a future SDK policy code). Keeps a denial actionable and never
|
|
54
|
+
* silently omits the code — it just cannot offer a code-specific next step.
|
|
55
|
+
*/
|
|
56
|
+
export const GENERIC_POLICY_GUIDANCE = 'This payment was blocked by a spending policy; review the bot\'s limits and trust level with paybot_balance, then adjust with paybot_set_spending_limit.';
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the plain-language guidance line for a denial error code.
|
|
59
|
+
*
|
|
60
|
+
* Returns guidance ONLY for policy codes (members of the SDK's
|
|
61
|
+
* {@link POLICY_ERROR_CODES}). Known codes get their mapped sentence; a policy
|
|
62
|
+
* code with no explicit mapping gets {@link GENERIC_POLICY_GUIDANCE}. Any code
|
|
63
|
+
* that is not a policy code — and a missing/undefined code — returns `null`, so
|
|
64
|
+
* the caller surfaces the SDK's own error text without fabricating advice.
|
|
65
|
+
*
|
|
66
|
+
* @param errorCode - Machine code from the SDK `PaymentResult.errorCode`, or
|
|
67
|
+
* undefined when the SDK did not provide one.
|
|
68
|
+
* @returns A one-line guidance string for policy denials, otherwise `null`.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* policyGuidance('DAILY_LIMIT_EXCEEDED')
|
|
72
|
+
* // → 'Raise the per-day limit with paybot_set_spending_limit, ...'
|
|
73
|
+
* policyGuidance('NETWORK_ERROR')
|
|
74
|
+
* // → null (non-policy failure: no guidance)
|
|
75
|
+
*/
|
|
76
|
+
export function policyGuidance(errorCode) {
|
|
77
|
+
if (!errorCode) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
if (!POLICY_ERROR_CODES.has(errorCode)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return POLICY_GUIDANCE[errorCode] ?? GENERIC_POLICY_GUIDANCE;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Build the full denial response text for a failed `PaymentResult`.
|
|
87
|
+
*
|
|
88
|
+
* Surfaces the machine `errorCode` and the human `errorDetails` (when present)
|
|
89
|
+
* in addition to the SDK's `error` message, then appends a plain-language
|
|
90
|
+
* guidance line for policy denials. Mirrors the in-repo reference pattern in
|
|
91
|
+
* `paybot_pool_allocate`, which already surfaces `errorCode` on the flagship
|
|
92
|
+
* tool's behalf.
|
|
93
|
+
*
|
|
94
|
+
* Behaviour by case:
|
|
95
|
+
* - Policy denial with a known code → message + `Code:` + `Details:` (if any) + guidance.
|
|
96
|
+
* - Policy denial with an unmapped policy code → as above with generic guidance.
|
|
97
|
+
* - Non-policy failure with a real SDK code → message + `Code:` (+ details), NO guidance.
|
|
98
|
+
* - Non-policy failure with no code → message only (unchanged legacy text), NO invented code.
|
|
99
|
+
*
|
|
100
|
+
* @param result - The failed payment result (`success: false`). Only `error`,
|
|
101
|
+
* `errorCode`, and `errorDetails` are read.
|
|
102
|
+
* @returns The multi-line denial text for the MCP tool response.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* formatDenial({ error: 'Daily limit exceeded', errorCode: 'DAILY_LIMIT_EXCEEDED' })
|
|
106
|
+
* // → 'Payment failed: Daily limit exceeded\nCode: DAILY_LIMIT_EXCEEDED\nGuidance: Raise the per-day limit ...'
|
|
107
|
+
*/
|
|
108
|
+
export function formatDenial(result) {
|
|
109
|
+
const lines = [`Payment failed: ${result.error ?? 'unknown error'}`];
|
|
110
|
+
if (result.errorCode) {
|
|
111
|
+
lines.push(`Code: ${result.errorCode}`);
|
|
112
|
+
}
|
|
113
|
+
if (result.errorDetails && Object.keys(result.errorDetails).length > 0) {
|
|
114
|
+
lines.push(`Details: ${JSON.stringify(result.errorDetails)}`);
|
|
115
|
+
}
|
|
116
|
+
const guidance = policyGuidance(result.errorCode);
|
|
117
|
+
if (guidance) {
|
|
118
|
+
lines.push(`Guidance: ${guidance}`);
|
|
119
|
+
}
|
|
120
|
+
return lines.join('\n');
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=denial-guidance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"denial-guidance.js","sourceRoot":"","sources":["../src/denial-guidance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IAC7D,iBAAiB;IACjB,aAAa;IACb,sBAAsB;IACtB,mBAAmB;CACpB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC,MAAM,CAAC,MAAM,CAAC;IAC7E,oBAAoB,EAClB,gGAAgG;IAClG,eAAe,EACb,6HAA6H;IAC/H,WAAW,EACT,+IAA+I;IACjJ,iBAAiB,EACf,4JAA4J;CAC/J,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAClC,0JAA0J,CAAC;AAE7J;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,cAAc,CAAC,SAA6B;IAC1D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,SAAS,CAAC,IAAI,uBAAuB,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,YAAY,CAAC,MAI5B;IACC,MAAM,KAAK,GAAa,CAAC,mBAAmB,MAAM,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;IAE/E,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvE,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -2,11 +2,17 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Create a PayBot MCP server exposing payment tools to AI agents.
|
|
4
4
|
*
|
|
5
|
-
* Tools:
|
|
6
|
-
* - paybot_pay — make a USDC
|
|
5
|
+
* Tools (v0.3.0):
|
|
6
|
+
* - paybot_pay — make a payment (USDC default; optional token + idempotencyKey)
|
|
7
7
|
* - paybot_balance — check spending limits and budget
|
|
8
8
|
* - paybot_history — view recent payment history
|
|
9
|
-
* - paybot_register — register a new bot
|
|
9
|
+
* - paybot_register — register a new bot (optional idempotencyKey)
|
|
10
|
+
* - paybot_list_networks_and_tokens — discover supported networks/tokens (offline, public registry only)
|
|
11
|
+
* - paybot_health_extended — facilitator health (status/version/uptime + extras)
|
|
12
|
+
* - paybot_set_spending_limit — tighten an agent's own spending limits
|
|
13
|
+
* - paybot_commission_inspect — commission summary + ledger
|
|
14
|
+
* - paybot_pool_create / paybot_pool_allocate / paybot_pool_revoke / paybot_pool_status —
|
|
15
|
+
* in-process multi-bot pool with a shared daily treasury
|
|
10
16
|
*/
|
|
11
17
|
export declare function createMcpServer(): McpServer;
|
|
12
18
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiDpE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,IAAI,SAAS,CAkjB3C"}
|