@fuul/mcp-server
v1.3.0
Published
Fuul MCP server for program management via MCP-compatible clients
Readme
@fuul/mcp-server
Fuul Model Context Protocol server for managing affiliate programs, analytics, incentives, and payouts through MCP-compatible clients (Claude Code, Cursor, Claude Desktop).
Table of Contents
- Quick Start
- Installation Methods
- Authentication
- Configuration
- MCP Tool Reference
- Troubleshooting
- Repository Layout
- Scripts Reference
- Documentation
- CI and Releases
- License
Quick Start
# 1. Install (choose one method below)
# 2. Authenticate once:
npx -y --package=@fuul/mcp-server@latest fuul-mcp login
# 3. Verify:
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoamiInstallation Methods
1. Claude Code Plugin (Recommended)
The easiest way to use Fuul MCP with Claude Code. Adds the MCP server plus a skill that documents how to use Fuul tools.
Step 1: Install the plugin
/plugin marketplace add kuyen-labs/mcp_server
/plugin install fuul-mcp@fuul-mcpStep 2: Verify the .mcp.json format
Check the plugin's .mcp.json at:
~/.claude/plugins/cache/fuul-mcp/fuul-mcp/<version>/.mcp.jsonIt must use the --package= format in args:
{
"mcpServers": {
"fuul": {
"command": "npx",
"args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"],
"env": {
"FUUL_API_BASE_URL": "${user_config.FUUL_API_BASE_URL}"
}
}
}
}If args shows ["-y", "@fuul/mcp-server@latest", "fuul-mcp-server"] (without --package=), update it to match the format above.
Step 3: Reload the plugin
/reload-pluginsStep 4: Authenticate (one-time)
Open a terminal and run:
npx -y --package=@fuul/mcp-server@latest fuul-mcp loginThis opens your browser for OAuth. Tokens are saved to ~/.fuul/tokens.json.
Step 5: Verify
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoamiOptional: Use staging environment
Set FUUL_API_BASE_URL in the plugin's user settings:
| Environment | URL |
|-------------|-----|
| Production (default) | https://api.fuul.xyz |
| Staging | https://api.stg.fuul.xyz |
2. Cursor IDE
Option A: Using npx (no clone required)
Authenticate first:
npx -y --package=@fuul/mcp-server@latest fuul-mcp login npx -y --package=@fuul/mcp-server@latest fuul-mcp whoamiConfigure MCP in Cursor:
Go to Settings → MCP or edit your
mcp.json:{ "mcpServers": { "fuul": { "command": "npx", "args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"], "env": { "FUUL_API_BASE_URL": "https://api.fuul.xyz" } } } }
Option B: Using local clone
Clone and build:
git clone https://github.com/kuyen-labs/mcp_server.git cd mcp_server npm ci npm run buildAuthenticate:
npm run cli -- login npm run cli -- whoamiConfigure MCP in Cursor:
{ "mcpServers": { "fuul": { "command": "node", "args": ["C:\\path\\to\\mcp_server\\dist\\index.js"], "cwd": "C:\\path\\to\\mcp_server" } } }On macOS/Linux:
{ "mcpServers": { "fuul": { "command": "node", "args": ["/path/to/mcp_server/dist/index.js"], "cwd": "/path/to/mcp_server" } } }
3. npx (Any MCP Client)
Use the published npm package without cloning:
| Command | Purpose |
|---------|---------|
| npx -y --package=@fuul/mcp-server@latest fuul-mcp login | Browser OAuth; writes ~/.fuul/tokens.json |
| npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami | Verify session (GET /api/v1/auth/user) |
| npx -y --package=@fuul/mcp-server@latest fuul-mcp logout | Clear tokens |
| npx -y --package=@fuul/mcp-server@latest fuul-mcp-server | Start stdio MCP server |
For MCP client configs (JSON), use the --package= format:
{
"command": "npx",
"args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"]
}4. Local Development (Clone)
git clone https://github.com/kuyen-labs/mcp_server.git
cd mcp_server
npm ci
cp .env.example .env # Optional: edit for staging/custom settings
npm run buildRun CLI commands:
npm run cli -- login
npm run cli -- whoami
npm run cli -- logoutRun MCP server:
npm start # Production (uses dist/)
npm run dev # Development (uses tsx, watches src/)Debug with MCP Inspector:
npm run build
npx @modelcontextprotocol/inspector node dist/index.jsAuthentication
Authentication uses OAuth with the Fuul dashboard. Tokens are stored locally and shared by the CLI and MCP server.
Token location
| OS | Path |
|----|------|
| macOS/Linux | ~/.fuul/tokens.json |
| Windows | %USERPROFILE%\.fuul\tokens.json |
Login flow
npx -y --package=@fuul/mcp-server@latest fuul-mcp loginThis opens your default browser to the Fuul OAuth page. After authorizing, tokens are saved automatically.
Verify session
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoamiClear tokens
npx -y --package=@fuul/mcp-server@latest fuul-mcp logoutConfiguration
Environment variables are read from process.env and, when present, a .env file in the current working directory.
| Variable | Default | Description |
|----------|---------|-------------|
| FUUL_API_BASE_URL | https://api.fuul.xyz | API origin (no trailing slash). Use https://api.stg.fuul.xyz for staging. |
| FUUL_OAUTH_CLIENT_ID | fuul-agent | OAuth client ID |
| FUUL_OAUTH_REDIRECT_URI | http://127.0.0.1:8765/callback | OAuth callback URL |
| FUUL_MCP_TOOL_TIMEOUT_MS | 90000 | Per-tool timeout in milliseconds |
| FUUL_MCP_PROJECT_API_KEY | (unset) | Project API key (Bearer) for public API tools: managed affiliates and Events |
| FUUL_MCP_DEBUG | false | Set to 1 or true for debug logging |
Example .env file
FUUL_API_BASE_URL=https://api.stg.fuul.xyz
FUUL_MCP_DEBUG=1Note: The
.envfile is for local development only and is not included in the npm package. Tokens are stored in~/.fuul/tokens.json, not in.env.
MCP Tool Reference
Tool Categories
| Category | Tools |
|----------|-------|
| Health | ping, whoami |
| Metadata (cached) | list_chains, list_trigger_types, list_payout_schemas |
| Projects | list_projects, get_project |
| Incentives | list_incentives, get_incentive, get_trigger |
| Affiliate Analytics | get_affiliate_portal_stats, get_project_affiliate_total_stats, get_project_affiliates_breakdown |
| Managed Affiliates (project API key) | get_project_affiliate_public, create_project_affiliate_public, update_project_affiliate_public |
| Events (project API key) | send_event, send_batch_events, check_event_status |
| Payouts (Read) | list_payouts_pending_approval, list_rewards_payouts |
| Payouts (Write) | approve_payouts, reject_payouts |
| Tiers | update_project_tier |
| Audiences | update_audience |
| Triggers | update_trigger |
| Payout Terms | update_payout_term |
Tool Examples
All tools receive JSON arguments. Use real UUIDs from your tenant.
Health checks
// ping (no auth required)
{}
// whoami (requires login)
{}Metadata queries
// list_chains, list_trigger_types, list_payout_schemas
{}Project operations
// list_projects
{ "page": 1, "query": "acme" }
// get_project
{ "project_id": "550e8400-e29b-41d4-a716-446655440000" }Incentives
// list_incentives
{ "project_id": "<uuid>" }
// get_incentive
{ "project_id": "<uuid>", "conversion_id": "<uuid>" }
// get_trigger
{ "project_id": "<uuid>", "trigger_id": "<uuid>" }Affiliate analytics
// get_affiliate_portal_stats (single affiliate)
{
"project_id": "<uuid>",
"user_identifier": "evm:0x1234..."
}
// get_project_affiliate_total_stats (project totals)
{
"project_id": "<uuid>",
"dateRange": "30d"
}
// get_project_affiliates_breakdown (grouped breakdown)
{
"project_id": "<uuid>",
"groupBy": "region",
"dateRange": "30d"
}groupBy options: audience, tier, region, status
dateRange options: 7d, 30d, 90d, MTD, QTD, custom, all
Events (project API key)
Requires FUUL_MCP_PROJECT_API_KEY or project_api_key on each call. Writes use dry_run then confirmed.
// check_event_status
{
"user_identifier": "0x80Fe27F878d2d42BD8b387F3cA4b96CBDEc05326",
"user_identifier_type": "evm_address",
"event_name": "trade"
}
// send_event (dry_run preview)
{
"name": "trade",
"user_identifier": "0x80Fe27F878d2d42BD8b387F3cA4b96CBDEc05326",
"user_identifier_type": "evm_address",
"dedup_id": "4bdabf2c-271a-4d66-afd0-a9f24119810a",
"args": { "volume": 1000 },
"dry_run": true
}
// send_batch_events (confirmed)
{
"events": [
{
"name": "trade",
"user_identifier": "0x80Fe27F878d2d42BD8b387F3cA4b96CBDEc05326",
"user_identifier_type": "evm_address",
"dedup_id": "batch-id-1"
}
],
"confirmed": true
}Payout operations
// list_payouts_pending_approval
{ "project_id": "<uuid>", "page": 1, "page_size": 50 }
// list_rewards_payouts
{ "project_id": "<uuid>", "page": 1 }Write Operations (Two-Step Flow)
All mutation tools require a two-step process:
- Preview: Call with
dry_run: true— validates and returns a preview without making changes - Confirm: Call with
confirmed: true— executes the mutation
Example: Approve payouts
// Step 1: Preview
{
"project_id": "<uuid>",
"payout_ids": ["<uuid1>", "<uuid2>"],
"dry_run": true
}
// Step 2: Confirm (after user approval)
{
"project_id": "<uuid>",
"payout_ids": ["<uuid1>", "<uuid2>"],
"confirmed": true
}Write tools: approve_payouts, reject_payouts, update_project_tier, update_audience, update_trigger, update_payout_term
Troubleshooting
MCP server fails to start
Symptom: Error like Cannot find package '@fuul/mcp-server' or binary not found.
Solution: Ensure you use the --package= format in args:
{
"args": ["-y", "--package=@fuul/mcp-server@latest", "fuul-mcp-server"]
}Wrong:
{
"args": ["-y", "@fuul/mcp-server@latest", "fuul-mcp-server"]
}401 Unauthorized errors
Symptom: API tools return 401 or whoami fails.
Solution:
Run login again:
npx -y --package=@fuul/mcp-server@latest fuul-mcp loginVerify tokens exist:
- macOS/Linux:
~/.fuul/tokens.json - Windows:
%USERPROFILE%\.fuul\tokens.json
- macOS/Linux:
Verify session:
npx -y --package=@fuul/mcp-server@latest fuul-mcp whoami
Rate limiting (HTTP 429)
Symptom: Tools return 429 errors.
Solution: Wait for the Retry-After header duration, then retry. The MCP server handles this automatically in most cases.
Environment not loading
Symptom: Staging URL not being used despite .env file.
Solution:
- Ensure
cwdin your MCP config points to the directory containing.env - Or pass environment directly in the config:
{ "env": { "FUUL_API_BASE_URL": "https://api.stg.fuul.xyz" } }
Windows path issues
Symptom: Paths not resolving correctly on Windows.
Solution: Use double backslashes or forward slashes:
{
"args": ["C:\\Users\\me\\mcp_server\\dist\\index.js"]
}Or:
{
"args": ["C:/Users/me/mcp_server/dist/index.js"]
}Repository Layout
mcp_server/
├── .claude-plugin/ # Claude Code marketplace manifest
│ └── marketplace.json
├── .github/
│ ├── workflows/ # CI and release workflows
│ │ ├── ci.yml
│ │ └── release.yml
│ └── pull_request_template.md
├── docs/ # Documentation
│ ├── README.md # Docs index
│ ├── AGENTS.md # Tool ↔ HTTP mapping
│ └── mcp-phase2/
│ ├── CONSUMER.md # API expectations
│ └── tool-prompts.md # Sample prompts for evals
├── plugins/
│ └── fuul-mcp/ # Claude Code plugin
│ ├── .claude-plugin/
│ │ └── plugin.json
│ ├── .mcp.json # MCP server config
│ └── skills/
│ └── fuul/
│ └── SKILL.md # Tool usage instructions
├── src/ # TypeScript source
│ ├── affiliate-portal/ # Affiliate analytics
│ ├── agent/ # Write confirmation logic
│ ├── auth/ # OAuth and tokens
│ ├── config/ # Environment config
│ ├── http/ # HTTP client
│ ├── metadata/ # Chains, triggers, schemas
│ ├── payouts/ # Payout operations
│ ├── tools/ # MCP tool definitions
│ ├── triggers/ # Trigger operations
│ ├── util/ # Utilities
│ ├── cli.ts # CLI entry point
│ └── index.ts # MCP server entry point
├── dist/ # Compiled output (gitignored)
├── .env.example # Environment template
├── CHANGELOG.md # Release notes
├── package.json
├── release.config.cjs # semantic-release config
├── tsconfig.json
└── vitest.config.tsScripts Reference
| Script | Description |
|--------|-------------|
| npm run build | Compile TypeScript → dist/ |
| npm start | Run MCP server (node dist/index.js) |
| npm run dev | Run MCP server with hot reload (tsx src/index.ts) |
| npm run cli | Run OAuth CLI (tsx src/cli.ts) |
| npm run lint | ESLint on src/ |
| npm run lint:fix | Auto-fix lint issues |
| npm run test | Run tests with Vitest |
| npm run test:ci | Run tests in CI mode |
| npm run format | Format code with Prettier |
Documentation
| Resource | Description | |----------|-------------| | docs/README.md | Documentation index | | docs/AGENTS.md | Tool ↔ HTTP endpoint mapping | | docs/mcp-phase2/CONSUMER.md | Staging/production URLs, API expectations | | docs/mcp-phase2/tool-prompts.md | Sample prompts for testing and evals | | CHANGELOG.md | Release notes |
CI and Releases
Continuous Integration
On each push/PR to main, master, beta, or alpha, GitHub Actions runs:
- lint — ESLint checks
- test — Vitest test suite
- build — TypeScript compilation
Publishing
Releases are automated via semantic-release and npm Trusted Publishing (OIDC):
- Use Conventional Commits:
feat:,fix:,BREAKING CHANGE: - Merge to
main(orbeta/alphafor pre-releases) - GitHub Actions runs
semantic-release, which:- Determines the next version from commits
- Updates
package.jsonandCHANGELOG.md - Publishes to npm
- Creates a GitHub release
No manual npm publish or GitHub Release creation needed.
Requirements
- Node.js 18 or higher
- A running fuul-server (staging or production) with Agent OAuth configured
License
MIT — see package.json
