PassNinja

io.github.flomio由 GitHub 帳號 flomio 發布v0.4.0更新於 Oct 24, 2026

Issue and manage Apple Wallet & Google Wallet passes from any MCP-aware AI client.

已驗證STDIO僅桌面效率與工作流商業與電商

概覽

AI 產生的概覽

PassNinja 讓助理透過 PassNinja API 簽發與管理 Apple Wallet 和 Google Wallet 票卡,以及票卡範本、Webhook 和掃描事件讀取器。

可以做什麼
列出、檢視、建立、更新與刪除票卡範本,包含必填欄位與讀取器設定(範本建立與刪除僅限企業版)。簽發、列出、讀取、更新、刪除與解密單張票卡,並取得票卡原始資料。管理 Webhook:建立、列出、檢視、刪除並讀取投遞結果。管理掃描事件應用程式與讀取器,包含讀取器權杖與合併後的讀取器設定。透過 whoami 工具查看目前憑證與帳戶。
適用情境
適合在聊天用戶端直接操作 PassNinja 錢包票卡流程,例如列出範本、統計每個範本已安裝的票卡數量,或為指定電子郵件簽發票卡,不必切換到命令列或主控台。
執行需求
以 stdio 本機程序執行,可安裝為桌面 .mcpb 套件(macOS、Linux amd64、Windows amd64),也可由任何 MCP 用戶端啟動 passninja mcp 指令。需要 PassNinja API key 與 account ID,可透過安裝對話框、PASSNINJA_API_KEY 與 PASSNINJA_ACCOUNT_ID 環境變數、命令列參數或已儲存的驗證檔案提供。需要連線至 PassNinja API 的網路存取。
安裝前請注意
會保存帳戶憑證:API key 與 account ID 存放在本機驗證檔案或環境變數中。許多工具會寫入或刪除資料,包括建立與刪除票卡、範本、Webhook、應用程式與讀取器。範本與 Webhook 操作僅限企業版,掃描事件功能為付費版,受方案限制。讀取器權杖與 Webhook bearer 權杖僅在建立時顯示一次。讀取器主機應使用讀取器權杖而非帳戶 API key。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 PassNinja,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

passninja

Command-line interface for the PassNinja REST API. Wraps /v1/pass_templates, /v1/passes, and /v1/webhooks so you can manage Apple Wallet and Google Wallet passes from the shell.

Install

macOS / Linux (Homebrew)

sh
brew tap flomio/passninjabrew install passninja

Windows (PowerShell)

powershell
irm https://github.com/flomio/passninja-cli/releases/latest/download/install.ps1 | iex

From cmd.exe:

cmd
powershell -ExecutionPolicy Bypass -Command "irm https://github.com/flomio/passninja-cli/releases/latest/download/install.ps1 | iex"

The script detects your CPU (amd64, arm64, or 386), downloads the matching binary from the latest GitHub release, verifies its SHA256, drops it in %LOCALAPPDATA%\Programs\passninja\, and adds that directory to your user PATH. No admin needed; re-running upgrades in place.

Pin a specific version, or override the install directory:

powershell
$env:PASSNINJA_VERSION = 'v1.2.3'$env:PASSNINJA_INSTALL_DIR = 'C:\tools\passninja'irm https://github.com/flomio/passninja-cli/releases/latest/download/install.ps1 | iex

Windows (Scoop)

If you already use Scoop:

powershell
scoop bucket add flomio https://github.com/flomio/scoop-passninjascoop install passninja

Claude Desktop (one-click .mcpb install)

For chat-driven pass workflows, install the PassNinja MCP server into Claude Desktop:

  1. Download passninja.mcpb from the latest release.

  2. Double-click the file. Claude Desktop opens an install dialog showing the 31 tools the server exposes (pass templates, issued passes, webhooks, scan-event applications and readers).

  3. The dialog prompts for your API key and account ID — get them at https://www.passninja.com/settings → API key.

  4. Hit Install, restart Claude Desktop, then ask Claude things like:

    List my passninja pass templates and tell me how many passes are installed on each.

    Issue a new pass on ptk_0x002 for [email protected].

The bundled binary is code-signed with Apple Developer ID and notarized, so macOS Gatekeeper accepts it without prompts. Same .mcpb works on macOS (universal), Linux (amd64), and Windows (amd64).

The server is also listed in the official MCP Registry as io.github.flomio/passninja-cli, so any MCP client that consumes the registry can discover and install it automatically.

Authenticate

sh
passninja auth# Pastes your API key and account ID; verifies by hitting /v1/pass_templates# and saves credentials to ~/.passninja-auth.json (0600).

Or pass credentials via env / flags:

sh
export PASSNINJA_API_KEY=...        PASSNINJA_ACCOUNT_ID=aid_0x002passninja --api-key=... --account-id=... pass-template list

Flag > env > ~/.passninja-auth.json > ~/.passninja.yaml > defaults.

The same precedence applies to the MCP server: passninja mcp (started by Claude Desktop and other MCP clients) reads PASSNINJA_API_KEY / PASSNINJA_ACCOUNT_ID from its environment, falling back to the auth file.

Stdio MCP server

The CLI also doubles as a Model Context Protocol server. The .mcpb install above wires this into Claude Desktop, but you can hook it into any MCP client (Cursor, Cline, Zed, etc.) by configuring the client to launch:

passninja mcp

Tool surface (snake_case names mirror the CLI subcommands):

whoamipass_template_{list, get, required_fields, reader_config, create, delete}pass_{list, get, create, update, delete, raw, decrypt}webhook_{list, get, create, delete, results}

Each tool's input schema, destructive-hint annotations, and rich descriptions let the LLM self-discover correct usage without external documentation.

Commands

text
passninja auth                                       Save API credentialspassninja whoami                                     Show the active credential / accountpassninja version
passninja pass-template listpassninja pass-template get <ptk_0x...>passninja pass-template required-fields <ptk_0x...>passninja pass-template reader-config <ptk_0x...>          # NFC reader config (merchant id, collector, EC keys)passninja pass-template create --name --platform --style [config flags]   # enterprise onlypassninja pass-template update <ptk_0x...> [--name --set --remap --show/--hide --require/--optional] [config flags] [--replace]   # enterprise onlypassninja pass-template delete <ptk_0x...> [--yes]          # enterprise only#   config flags (create + update): --constrain-device/-browser/-ip,#   --disable-apple-sharing/-google-sharing, --auto-recharge --balance-trigger --top-up-target
passninja pass create <ptk_0x...> [--field k=v | --data @file.json | --data '<json>']passninja pass list <ptk_0x...>passninja pass get <ptk_0x...> <pass_id>passninja pass raw <ptk_0x...> <pass_id>passninja pass update <ptk_0x...> <pass_id> [--field k=v | --data ... | --replace]passninja pass delete <ptk_0x...> <pass_id> [--yes]passninja pass decrypt <ptk_0x...> [--payload <hex> | --payload-file <path> | <stdin>] [--platform apple]#   Google Smart Tap is session-bound — use `reader serve` on the reader host
# Enterprise only:passninja webhook create --name --url --event <type> [--event <type> ...] [--pass-template ptk_0x...]passninja webhook list [--page --per-page --pass-template]passninja webhook get <webhook_id>passninja webhook delete <webhook_id> [--yes]passninja webhook results <webhook_id> [--page --per-page]
# Scan event system (premium):passninja application listpassninja application get <app_0x...>passninja application create --name --pass-template ptk_0x... [--kind log|validate|forward]                             [--rescan-window <seconds>] [--endpoint-url <https>] [--bearer-token <secret>]                             [--timeout-ms <100-8000>] [--on-endpoint-error accept|reject] [--description]passninja application update <app_0x...> [--name --description --kind --rescan-window --endpoint-url                             --bearer-token --timeout-ms --on-endpoint-error --active/--inactive]passninja application delete <app_0x...> [--yes]
passninja reader listpassninja reader get <reader_id>passninja reader create --name --location --application app_0x... [--application ...]   # prints the token oncepassninja reader update <reader_id> [--name --location --status active|revoked --application ...]passninja reader rotate-token <reader_id> [--yes]passninja reader delete <reader_id> [--yes]passninja reader config <reader_id>                        # merged reader config across bound templatespassninja reader serve --token rdr_... [--pcsc [--pcsc-reader <name>] | --listen host:port]                       [--platform apple|google] [--heartbeat 5m | --no-heartbeat]                       [--serial --manufacturer --model --firmware --source]                       [--on-accept '<cmd>'] [--on-reject '<cmd>']

Output formats

FlagMode
--jsonPretty-printed JSON
--plaintextTab-separated, no decoration (good for piping to awk)
defaultBordered ASCII table

Set a session-wide default via ~/.passninja.yaml:

yaml
default_output: json    # one of: table | json | plaintextbase_url: https://api.passninja.com/v1

Webhook events

The CloudEvents 1.0 type taxonomy emitted by passninja-site:

Event typeWhen it fires
pn.pass.installedFirst device installs an issued pass
pn.pass.updatedPass fields change via PATCH/PUT
pn.pass.uninstalledLast device removes the pass
pn.pass.scannedA reader records a scan event (carries scanId, readerSerial, result)

Reserved for future use: pn.pass.issued, pn.pass.deleted, pn.pass_template.created, pn.pass_template.updated, pn.pass_template.deleted.

Running a reader host

Cloud-connected readers (VTAP Cloud, Famoco Tap&Go) post scans to PassNinja themselves. A simple reader — Reyax RYRR30D, ACS WalletMate, Elatec TWN4 — has no cloud connection of its own, so reader serve supplies one: it takes the values the reader captures, submits them as scan events, and applies the LED/beep instruction the server returns.

Setup is three steps, and only the last one runs on the reader host:

sh
# 1. an application decides what a scan means for one pass templatepassninja application create --name "Front gate" --kind validate \  --pass-template ptk_0x216 --rescan-window 14400
# 2. a reader binds to it; the token is printed once — save itpassninja reader create --name "Front gate" --location "Gate 2" \  --application app_0x1
# 3. on the reader host (a Raspberry Pi, a kiosk PC, …)passninja reader serve --token rdr_... --pcsc         # attached PC/SC readermy-reader-daemon | passninja reader serve --token rdr_...   # or any daemon

serve authenticates as that one reader with its bearer token — a reader host never needs, and should never hold, your account API key.

Tap values arrive from one of three sources:

  • --pcsc drives an attached PC/SC contactless reader (ACS WalletMate / WalletMate II, incl. the Mini module) directly — no separate daemon. The host runs the wallet flows itself: on an Apple tap it captures the VAS cryptogram; on an Android tap it has the server pre-sign the Smart Tap session mid-tap (the collector key never leaves PassNinja), negotiates the secure channel, and captures the encrypted bundle. Both are submitted for server-side decryption — the host holds no key material. First-generation WalletMates ship with RF polling disabled; serve enables it automatically when the vendor CCID driver is installed. Needs a native (cgo) build on macOS/Linux — go install and Homebrew builds qualify.
  • stdin (one value per line) — pipe any reader daemon's output in.
  • --listen 127.0.0.1:8080 — a loopback HTTP endpoint a driver POSTs to.

For stdin/HTTP, a value that looks like raw captured APDUs is forwarded for server-side decryption; anything else is treated as an already-decrypted pass serial.

Each result is one JSON object on stdout:

json
{"scanId":"9f8e7d6c-…","result":"accepted","pass":{"passTemplate":"ptk_0x216","passId":"fee4a257185906b92a"}, "readerInstructions":{"success":true,"led":"green","beep":true,"message":"Accepted"}}

To drive a physical LED, use the outcome hooks — they receive $PN_RESULT, $PN_LED, $PN_MESSAGE, $PN_PASS, $PN_SCAN_ID, and — when a forward application answered — $PN_FORWARD_BODY (the endpoint's JSON reply). On a forward application, $PN_MESSAGE is the endpoint's message verbatim and the printed scan JSON carries the reply under forwardResponse:

sh
passninja reader serve --token rdr_... \  --on-accept 'gpioset 0 17=1' --on-reject 'gpioset 0 27=1'

Heartbeats (default every 5m) report liveness plus the hardware identity you pass with --serial / --manufacturer / --model / --firmware, which is what fills in the reader's Hardware panel in the dashboard. Readers whose vendor MDM already tracks them should use --no-heartbeat.

passninja webhook create returns the bearer token once on creation. Save it — it will not be shown again.

Build from source

sh
git clone https://github.com/flomio/passninja-cli.gitcd passninja-climake build                 # writes dist/passninja./dist/passninja versionmake install               # installs to $GOPATH/bin

Release flow

Tag-driven. Push a vX.Y.Z tag on master; the GitHub Actions workflow at .github/workflows/release.yml matrix-builds darwin/linux × arm64/amd64, packages a code-signed + Apple-notarized passninja.mcpb on a macOS runner, publishes both the binaries and the .mcpb on the GitHub Release, and opens a PR against flomio/homebrew-passninja bumping the formula url and sha256.

Apple credentials live in repo secrets (APPLE_TEAM_ID, APPLE_API_KEY_ID, APPLE_API_ISSUER_ID, APPLE_SIGN_IDENTITY, APPLE_CERTIFICATE_PASSWORD, plus the base64-encoded APPLE_API_KEY_P8 and APPLE_CERTIFICATE_P12).

After each tagged release, the MCP Registry entry needs a refresh. Bump packages[0].identifier, packages[0].version, packages[0].fileSha256, and the top-level version in server.json to match the new release, then:

sh
mcp-publisher login github      # one-time per machinemcp-publisher publish

來源:README.md,提交 026b860

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.4.0最新Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分