@fuul/mcp-server 1.0.1 → 1.1.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/README.md
CHANGED
|
@@ -1,231 +1,628 @@
|
|
|
1
1
|
# @fuul/mcp-server
|
|
2
2
|
|
|
3
|
-
Fuul [Model Context Protocol](https://modelcontextprotocol.io/) server
|
|
3
|
+
Fuul [Model Context Protocol](https://modelcontextprotocol.io/) server for managing affiliate programs, analytics, incentives, and payouts through MCP-compatible clients (Claude Code, Cursor, Claude Desktop).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@fuul/mcp-server)
|
|
6
|
+
[](https://nodejs.org/)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
| [docs/AGENTS.md](docs/AGENTS.md) | Tool ↔ HTTP map (audit, support, PR review) |
|
|
11
|
-
| [docs/mcp-phase2/CONSUMER.md](docs/mcp-phase2/CONSUMER.md) | Staging/production URLs, API expectations |
|
|
12
|
-
| [docs/mcp-phase2/tool-prompts.md](docs/mcp-phase2/tool-prompts.md) | Sample prompts for tooling and evals |
|
|
13
|
-
| [CHANGELOG.md](CHANGELOG.md) | Release notes |
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
- [Quick Start](#quick-start)
|
|
13
|
+
- [Installation Methods](#installation-methods)
|
|
14
|
+
- [Claude Code Plugin (Recommended)](#1-claude-code-plugin-recommended)
|
|
15
|
+
- [Cursor IDE](#2-cursor-ide)
|
|
16
|
+
- [npx (Any MCP Client)](#3-npx-any-mcp-client)
|
|
17
|
+
- [Local Development (Clone)](#4-local-development-clone)
|
|
18
|
+
- [Authentication](#authentication)
|
|
19
|
+
- [Configuration](#configuration)
|
|
20
|
+
- [MCP Tool Reference](#mcp-tool-reference)
|
|
21
|
+
- [Troubleshooting](#troubleshooting)
|
|
22
|
+
- [Repository Layout](#repository-layout)
|
|
23
|
+
- [Scripts Reference](#scripts-reference)
|
|
24
|
+
- [Documentation](#documentation)
|
|
25
|
+
- [CI and Releases](#ci-and-releases)
|
|
26
|
+
- [License](#license)
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
---
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
## Quick Start
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
```bash
|
|
33
|
+
# 1. Install (choose one method below)
|
|
34
|
+
# 2. Authenticate once:
|
|
35
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp login
|
|
36
|
+
|
|
37
|
+
# 3. Verify:
|
|
38
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Installation Methods
|
|
44
|
+
|
|
45
|
+
### 1. Claude Code Plugin (Recommended)
|
|
46
|
+
|
|
47
|
+
The easiest way to use Fuul MCP with Claude Code. Adds the MCP server plus a **skill** that documents how to use Fuul tools.
|
|
48
|
+
|
|
49
|
+
#### Step 1: Install the plugin
|
|
22
50
|
|
|
23
51
|
```text
|
|
24
52
|
/plugin marketplace add kuyen-labs/mcp_server
|
|
25
53
|
/plugin install fuul-mcp@fuul-mcp
|
|
26
54
|
```
|
|
27
55
|
|
|
28
|
-
|
|
56
|
+
#### Step 2: Verify the `.mcp.json` format
|
|
57
|
+
|
|
58
|
+
Check the plugin's `.mcp.json` at:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
~/.claude/plugins/cache/fuul-mcp/fuul-mcp/<version>/.mcp.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
It must use the `--package=` format in `args`:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"mcpServers": {
|
|
69
|
+
"fuul": {
|
|
70
|
+
"command": "npx",
|
|
71
|
+
"args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"],
|
|
72
|
+
"env": {
|
|
73
|
+
"FUUL_API_BASE_URL": "${user_config.FUUL_API_BASE_URL}"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
If `args` shows `["-y", "@fuul/mcp-server@latest", "fuul-mcp-server"]` (without `--package=`), update it to match the format above.
|
|
81
|
+
|
|
82
|
+
#### Step 3: Reload the plugin
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
/reload-plugins
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Step 4: Authenticate (one-time)
|
|
89
|
+
|
|
90
|
+
Open a terminal and run:
|
|
29
91
|
|
|
30
92
|
```bash
|
|
31
|
-
npx -y
|
|
32
|
-
npx -y @fuul/mcp-server@latest fuul-mcp whoami
|
|
93
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp login
|
|
33
94
|
```
|
|
34
95
|
|
|
35
|
-
|
|
96
|
+
This opens your browser for OAuth. Tokens are saved to `~/.fuul/tokens.json`.
|
|
97
|
+
|
|
98
|
+
#### Step 5: Verify
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Optional: Use staging environment
|
|
105
|
+
|
|
106
|
+
Set `FUUL_API_BASE_URL` in the plugin's user settings:
|
|
107
|
+
|
|
108
|
+
| Environment | URL |
|
|
109
|
+
|-------------|-----|
|
|
110
|
+
| Production (default) | `https://api.fuul.xyz` |
|
|
111
|
+
| Staging | `https://api.stg.fuul.xyz` |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### 2. Cursor IDE
|
|
116
|
+
|
|
117
|
+
#### Option A: Using npx (no clone required)
|
|
118
|
+
|
|
119
|
+
1. **Authenticate first:**
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp login
|
|
123
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
2. **Configure MCP in Cursor:**
|
|
127
|
+
|
|
128
|
+
Go to **Settings → MCP** or edit your `mcp.json`:
|
|
36
129
|
|
|
37
|
-
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"mcpServers": {
|
|
133
|
+
"fuul": {
|
|
134
|
+
"command": "npx",
|
|
135
|
+
"args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"],
|
|
136
|
+
"env": {
|
|
137
|
+
"FUUL_API_BASE_URL": "https://api.fuul.xyz"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
38
143
|
|
|
39
|
-
|
|
144
|
+
#### Option B: Using local clone
|
|
40
145
|
|
|
41
|
-
|
|
146
|
+
1. **Clone and build:**
|
|
42
147
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
148
|
+
```bash
|
|
149
|
+
git clone https://github.com/kuyen-labs/mcp_server.git
|
|
150
|
+
cd mcp_server
|
|
151
|
+
npm ci
|
|
152
|
+
npm run build
|
|
153
|
+
```
|
|
48
154
|
|
|
49
|
-
|
|
155
|
+
2. **Authenticate:**
|
|
50
156
|
|
|
51
|
-
|
|
157
|
+
```bash
|
|
158
|
+
npm run cli -- login
|
|
159
|
+
npm run cli -- whoami
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
3. **Configure MCP in Cursor:**
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"mcpServers": {
|
|
167
|
+
"fuul": {
|
|
168
|
+
"command": "node",
|
|
169
|
+
"args": ["C:\\path\\to\\mcp_server\\dist\\index.js"],
|
|
170
|
+
"cwd": "C:\\path\\to\\mcp_server"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
On macOS/Linux:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"mcpServers": {
|
|
181
|
+
"fuul": {
|
|
182
|
+
"command": "node",
|
|
183
|
+
"args": ["/path/to/mcp_server/dist/index.js"],
|
|
184
|
+
"cwd": "/path/to/mcp_server"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### 3. npx (Any MCP Client)
|
|
193
|
+
|
|
194
|
+
Use the published npm package without cloning:
|
|
195
|
+
|
|
196
|
+
| Command | Purpose |
|
|
197
|
+
|---------|---------|
|
|
198
|
+
| `npx -y --package=@fuul/mcp-server@latest fuul-mcp login` | Browser OAuth; writes `~/.fuul/tokens.json` |
|
|
199
|
+
| `npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami` | Verify session (`GET /api/v1/auth/user`) |
|
|
200
|
+
| `npx -y --package=@fuul/mcp-server@latest fuul-mcp logout` | Clear tokens |
|
|
201
|
+
| `npx -y --package=@fuul/mcp-server@latest fuul-mcp-server` | Start stdio MCP server |
|
|
202
|
+
|
|
203
|
+
For MCP client configs (JSON), use the `--package=` format:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"command": "npx",
|
|
208
|
+
"args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"]
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### 4. Local Development (Clone)
|
|
52
215
|
|
|
53
216
|
```bash
|
|
54
217
|
git clone https://github.com/kuyen-labs/mcp_server.git
|
|
55
218
|
cd mcp_server
|
|
56
219
|
npm ci
|
|
57
|
-
cp .env.example .env #
|
|
220
|
+
cp .env.example .env # Optional: edit for staging/custom settings
|
|
58
221
|
npm run build
|
|
59
222
|
```
|
|
60
223
|
|
|
61
|
-
Run
|
|
224
|
+
#### Run CLI commands:
|
|
62
225
|
|
|
63
226
|
```bash
|
|
64
227
|
npm run cli -- login
|
|
65
228
|
npm run cli -- whoami
|
|
229
|
+
npm run cli -- logout
|
|
66
230
|
```
|
|
67
231
|
|
|
68
|
-
Run
|
|
232
|
+
#### Run MCP server:
|
|
69
233
|
|
|
70
234
|
```bash
|
|
71
|
-
npm start
|
|
72
|
-
#
|
|
235
|
+
npm start # Production (uses dist/)
|
|
236
|
+
npm run dev # Development (uses tsx, watches src/)
|
|
73
237
|
```
|
|
74
238
|
|
|
75
|
-
|
|
239
|
+
#### Debug with MCP Inspector:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
npm run build
|
|
243
|
+
npx @modelcontextprotocol/inspector node dist/index.js
|
|
244
|
+
```
|
|
76
245
|
|
|
77
|
-
|
|
246
|
+
---
|
|
78
247
|
|
|
79
|
-
|
|
80
|
-
| -------- | ------- |
|
|
81
|
-
| `FUUL_API_BASE_URL` | API origin only, no trailing slash. Production: `https://api.fuul.xyz`. Staging: `https://api.stg.fuul.xyz`. |
|
|
82
|
-
| `FUUL_OAUTH_CLIENT_ID` | OAuth client id (default `fuul-agent`). |
|
|
83
|
-
| `FUUL_OAUTH_REDIRECT_URI` | Loopback callback (default `http://127.0.0.1:8765/callback`). |
|
|
84
|
-
| `FUUL_MCP_TOOL_TIMEOUT_MS` | Per-tool timeout in ms (default `90000`). |
|
|
85
|
-
| `FUUL_MCP_DEBUG` | Set to `1` or `true` for debug logging. |
|
|
248
|
+
## Authentication
|
|
86
249
|
|
|
87
|
-
|
|
250
|
+
Authentication uses OAuth with the Fuul dashboard. Tokens are stored locally and shared by the CLI and MCP server.
|
|
88
251
|
|
|
89
|
-
|
|
252
|
+
### Token location
|
|
90
253
|
|
|
91
|
-
|
|
254
|
+
| OS | Path |
|
|
255
|
+
|----|------|
|
|
256
|
+
| macOS/Linux | `~/.fuul/tokens.json` |
|
|
257
|
+
| Windows | `%USERPROFILE%\.fuul\tokens.json` |
|
|
92
258
|
|
|
93
|
-
|
|
259
|
+
### Login flow
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp login
|
|
263
|
+
```
|
|
94
264
|
|
|
95
|
-
|
|
96
|
-
- `whoami` → `{}` (requires login)
|
|
265
|
+
This opens your default browser to the Fuul OAuth page. After authorizing, tokens are saved automatically.
|
|
97
266
|
|
|
98
|
-
|
|
267
|
+
### Verify session
|
|
99
268
|
|
|
100
|
-
|
|
269
|
+
```bash
|
|
270
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami
|
|
271
|
+
```
|
|
101
272
|
|
|
102
|
-
|
|
273
|
+
### Clear tokens
|
|
103
274
|
|
|
104
|
-
|
|
105
|
-
-
|
|
106
|
-
|
|
275
|
+
```bash
|
|
276
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp logout
|
|
277
|
+
```
|
|
107
278
|
|
|
108
|
-
|
|
279
|
+
---
|
|
109
280
|
|
|
110
|
-
|
|
111
|
-
- `get_project_affiliate_total_stats` → `project_id`, optional `dateRange`, filters
|
|
112
|
-
- `get_project_affiliates_breakdown` → `project_id`, **`groupBy`** (`audience` \| `tier` \| `region` \| `status`)
|
|
281
|
+
## Configuration
|
|
113
282
|
|
|
114
|
-
|
|
283
|
+
Environment variables are read from `process.env` and, when present, a `.env` file in the current working directory.
|
|
115
284
|
|
|
116
|
-
|
|
285
|
+
| Variable | Default | Description |
|
|
286
|
+
|----------|---------|-------------|
|
|
287
|
+
| `FUUL_API_BASE_URL` | `https://api.fuul.xyz` | API origin (no trailing slash). Use `https://api.stg.fuul.xyz` for staging. |
|
|
288
|
+
| `FUUL_OAUTH_CLIENT_ID` | `fuul-agent` | OAuth client ID |
|
|
289
|
+
| `FUUL_OAUTH_REDIRECT_URI` | `http://127.0.0.1:8765/callback` | OAuth callback URL |
|
|
290
|
+
| `FUUL_MCP_TOOL_TIMEOUT_MS` | `90000` | Per-tool timeout in milliseconds |
|
|
291
|
+
| `FUUL_MCP_DEBUG` | `false` | Set to `1` or `true` for debug logging |
|
|
117
292
|
|
|
118
|
-
|
|
293
|
+
### Example `.env` file
|
|
119
294
|
|
|
120
295
|
```bash
|
|
121
|
-
|
|
296
|
+
FUUL_API_BASE_URL=https://api.stg.fuul.xyz
|
|
297
|
+
FUUL_MCP_DEBUG=1
|
|
122
298
|
```
|
|
123
299
|
|
|
124
|
-
|
|
300
|
+
> **Note:** The `.env` file is for local development only and is not included in the npm package. Tokens are stored in `~/.fuul/tokens.json`, not in `.env`.
|
|
125
301
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## MCP Tool Reference
|
|
305
|
+
|
|
306
|
+
### Tool Categories
|
|
307
|
+
|
|
308
|
+
| Category | Tools |
|
|
309
|
+
|----------|-------|
|
|
310
|
+
| **Health** | `ping`, `whoami` |
|
|
311
|
+
| **Metadata** (cached) | `list_chains`, `list_trigger_types`, `list_payout_schemas` |
|
|
312
|
+
| **Projects** | `list_projects`, `get_project` |
|
|
313
|
+
| **Incentives** | `list_incentives`, `get_incentive`, `get_trigger` |
|
|
314
|
+
| **Affiliate Analytics** | `get_affiliate_portal_stats`, `get_project_affiliate_total_stats`, `get_project_affiliates_breakdown` |
|
|
315
|
+
| **Payouts (Read)** | `list_payouts_pending_approval`, `list_rewards_payouts` |
|
|
316
|
+
| **Payouts (Write)** | `approve_payouts`, `reject_payouts` |
|
|
317
|
+
| **Tiers** | `update_project_tier` |
|
|
318
|
+
| **Audiences** | `update_audience` |
|
|
319
|
+
| **Triggers** | `update_trigger` |
|
|
320
|
+
| **Payout Terms** | `update_payout_term` |
|
|
321
|
+
|
|
322
|
+
### Tool Examples
|
|
323
|
+
|
|
324
|
+
All tools receive JSON arguments. Use real UUIDs from your tenant.
|
|
325
|
+
|
|
326
|
+
#### Health checks
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
// ping (no auth required)
|
|
330
|
+
{}
|
|
331
|
+
|
|
332
|
+
// whoami (requires login)
|
|
333
|
+
{}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### Metadata queries
|
|
337
|
+
|
|
338
|
+
```json
|
|
339
|
+
// list_chains, list_trigger_types, list_payout_schemas
|
|
340
|
+
{}
|
|
129
341
|
```
|
|
130
342
|
|
|
131
|
-
|
|
343
|
+
#### Project operations
|
|
132
344
|
|
|
133
|
-
|
|
345
|
+
```json
|
|
346
|
+
// list_projects
|
|
347
|
+
{ "page": 1, "query": "acme" }
|
|
134
348
|
|
|
135
|
-
|
|
136
|
-
|
|
349
|
+
// get_project
|
|
350
|
+
{ "project_id": "550e8400-e29b-41d4-a716-446655440000" }
|
|
351
|
+
```
|
|
137
352
|
|
|
138
|
-
|
|
353
|
+
#### Incentives
|
|
139
354
|
|
|
140
355
|
```json
|
|
356
|
+
// list_incentives
|
|
357
|
+
{ "project_id": "<uuid>" }
|
|
358
|
+
|
|
359
|
+
// get_incentive
|
|
360
|
+
{ "project_id": "<uuid>", "conversion_id": "<uuid>" }
|
|
361
|
+
|
|
362
|
+
// get_trigger
|
|
363
|
+
{ "project_id": "<uuid>", "trigger_id": "<uuid>" }
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### Affiliate analytics
|
|
367
|
+
|
|
368
|
+
```json
|
|
369
|
+
// get_affiliate_portal_stats (single affiliate)
|
|
141
370
|
{
|
|
142
|
-
"
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
371
|
+
"project_id": "<uuid>",
|
|
372
|
+
"user_identifier": "evm:0x1234..."
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// get_project_affiliate_total_stats (project totals)
|
|
376
|
+
{
|
|
377
|
+
"project_id": "<uuid>",
|
|
378
|
+
"dateRange": "30d"
|
|
149
379
|
}
|
|
380
|
+
|
|
381
|
+
// get_project_affiliates_breakdown (grouped breakdown)
|
|
382
|
+
{
|
|
383
|
+
"project_id": "<uuid>",
|
|
384
|
+
"groupBy": "region",
|
|
385
|
+
"dateRange": "30d"
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
`groupBy` options: `audience`, `tier`, `region`, `status`
|
|
390
|
+
|
|
391
|
+
`dateRange` options: `7d`, `30d`, `90d`, `MTD`, `QTD`, `custom`, `all`
|
|
392
|
+
|
|
393
|
+
#### Payout operations
|
|
394
|
+
|
|
395
|
+
```json
|
|
396
|
+
// list_payouts_pending_approval
|
|
397
|
+
{ "project_id": "<uuid>", "page": 1, "page_size": 50 }
|
|
398
|
+
|
|
399
|
+
// list_rewards_payouts
|
|
400
|
+
{ "project_id": "<uuid>", "page": 1 }
|
|
150
401
|
```
|
|
151
402
|
|
|
152
|
-
|
|
403
|
+
### Write Operations (Two-Step Flow)
|
|
404
|
+
|
|
405
|
+
All mutation tools require a **two-step process**:
|
|
406
|
+
|
|
407
|
+
1. **Preview:** Call with `dry_run: true` — validates and returns a preview without making changes
|
|
408
|
+
2. **Confirm:** Call with `confirmed: true` — executes the mutation
|
|
409
|
+
|
|
410
|
+
#### Example: Approve payouts
|
|
153
411
|
|
|
154
412
|
```json
|
|
413
|
+
// Step 1: Preview
|
|
155
414
|
{
|
|
156
|
-
"
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
415
|
+
"project_id": "<uuid>",
|
|
416
|
+
"payout_ids": ["<uuid1>", "<uuid2>"],
|
|
417
|
+
"dry_run": true
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Step 2: Confirm (after user approval)
|
|
421
|
+
{
|
|
422
|
+
"project_id": "<uuid>",
|
|
423
|
+
"payout_ids": ["<uuid1>", "<uuid2>"],
|
|
424
|
+
"confirmed": true
|
|
165
425
|
}
|
|
166
426
|
```
|
|
167
427
|
|
|
168
|
-
|
|
428
|
+
Write tools: `approve_payouts`, `reject_payouts`, `update_project_tier`, `update_audience`, `update_trigger`, `update_payout_term`
|
|
169
429
|
|
|
170
|
-
|
|
430
|
+
---
|
|
171
431
|
|
|
172
|
-
|
|
432
|
+
## Troubleshooting
|
|
173
433
|
|
|
174
|
-
|
|
434
|
+
### MCP server fails to start
|
|
175
435
|
|
|
176
|
-
|
|
436
|
+
**Symptom:** Error like `Cannot find package '@fuul/mcp-server'` or binary not found.
|
|
177
437
|
|
|
178
|
-
|
|
438
|
+
**Solution:** Ensure you use the `--package=` format in args:
|
|
439
|
+
|
|
440
|
+
```json
|
|
441
|
+
{
|
|
442
|
+
"args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"]
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Wrong:**
|
|
447
|
+
```json
|
|
448
|
+
{
|
|
449
|
+
"args": ["-y", "@fuul/mcp-server@latest", "fuul-mcp-server"]
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### 401 Unauthorized errors
|
|
454
|
+
|
|
455
|
+
**Symptom:** API tools return 401 or `whoami` fails.
|
|
456
|
+
|
|
457
|
+
**Solution:**
|
|
458
|
+
|
|
459
|
+
1. Run login again:
|
|
460
|
+
```bash
|
|
461
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp login
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
2. Verify tokens exist:
|
|
465
|
+
- macOS/Linux: `~/.fuul/tokens.json`
|
|
466
|
+
- Windows: `%USERPROFILE%\.fuul\tokens.json`
|
|
467
|
+
|
|
468
|
+
3. Verify session:
|
|
469
|
+
```bash
|
|
470
|
+
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### Rate limiting (HTTP 429)
|
|
474
|
+
|
|
475
|
+
**Symptom:** Tools return 429 errors.
|
|
476
|
+
|
|
477
|
+
**Solution:** Wait for the `Retry-After` header duration, then retry. The MCP server handles this automatically in most cases.
|
|
478
|
+
|
|
479
|
+
### Environment not loading
|
|
480
|
+
|
|
481
|
+
**Symptom:** Staging URL not being used despite `.env` file.
|
|
482
|
+
|
|
483
|
+
**Solution:**
|
|
484
|
+
|
|
485
|
+
1. Ensure `cwd` in your MCP config points to the directory containing `.env`
|
|
486
|
+
2. Or pass environment directly in the config:
|
|
487
|
+
```json
|
|
488
|
+
{
|
|
489
|
+
"env": {
|
|
490
|
+
"FUUL_API_BASE_URL": "https://api.stg.fuul.xyz"
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Windows path issues
|
|
496
|
+
|
|
497
|
+
**Symptom:** Paths not resolving correctly on Windows.
|
|
498
|
+
|
|
499
|
+
**Solution:** Use double backslashes or forward slashes:
|
|
500
|
+
|
|
501
|
+
```json
|
|
502
|
+
{
|
|
503
|
+
"args": ["C:\\Users\\me\\mcp_server\\dist\\index.js"]
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Or:
|
|
508
|
+
|
|
509
|
+
```json
|
|
510
|
+
{
|
|
511
|
+
"args": ["C:/Users/me/mcp_server/dist/index.js"]
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## Repository Layout
|
|
518
|
+
|
|
519
|
+
```
|
|
179
520
|
mcp_server/
|
|
180
521
|
├── .claude-plugin/ # Claude Code marketplace manifest
|
|
181
522
|
│ └── marketplace.json
|
|
523
|
+
├── .github/
|
|
524
|
+
│ ├── workflows/ # CI and release workflows
|
|
525
|
+
│ │ ├── ci.yml
|
|
526
|
+
│ │ └── release.yml
|
|
527
|
+
│ └── pull_request_template.md
|
|
528
|
+
├── docs/ # Documentation
|
|
529
|
+
│ ├── README.md # Docs index
|
|
530
|
+
│ ├── AGENTS.md # Tool ↔ HTTP mapping
|
|
531
|
+
│ └── mcp-phase2/
|
|
532
|
+
│ ├── CONSUMER.md # API expectations
|
|
533
|
+
│ └── tool-prompts.md # Sample prompts for evals
|
|
182
534
|
├── plugins/
|
|
183
|
-
│ └── fuul-mcp/ #
|
|
535
|
+
│ └── fuul-mcp/ # Claude Code plugin
|
|
184
536
|
│ ├── .claude-plugin/
|
|
185
537
|
│ │ └── plugin.json
|
|
186
|
-
│ ├── .mcp.json
|
|
187
|
-
│ └── skills/
|
|
538
|
+
│ ├── .mcp.json # MCP server config
|
|
539
|
+
│ └── skills/
|
|
540
|
+
│ └── fuul/
|
|
541
|
+
│ └── SKILL.md # Tool usage instructions
|
|
188
542
|
├── src/ # TypeScript source
|
|
189
|
-
├──
|
|
190
|
-
├──
|
|
191
|
-
├──
|
|
192
|
-
|
|
543
|
+
│ ├── affiliate-portal/ # Affiliate analytics
|
|
544
|
+
│ ├── agent/ # Write confirmation logic
|
|
545
|
+
│ ├── auth/ # OAuth and tokens
|
|
546
|
+
│ ├── config/ # Environment config
|
|
547
|
+
│ ├── http/ # HTTP client
|
|
548
|
+
│ ├── metadata/ # Chains, triggers, schemas
|
|
549
|
+
│ ├── payouts/ # Payout operations
|
|
550
|
+
│ ├── tools/ # MCP tool definitions
|
|
551
|
+
│ ├── triggers/ # Trigger operations
|
|
552
|
+
│ ├── util/ # Utilities
|
|
553
|
+
│ ├── cli.ts # CLI entry point
|
|
554
|
+
│ └── index.ts # MCP server entry point
|
|
555
|
+
├── dist/ # Compiled output (gitignored)
|
|
556
|
+
├── .env.example # Environment template
|
|
557
|
+
├── CHANGELOG.md # Release notes
|
|
558
|
+
├── package.json
|
|
559
|
+
├── release.config.cjs # semantic-release config
|
|
560
|
+
├── tsconfig.json
|
|
561
|
+
└── vitest.config.ts
|
|
193
562
|
```
|
|
194
563
|
|
|
195
|
-
|
|
564
|
+
---
|
|
196
565
|
|
|
197
|
-
|
|
198
|
-
- A running **fuul-server** (staging or production) with **Agent OAuth** configured
|
|
566
|
+
## Scripts Reference
|
|
199
567
|
|
|
200
|
-
|
|
568
|
+
| Script | Description |
|
|
569
|
+
|--------|-------------|
|
|
570
|
+
| `npm run build` | Compile TypeScript → `dist/` |
|
|
571
|
+
| `npm start` | Run MCP server (`node dist/index.js`) |
|
|
572
|
+
| `npm run dev` | Run MCP server with hot reload (`tsx src/index.ts`) |
|
|
573
|
+
| `npm run cli` | Run OAuth CLI (`tsx src/cli.ts`) |
|
|
574
|
+
| `npm run lint` | ESLint on `src/` |
|
|
575
|
+
| `npm run lint:fix` | Auto-fix lint issues |
|
|
576
|
+
| `npm run test` | Run tests with Vitest |
|
|
577
|
+
| `npm run test:ci` | Run tests in CI mode |
|
|
578
|
+
| `npm run format` | Format code with Prettier |
|
|
201
579
|
|
|
202
|
-
|
|
580
|
+
---
|
|
203
581
|
|
|
204
|
-
##
|
|
582
|
+
## Documentation
|
|
205
583
|
|
|
206
|
-
|
|
584
|
+
| Resource | Description |
|
|
585
|
+
|----------|-------------|
|
|
586
|
+
| [docs/README.md](docs/README.md) | Documentation index |
|
|
587
|
+
| [docs/AGENTS.md](docs/AGENTS.md) | Tool ↔ HTTP endpoint mapping |
|
|
588
|
+
| [docs/mcp-phase2/CONSUMER.md](docs/mcp-phase2/CONSUMER.md) | Staging/production URLs, API expectations |
|
|
589
|
+
| [docs/mcp-phase2/tool-prompts.md](docs/mcp-phase2/tool-prompts.md) | Sample prompts for testing and evals |
|
|
590
|
+
| [CHANGELOG.md](CHANGELOG.md) | Release notes |
|
|
207
591
|
|
|
208
|
-
|
|
209
|
-
**About `NPM_TOKEN` in caps:** npm docs use that name for **classic token** auth. With **Trusted Publishing** you do **not** put a token value into npm for OIDC; GitHub provides the identity. You also do **not** need a GitHub secret named `NPM_TOKEN` for this flow. (If the npm UI showed `NPM_TOKEN`, it is usually help text for the non-OIDC case.)
|
|
210
|
-
2. **Branches**: on **push** to `main`, `beta`, or `alpha`, that workflow runs `npm ci`, **build**, **`npm run test:ci`**, then `npx semantic-release` on push only.
|
|
211
|
-
3. **Config**: [release.config.cjs](release.config.cjs) matches fuul-sdk’s plugin list and order; `@semantic-release/exec` uses the same **`verifyReleaseCmd`** writing `src/release.json` (placeholder [src/release.json](src/release.json)); `@semantic-release/git` commits **`package.json`** only.
|
|
212
|
-
4. **Commits**: use [Conventional Commits](https://www.conventionalcommits.org/) on releasable branches (e.g. `feat:`, `fix:`, `BREAKING CHANGE:`) so the next version is computed; if nothing warrants a release, the job exits without publishing (expected).
|
|
592
|
+
---
|
|
213
593
|
|
|
214
|
-
|
|
594
|
+
## CI and Releases
|
|
215
595
|
|
|
216
|
-
|
|
596
|
+
### Continuous Integration
|
|
217
597
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
598
|
+
On each push/PR to `main`, `master`, `beta`, or `alpha`, GitHub Actions runs:
|
|
599
|
+
- **lint** — ESLint checks
|
|
600
|
+
- **test** — Vitest test suite
|
|
601
|
+
- **build** — TypeScript compilation
|
|
602
|
+
|
|
603
|
+
### Publishing
|
|
604
|
+
|
|
605
|
+
Releases are automated via **semantic-release** and **npm Trusted Publishing (OIDC)**:
|
|
606
|
+
|
|
607
|
+
1. Use [Conventional Commits](https://www.conventionalcommits.org/): `feat:`, `fix:`, `BREAKING CHANGE:`
|
|
608
|
+
2. Merge to `main` (or `beta`/`alpha` for pre-releases)
|
|
609
|
+
3. GitHub Actions runs `semantic-release`, which:
|
|
610
|
+
- Determines the next version from commits
|
|
611
|
+
- Updates `package.json` and `CHANGELOG.md`
|
|
612
|
+
- Publishes to npm
|
|
613
|
+
- Creates a GitHub release
|
|
614
|
+
|
|
615
|
+
No manual `npm publish` or GitHub Release creation needed.
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
## Requirements
|
|
620
|
+
|
|
621
|
+
- **Node.js** 18 or higher
|
|
622
|
+
- A running **fuul-server** (staging or production) with **Agent OAuth** configured
|
|
623
|
+
|
|
624
|
+
---
|
|
228
625
|
|
|
229
626
|
## License
|
|
230
627
|
|
|
231
|
-
MIT — see
|
|
628
|
+
MIT — see [package.json](package.json)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare const PING_DESCRIPTION = "Health check: returns \"pong\" if the MCP process is running. No API calls. Example: invoke with empty input {}.";
|
|
5
5
|
export declare const WHOAMI_DESCRIPTION = "Returns the current Fuul dashboard user as JSON from GET /api/v1/auth/user. Requires prior CLI login (tokens in ~/.fuul/tokens.json). Example: {} after `npm run cli -- login`.";
|
|
6
|
-
export declare const LIST_CHAINS_DESCRIPTION = "Lists supported blockchain chains from GET /public-api/v1/metadata/chains. Uses server metadata (not a hardcoded catalog); responses are cached with ETag/Cache-Control. Params: none (pass {}). Pagination: not exposed by this tool until the API adds cursor/limit.";
|
|
6
|
+
export declare const LIST_CHAINS_DESCRIPTION = "Lists supported blockchain chains from GET /public-api/v1/metadata/chains. Uses server metadata (not a hardcoded catalog); responses are cached with ETag/Cache-Control. Each chain includes snake_case fields such as chain_id, is_testnet, optional svm_network and webapp_capabilities, and can_be_used_for_payouts (boolean: true where Fuul reward/payout infra is deployed). Params: none (pass {}). Pagination: not exposed by this tool until the API adds cursor/limit.";
|
|
7
7
|
export declare const LIST_TRIGGER_TYPES_DESCRIPTION = "Lists trigger type metadata from GET /public-api/v1/metadata/trigger-types (cached). Use ids from this response when building programs/triggers. Params: {}.";
|
|
8
8
|
export declare const LIST_PAYOUT_SCHEMAS_DESCRIPTION = "Lists payout schema metadata from GET /public-api/v1/metadata/payout-schemas (cached). Params: {}.";
|
|
9
9
|
export declare const LIST_PROJECTS_DESCRIPTION = "Lists dashboard projects for the current user: GET /api/v1/projects with optional ?page= (1-based) and ?query=. Example: {\"page\":1} or {\"query\":\"acme\"}.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-descriptions.d.ts","sourceRoot":"","sources":["../../src/tools/tool-descriptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,gBAAgB,qHAAmH,CAAC;AAEjJ,eAAO,MAAM,kBAAkB,oLACoJ,CAAC;AAEpL,eAAO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"tool-descriptions.d.ts","sourceRoot":"","sources":["../../src/tools/tool-descriptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,gBAAgB,qHAAmH,CAAC;AAEjJ,eAAO,MAAM,kBAAkB,oLACoJ,CAAC;AAEpL,eAAO,MAAM,uBAAuB,qdACgb,CAAC;AAGrd,eAAO,MAAM,8BAA8B,iKACqH,CAAC;AAEjK,eAAO,MAAM,+BAA+B,uGAAuG,CAAC;AAEpJ,eAAO,MAAM,yBAAyB,mKACsH,CAAC;AAE7J,eAAO,MAAM,uBAAuB,4HACmF,CAAC;AAExH,eAAO,MAAM,2BAA2B,0IAC6F,CAAC;AAEtI,eAAO,MAAM,yBAAyB,qJACsG,CAAC;AAE7I,eAAO,MAAM,uBAAuB,2LAC8I,CAAC;AAEnL,eAAO,MAAM,8BAA8B,QAGwF,CAAC;AAEpI,eAAO,MAAM,+BAA+B,QAEyF,CAAC;AAEtI,eAAO,MAAM,2BAA2B,QAEgF,CAAC;AAEzH,eAAO,MAAM,0BAA0B,QAEgE,CAAC;AAExG,eAAO,MAAM,yCAAyC,0LAC2H,CAAC;AAElL,eAAO,MAAM,gCAAgC,mMAC+I,CAAC;AAE7L,eAAO,MAAM,2BAA2B,oQACiN,CAAC;AAE1P,eAAO,MAAM,0BAA0B,2GAA2G,CAAC;AAInJ,eAAO,MAAM,sCAAsC,QAIlC,CAAC;AAElB,eAAO,MAAM,6CAA6C,QAIzC,CAAC;AAElB,eAAO,MAAM,4CAA4C,QAIxC,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const PING_DESCRIPTION = 'Health check: returns "pong" if the MCP process is running. No API calls. Example: invoke with empty input {}.';
|
|
5
5
|
export const WHOAMI_DESCRIPTION = 'Returns the current Fuul dashboard user as JSON from GET /api/v1/auth/user. Requires prior CLI login (tokens in ~/.fuul/tokens.json). Example: {} after `npm run cli -- login`.';
|
|
6
|
-
export const LIST_CHAINS_DESCRIPTION = 'Lists supported blockchain chains from GET /public-api/v1/metadata/chains. Uses server metadata (not a hardcoded catalog); responses are cached with ETag/Cache-Control. Params: none (pass {}). Pagination: not exposed by this tool until the API adds cursor/limit.';
|
|
6
|
+
export const LIST_CHAINS_DESCRIPTION = 'Lists supported blockchain chains from GET /public-api/v1/metadata/chains. Uses server metadata (not a hardcoded catalog); responses are cached with ETag/Cache-Control. Each chain includes snake_case fields such as chain_id, is_testnet, optional svm_network and webapp_capabilities, and can_be_used_for_payouts (boolean: true where Fuul reward/payout infra is deployed). Params: none (pass {}). Pagination: not exposed by this tool until the API adds cursor/limit.';
|
|
7
7
|
export const LIST_TRIGGER_TYPES_DESCRIPTION = 'Lists trigger type metadata from GET /public-api/v1/metadata/trigger-types (cached). Use ids from this response when building programs/triggers. Params: {}.';
|
|
8
8
|
export const LIST_PAYOUT_SCHEMAS_DESCRIPTION = 'Lists payout schema metadata from GET /public-api/v1/metadata/payout-schemas (cached). Params: {}.';
|
|
9
9
|
export const LIST_PROJECTS_DESCRIPTION = 'Lists dashboard projects for the current user: GET /api/v1/projects with optional ?page= (1-based) and ?query=. Example: {"page":1} or {"query":"acme"}.';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-descriptions.js","sourceRoot":"","sources":["../../src/tools/tool-descriptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,gHAAgH,CAAC;AAEjJ,MAAM,CAAC,MAAM,kBAAkB,GAC7B,iLAAiL,CAAC;AAEpL,MAAM,CAAC,MAAM,uBAAuB,GAClC,
|
|
1
|
+
{"version":3,"file":"tool-descriptions.js","sourceRoot":"","sources":["../../src/tools/tool-descriptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,gHAAgH,CAAC;AAEjJ,MAAM,CAAC,MAAM,kBAAkB,GAC7B,iLAAiL,CAAC;AAEpL,MAAM,CAAC,MAAM,uBAAuB,GAClC,kdAAkd,CAAC;AAGrd,MAAM,CAAC,MAAM,8BAA8B,GACzC,8JAA8J,CAAC;AAEjK,MAAM,CAAC,MAAM,+BAA+B,GAAG,oGAAoG,CAAC;AAEpJ,MAAM,CAAC,MAAM,yBAAyB,GACpC,0JAA0J,CAAC;AAE7J,MAAM,CAAC,MAAM,uBAAuB,GAClC,qHAAqH,CAAC;AAExH,MAAM,CAAC,MAAM,2BAA2B,GACtC,mIAAmI,CAAC;AAEtI,MAAM,CAAC,MAAM,yBAAyB,GACpC,0IAA0I,CAAC;AAE7I,MAAM,CAAC,MAAM,uBAAuB,GAClC,gLAAgL,CAAC;AAEnL,MAAM,CAAC,MAAM,8BAA8B,GACzC,yIAAyI;IACzI,kIAAkI;IAClI,iIAAiI,CAAC;AAEpI,MAAM,CAAC,MAAM,+BAA+B,GAC1C,mKAAmK;IACnK,mIAAmI,CAAC;AAEtI,MAAM,CAAC,MAAM,2BAA2B,GACtC,sRAAsR;IACtR,sHAAsH,CAAC;AAEzH,MAAM,CAAC,MAAM,0BAA0B,GACrC,2NAA2N;IAC3N,qGAAqG,CAAC;AAExG,MAAM,CAAC,MAAM,yCAAyC,GACpD,+KAA+K,CAAC;AAElL,MAAM,CAAC,MAAM,gCAAgC,GAC3C,0LAA0L,CAAC;AAE7L,MAAM,CAAC,MAAM,2BAA2B,GACtC,uPAAuP,CAAC;AAE1P,MAAM,CAAC,MAAM,0BAA0B,GAAG,wGAAwG,CAAC;AAEnJ,MAAM,eAAe,GAAG,sFAAsF,CAAC;AAE/G,MAAM,CAAC,MAAM,sCAAsC,GACjD,2GAA2G;IAC3G,kHAAkH;IAClH,iEAAiE;IACjE,eAAe,CAAC;AAElB,MAAM,CAAC,MAAM,6CAA6C,GACxD,0GAA0G;IAC1G,yHAAyH;IACzH,gFAAgF;IAChF,eAAe,CAAC;AAElB,MAAM,CAAC,MAAM,4CAA4C,GACvD,+IAA+I;IAC/I,4HAA4H;IAC5H,wEAAwE;IACxE,eAAe,CAAC"}
|