funifier-mcp
v0.7.0
Published
Funifier AI toolkit — MCP server, API client, and Claude Code skills for the Funifier gamification platform
Maintainers
Readme
funifier-mcp
Funifier AI toolkit — API client, MCP server, and AI assistant skills for the Funifier gamification platform.
What's included
| Component | Description |
|-----------|-------------|
| API Client | Pure Node.js client for the Funifier REST API (80+ methods, 18 resource types) |
| MCP Server | Model Context Protocol server — 14 tools, 3 prompts, documentation resources |
| Skills | 32 guided workflows for Claude Code, Codex, OpenCode, Copilot, Continue, and Cursor |
| CLI | npx funifier-mcp@latest init — interactive setup for AI platforms |
Quick Start
npx funifier-mcp@latest initOne command — no install required. init is interactive: it asks which AI platforms you use (Claude Code, Codex CLI, OpenCode, Cursor, Copilot, Google Antigravity), prompts for your Funifier credentials, and writes all config files automatically (skills, MCP config, funifier.json).
CLI Reference
npx funifier-mcp@latest init Interactive setup for AI platforms
funifier-mcp Start the MCP server (stdio)
funifier-mcp --version Print versionDocumentation access
Once the MCP server is connected, agents discover and read docs through MCP tools — the docs ship inside the package, so nothing is copied into your project:
funifier_search_docs "<query>"— ranked, relevant doc paths for a queryfunifier_read_doc path=<path>— full markdown of a doc (e.g.path=modules/trigger)
MCP Server Setup
The MCP server exposes Funifier as tools in any MCP-compatible AI client. npx funifier-mcp@latest init configures it automatically. The server runs via npx — it is never installed into your project, so there are no dependency conflicts with your app's package.json/lockfile. The only requirement is Node.js with npx on your PATH (npx ships with npm). For manual setup, add the block below to your client config:
Claude Code / Cursor / Antigravity (.mcp.json)
{
"mcpServers": {
"funifier": {
"command": "npx",
"args": ["-y", "funifier-mcp@latest"],
"env": {
"FUNIFIER_API_KEY": "your-api-key",
"FUNIFIER_SECRET_KEY": "your-secret-key",
"FUNIFIER_SERVER_URL": "https://your-instance.funifier.com"
}
}
}
}Codex CLI (.codex/config.toml)
[mcp_servers.funifier]
command = "npx"
args = ["-y", "funifier-mcp@latest"]
enabled = true
[mcp_servers.funifier.env]
FUNIFIER_API_KEY = "your-api-key"
FUNIFIER_SECRET_KEY = "your-secret-key"
FUNIFIER_SERVER_URL = "https://your-instance.funifier.com"OpenCode (opencode.json)
{
"mcp": {
"funifier": {
"type": "local",
"command": ["npx", "-y", "funifier-mcp@latest"],
"environment": {
"FUNIFIER_API_KEY": "your-api-key",
"FUNIFIER_SECRET_KEY": "your-secret-key",
"FUNIFIER_SERVER_URL": "https://your-instance.funifier.com"
}
}
}
}Windows: if your client can't find
npx, set"command": "npx.cmd"(or wrap it as"command": "cmd", "args": ["/c", "npx", "-y", "funifier-mcp@latest"]).Air-gapped / offline: npx needs network access on first run to fetch the package. Where that isn't possible, install
funifier-mcpanywhere you like and point the client at its bin directly — e.g."command": "node", "args": ["/path/to/funifier-mcp/dist/mcp/index.js"].
Runtime connection
If no config is provided at startup, use the funifier_connect tool to connect. Two mutually
exclusive ways to call it — never both in the same call:
funifier_connect({ apiKey: "...", secretKey: "...", serverUrl: "https://..." })
funifier_connect({ alias: "prod" })The alias form connects to a name declared in the instances block of funifier.json (see
below) without any credential ever appearing as an argument — the same treatment
funifier_promotion_report already gives both sides it compares. The response declares the
provenance of the connection (e.g. prod ← $PROD_API_KEY), never the value. An optional
config_path mirrors the one on funifier_promotion_report, and an optional name sets the
friendly display name shown back (defaults to the alias itself).
Credentials via funifier.json
Place in your project root for automatic connection at startup:
{
"apiKey": "your-api-key",
"secretKey": "your-secret-key",
"serverUrl": "https://your-instance.funifier.com"
}Add funifier.json to .gitignore — it contains secrets. Also ignore .funifier/backups/ and
.funifier/relatorios/ — the former may contain app_secret values and full scope lists, the
latter carries field paths and secret fingerprints from promotion reports.
Instances (the instances block)
Tools that compare or act across environments — funifier_promotion_report, funifier_connect
(alias form), and any future multi-environment tool — never accept credentials as arguments. They
accept an alias, declared once in the instances block of funifier.json. This is how a
secret value can be referenced without ever crossing into an agent's context window.
{
"apiKey": "your-api-key",
"secretKey": "your-secret-key",
"serverUrl": "https://your-instance.funifier.com",
"instances": {
"dev": {
"apiKey": "dev-api-key",
"secretKey": "dev-secret-key"
},
"prod": {
"apiKeyEnv": "PROD_API_KEY",
"secretKeyEnv": "PROD_SECRET_KEY",
"repo": "../admin-repo"
}
}
}Resolution rules — each one fails loud, naming the alias and the field, instead of resolving to the wrong instance in silence:
- Field by field, literal or
<field>Env. Every field (apiKey,secretKey,serverUrl,repo) accepts either a literal value or a<field>Envholding the name of an environment variable — never the secret value itself. Declare neither and resolution fails, naming the missing field. - Declaring both a literal and its
Envcounterpart is an error, not a silent preference."apiKey"and"apiKeyEnv"on the same alias throws instead of picking one — a stale literal left behind by a credential rotation would otherwise win silently and nobody would notice. apiKeyandsecretKeynever inherit from the top-level fields offunifier.json; onlyserverUrldoes, in the chain instance → top offunifier.json→FUNIFIER_SERVER_URL. An alias missingapiKeyorsecretKeyfails naming the field, instead of quietly falling back to the top-level credential and running against the wrong instance.repo(optional) resolves relative to the directory offunifier.json, not the processcwd. A server launched by a desktop app has an unpredictablecwd, so the path is always anchored to the config file the alias was declared in — not guessed by convention.
Reports never print a secret value: a credential is declared by provenance (e.g.
prod ← $PROD_API_KEY), never by value.
MCP Tools
| Tool | Description |
|------|-------------|
| funifier_connect | Connect to a Funifier instance by credential trio or by instances alias (or switch between instances) |
| funifier_list | List resources by type with optional search filtering |
| funifier_get | Get a specific resource with full details (including code) |
| funifier_save | Create or update a resource |
| funifier_delete | Delete a resource by type and ID |
| funifier_execute | Execute a scheduler, aggregate, or public endpoint |
| funifier_logs | Get execution logs for triggers and schedulers |
| funifier_database | Query, aggregate, insert, update, delete on any collection |
| funifier_permissions | Manage API scopes/security roles and Studio roles/assignments; every mutation auto-backups prior state to .funifier/backups/ — use list_backups and restore_backup to roll back |
| funifier_promotion_report | Compare two Funifier gamifications by alias (e.g. dev → production) and report what to copy, what to configure by hand, and what it cannot assert; it never writes to either gamification — the only side effect is the local report file under .funifier/relatorios/ |
| funifier_promotion_diff | Report what changed for the same alias pair since the most recent retained promotion report; it is an extra reading alongside the full report, never a mode or filter of it. Redacted fields are always reported as indeterminate between runs — the secret fingerprint is salted per run by design |
Resource types: trigger, scheduler, aggregate, websocket, widget, custom-page, public-endpoint, challenge-aggregate, auth-module, ai-knowledge, action, challenge, point, level, leaderboard, quiz, virtual-good-catalog, virtual-good-item
Permissions backup and rollback
Every mutating funifier_permissions action writes a full pre-image snapshot under .funifier/backups/ before the remote write. Snapshots may contain secrets — keep .funifier/backups/ in .gitignore (npx funifier-mcp init adds it automatically).
funifier_permissions({ action: "list_backups" })
funifier_permissions({ action: "restore_backup", backup_path: "<path from list_backups>" })Restore refuses cross-server application when the snapshot's serverUrl differs from the current connection. Optional env vars: FUNIFIER_PROJECT_ROOT (project directory, set in generated MCP configs) and FUNIFIER_BACKUP_ROOT (override backup directory). Snapshots are not auto-pruned — delete old files manually when needed.
Setup backup and rollback
Every init that changes a file first captures a snapshot under .funifier/backups/setup/<timestamp>/
(a manifest.json plus the pre-image of each touched file). If the backup cannot be written, the run
aborts with zero files touched.
npx funifier-mcp@latest restore-setup --list # every snapshot, newest first
npx funifier-mcp@latest restore-setup # undo the most recent init
npx funifier-mcp@latest restore-setup <timestamp> # undo a specific oneRestore replays the pre-images through the same writer init uses, with no merge logic involved. It
refuses any entry whose pre-image no longer matches the sha256 recorded in the manifest, and it takes
a pre-restore snapshot of its own before applying, so an undo can itself be undone.
⚠ These snapshots contain
FUNIFIER_SECRET_KEYin plain text, because the generated configs carry it inline — and now in duplicate, sincerestore-setupsnapshots before restoring. Nothing is pruned automatically: delete.funifier/backups/setup/by hand when you no longer need it. Same trade-off, and same remedy, as the permissions backup above.
Skills and Instructions
npx funifier-mcp@latest init copies the right files for each platform automatically (recommended). For manual copying, use npm install --no-save so nothing is added to your project's package.json/lockfile:
Claude Code
npm install --no-save funifier-mcp
cp -r node_modules/funifier-mcp/skills/* .claude/skills/Start with /funifier in Claude Code — the router skill routes to the right workflow:
/funifierCodex CLI / OpenCode
npm install --no-save funifier-mcp
cp node_modules/funifier-mcp/AGENTS.md .The AGENTS.md is the entry point for Codex, OpenCode, and any agent that reads AGENTS.md.
GitHub Copilot / Continue
npm install --no-save funifier-mcp
mkdir -p .github
cp node_modules/funifier-mcp/.github/copilot-instructions.md .github/Copilot and Continue automatically apply .github/copilot-instructions.md.
Cursor IDE
npm install --no-save funifier-mcp
mkdir -p .cursor/rules
cp node_modules/funifier-mcp/.cursor/rules/funifier.mdc .cursor/rules/Cursor discovers and applies .mdc files in .cursor/rules/ automatically.
Available Workflows
All workflows are accessible through a single /funifier skill. The skill router loads in every conversation (one description) and loads the specific workflow file on demand.
| Workflow | Reference file |
|----------|----------------|
| Help and routing | references/help.md |
| Debug any resource | references/debug.md |
| Create trigger | references/create-trigger.md |
| Create scheduler | references/create-scheduler.md |
| Create aggregate | references/create-aggregate.md |
| Create custom page | references/create-custom-page.md |
| Create action | references/create-action.md |
| Create challenge | references/create-challenge.md |
| Create point category | references/create-point.md |
| Create level progression | references/create-level.md |
| Create leaderboard | references/create-leaderboard.md |
| Create quiz | references/create-quiz.md |
| Create virtual good | references/create-virtual-good.md |
| Implement frontend | references/implement-frontend.md |
| Manage player | references/manage-player.md |
| Manage team | references/manage-team.md |
| Create competition | references/create-competition.md |
| Create folder | references/create-folder.md |
| Create lottery | references/create-lottery.md |
| Create mystery box | references/create-mystery.md |
| Create story | references/create-story.md |
| Create crossword | references/create-crossword.md |
| Create notification | references/create-notification.md |
| Create last mile | references/create-lastmile.md |
| Create webhook | references/create-webhook.md |
| Create websocket | references/create-websocket.md |
| Create widget | references/create-widget.md |
| Create swap | references/create-swap.md |
| Create custom object | references/create-custom-object.md |
| Configure security | references/configure-security.md |
| Import CSV | references/import-csv.md |
| Upload file | references/upload-file.md |
API Client
npm install funifier-mcpimport { createAPIClient } from "funifier-mcp";
const api = createAPIClient({
apiKey: "your-api-key",
secretKey: "your-secret-key",
serverUrl: "https://your-instance.funifier.com",
});
// List resources
const triggers = await api.listTriggers();
// Execute an aggregate
const result = await api.executeAggregate("my-aggregate-id", {});
// Query any collection
const players = await api.queryCollection("player", { active: true }, { limit: 10 });Configuration
Environment variables
| Variable | Description |
|----------|-------------|
| FUNIFIER_API_KEY | API key for authentication |
| FUNIFIER_SECRET_KEY | Secret key for authentication |
| FUNIFIER_SERVER_URL | Base URL of your Funifier instance |
| FUNIFIER_DOCS_PATH | Path to documentation files (optional override) |
Config resolution order
funifier.json in cwd → environment variables.
Documentation
- docs/PLATFORM_SETUP.md — Detailed setup for all platforms
- docs/QUICK_REFERENCE.md — Copy-paste setup commands
- docs/INSTALL_EXAMPLES.md — Real-world scenarios
- docs/MCP_SETUP.md — MCP configuration and troubleshooting
License
MIT
