npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

funifier-mcp

v0.7.0

Published

Funifier AI toolkit — MCP server, API client, and Claude Code skills for the Funifier gamification platform

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 init

One 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 version

Documentation 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 query
  • funifier_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-mcp anywhere 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:

  1. Field by field, literal or <field>Env. Every field (apiKey, secretKey, serverUrl, repo) accepts either a literal value or a <field>Env holding the name of an environment variable — never the secret value itself. Declare neither and resolution fails, naming the missing field.
  2. Declaring both a literal and its Env counterpart 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.
  3. apiKey and secretKey never inherit from the top-level fields of funifier.json; only serverUrl does, in the chain instance → top of funifier.jsonFUNIFIER_SERVER_URL. An alias missing apiKey or secretKey fails naming the field, instead of quietly falling back to the top-level credential and running against the wrong instance.
  4. repo (optional) resolves relative to the directory of funifier.json, not the process cwd. A server launched by a desktop app has an unpredictable cwd, 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 one

Restore 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_KEY in plain text, because the generated configs carry it inline — and now in duplicate, since restore-setup snapshots 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:

/funifier

Codex 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-mcp
import { 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


License

MIT