Paigy

io.github.paigy-ai由 GitHub 账号 paigy-ai 发布v0.40.42更新于 Nov 3, 2026

Lets your AI agents call you when they need a decision, and hear your answer.

已验证STDIO仅桌面效率与工作流沟通与协作

概览

AI 生成的概览

Paigy 是给 AI 智能体用的语音收件箱:智能体需要你决策时,可通过短信、推送、横幅或真实电话联系你,并收到你的回答。

可以做什么
  • 配置并配对智能体身份,查看监听与唤醒状态,阅读内置帮助
  • 向本人提问(确认、单选、多选、排序),发送进展与完成通知,撤回问题
  • 创建、指派、延后、完成和整理目标,并读取目标的对话与历史
  • 完整读取一次投递,包括通话状态、结果以及可选的通话记录
  • 跨该用户所有智能体搜索历史,并查看最近 24 小时活跃的智能体
  • 就 Paigy 本身向 Paigy 团队发送缺陷报告或建议
适用场景
适用于长时间运行或会阻塞的智能体会话,避免你一直盯着终端,或回来发现任务早已卡在一个问题上。适合希望智能体在需要决策的那一刻通过手机联系你、并让你用语音或文字回复的人。
运行要求
以本地 stdio 进程运行,通常通过 npx 使用 @paigy/mcp 包,也可经 Homebrew、Claude Code 插件、Claude Desktop 打包文件或 Codex 插件安装。需要配对手机,可用 onboard 命令或配对提示完成;原生 iOS 应用才能实现来电式响铃。未声明任何 API 密钥或环境变量。
安装前请注意
配对会把你的手机和账号与智能体关联;服务器可发起真实响铃电话并发送推送或锁屏通知,因此紧急级别与账号上限需要留意。智能体可创建、修改和关闭目标,并向你以及 Paigy 团队发送消息。反馈只发给 Paigy,不会发给你。较小的本地模型在选择回答形式时可能不够稳定。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Paigy,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

Paigy — MCP server

A voice inbox for your AI agents. When an agent needs your input — mid-task, blocked, or done with something long-running — it can place an actual phone call and read the question aloud, text, push, or ring your phone with a banner, so you can reply by voice instead of babysitting a terminal.

Without Paigy, a long agent session means one of two bad options: sit and watch the terminal so you don't miss the moment it needs you, or walk away and come back to a task that stalled an hour ago waiting on a question you never saw. Paigy closes that gap — the moment your agent actually needs a decision, your phone gets pulled into the loop with the level of urgency that matches the moment (a silent inbox card, a quiet push, a banner, or a real ringing call), so you find out immediately instead of on your next check-in. Answer by voice or text and the reply lands back with the agent exactly like any other tool response, so it just continues — no copy-pasting, no reopening the terminal. It also pairs with the native Paigy iOS app, so a call rings through like a real phone call (CallKit) even when your phone is locked, and you can glance at or reply to anything from the lock screen.

Works with

A standard MCP server (stdio, TypeScript) — no client-specific code anywhere, verified over the raw protocol against a non-Claude client identity.

  • Claude Code (this repo is also the plugin + marketplace for it)
  • Codex CLI
  • Gemini CLI
  • Any other MCP client via standard config: Cline, Continue.dev, Zed, Cursor, Goose, mcphost — including local-model setups over Ollama, LM Studio, or llama.cpp

(The app + backend live in a separate repo.)

Install

One line, any terminal — detects your agents (Claude Code, Codex, Antigravity), wires Paigy into each, and pairs your phone once. Prints every command before running it; --dry-run shows the plan:

curl -fsSL https://paigy.ai/install | sh

Prefer to do it by hand? Pick your client below.

Homebrew (macOS and Linux):

brew tap paigy-ai/mcp https://github.com/paigy-ai/mcpbrew trust paigy-ai/mcpbrew install paigy

(brew trust is how current Homebrew opts in to a tap outside homebrew-core.) Installs the server and its commands (paigy-mcp, paigy-listen, paigy-mcp-onboard, ...). Point your MCP client at paigy-mcp, then run paigy-mcp-onboard once to pair your phone.

Claude Code (plugin — easiest path on Claude):

/plugin marketplace add paigy-ai/mcp/plugin install paigy

Connects automatically; the first time an agent uses it while unpaired, it'll prompt you to pair — run /paigy-onboard (opens your browser to approve).

Claude Desktop (MCPB bundle — no terminal needed): download paigy.mcpb, then in Claude Desktop open Settings → Extensions and drag the file in (or double-click it). Ask Claude to "pair with Paigy" — it runs pairing itself and shows a code to approve on your phone. Also on Smithery.

Codex CLI:

codex plugin marketplace add paigy-ai/mcp --ref maincodex plugin add paigy@paigy-ainpx -y -p @paigy/mcp@latest paigy-mcp-onboard

The plugin configures the Paigy MCP server and includes guidance for calls, replies, and callbacks. Start a new Codex session after installation.

Codex CLI — direct MCP fallback:

codex mcp add paigy -- npx -y @paigy/mcp@latest

Then forward Codex's thread id into the server, so each Codex conversation gets its own Paigy identity — Codex builds the MCP server's environment from a fixed allow-list, so a variable it isn't told to pass never reaches us. Add this line under [mcp_servers.paigy] in ~/.codex/config.toml (paigy-harness setup does it for you):

toml
env_vars = ["CODEX_THREAD_ID", "CODEX_SESSION_ID"]

(Don't pass it as a -c override on mcp add — that lands before the block is written and Codex rejects the half-table with "invalid transport", writing nothing.)

Gemini CLI:

gemini mcp add -s user paigy npx -y @paigy/mcp@latest

Any other MCP client (Cline, Continue.dev, Zed, Cursor, or a CLI that takes the standard MCP JSON config directly) — most GUI clients take this in their MCP settings (Cline: cline_mcp_settings.json; Continue: ~/.continue/config.json):

json
{  "mcpServers": {    "paigy": {      "command": "npx",      "args": ["-y", "@paigy/mcp@latest"]    }  }}

Then pair your phone:

npx -y -p @paigy/mcp@latest paigy-mcp-onboard

Each session hatches its own identity automatically the first time it reaches Paigy — no agent name to set or match. (Set PAIGY_AGENT=<name> only if you deliberately want a client to always speak as one fixed named identity; then run onboard with the same name.) Approve on your phone, then sign in at paigy.ai to start receiving messages.

Heads-up for smaller/local models: the tool descriptions ask the agent to pick between a few answer shapes (confirm, options, free text) based on context — Claude follows this reliably; smaller local models may be less consistent about it. Free text always works as a fallback.

Choosing how the user answers

notify_user should ask in the shape that's fastest to answer — don't leave a decision as free text. Pick with select (and options):

You need…UseAnswer comes back as
Yes/No or Approve/Denyselect:"confirm" (confirmStyle:"approve" for Approve/Deny){kind:"confirm", approved}
Pick one of severaloptions + select:"one"{kind:"option", optionId}
Pick severaloptions + select:"many"{kind:"multi", optionIds}
Rank / order a subsetoptions + select:"rank"{kind:"ranked", optionIds}
A visual choiceoptions with an html or image previewone of the above
An open-ended replyno options{kind:"text", text}

confirm is answerable straight from the banner (Yes/No or Approve/Deny buttons). Other paiges get banner actions See Options · Hear them · Remind me later.

urgency is a request, not a guarantee — the user's account settings can cap it lower. Four levels, low to high: "inbox" (silent, sits in the inbox), "push" (a quiet passive notification, no sound), "banner" (a time-sensitive lock-screen banner with sound), "call" (rings the phone — use only when you genuinely need the user in the moment).

If you're about to start something long-running or blocking — the kind of thing where the user would otherwise sit and wait on you — mention once, in passing, that you can text or call them when it's done or if you hit a blocker. Don't offer it for quick tasks, and don't repeat the offer once they've answered.

Stalled work (automatic, no setup)

When a session stops and its agent owns Paigy Goals with no progress for three days, a Stop hook holds the stop once a day and lists them, so the agent updates, finishes or cancels each before it goes quiet. It runs paigy-stalled from @paigy/mcp (0.40.15 or later) and is silent otherwise: nothing stalled, a stop already being continued by a hook, a reminder already given that day, or any error. One script, the same hook in each harness's plugin:

  • Claude Code — hooks/hooks.json, wired by the plugin; nothing to set up.
  • Codex CLI — plugins/paigy/hooks/hooks.json, wired by the Codex plugin. Codex runs a plugin's hooks only after you trust them: review and trust the Paigy hook when Codex asks.
  • Any other harness with a Claude-style Stop hook — register npx -y -p @paigy/mcp@latest paigy-stalled as the Stop command. It reads the hook's JSON (session_id, stop_hook_active) on stdin and prints {"decision":"block","reason":…}.

Hosts with no hooks still get the list: check_replies (which the server's instructions tell every agent to call on startup and after a wake) returns it under stalled, and paigy-listen carries it in the work it hands a session it wakes.

License

MIT

来源:README.md,提交 b0c96fb

工具

10

configure

Set this agent up with Paigy — call it FIRST, before contact, and any time you're unsure who you are. One call does whatever the situation needs: NOT SET UP → if this machine holds a device credential (the user ran the Paigy desktop app or harness) it hatches an identity INSTANTLY, no code and no approval; otherwise it starts the code ceremony. ALREADY SET UP → returns your current identity and the two things left to decide, renaming it or logging out. TOKEN NO LONGER VALID → says so, then re-pairs. Pass { name, voice } to choose who you are when hatching, or to RENAME yourself when already set up (pick your own; voices: rachel, george, jessica, brian, lily). Safe to call any time: idempotent, and it never writes settings. THE CODE CEREMONY does not open a browser; the user enters the code in the Paigy app (or scans `qr`). A result with { user_code, device_code, qr, user_message } has already started polling for approval in the background: you MUST immediately print the `user_message` (the bare code) to the user, AND in that same turn call configure again with that `device_code` to collect the result. It returns the moment the user approves; on { status:'pending' } call again to keep waiting; on { status:'awaiting_confirmation' } (E2EE) show the bare `user_message` verify code and call again to finish. Every result's first text block states the code plainly. On { status:'paired' }, or whenever it returns `enable_command`, ALWAYS follow the `enable_prompt`: PRINT that command for the user to run, so Paigy's tools stop prompting each time. You cannot apply it yourself (it writes your own permission allowlist, which hosts block as privilege escalation), so print it, don't wait for it, and carry on. LOG OUT with { logOut: true }: it logs out THIS agent only — its token is revoked server-side and its local entry removed. Other agents and this device's credential are untouched, and a later configure re-hatches instantly while the device credential exists. Disconnecting

输入参数namescopevoicelogOutdevice_code

contact

Send to and receive from the person: completions, updates, questions, answers to questions addressed to you, withdrawals, and what a question holds up. Every Goal named must exist: an unknown one refuses the whole contact. Each item applies on its own: read `results`, where a failed one names why. HOW TO ASK: 1. One question per object in `questions`, so each is answered on its own. 2. `goalId` names the existing Goal it is about (create one with manage_goals first); the answer comes back there. 3. `workItBlocks` only when you are truly blocked: it asks for a call. 4. No while-loops. While any Call is open, even one your question joined from their items, keep receiving through empty windows; otherwise stop at one: the answer reaches you on the Goal. Yield only with a listener or wakeup. 5. One question, one row: never re-send one still waiting; take back one that no longer matters with `withdrawQuestionIds`. 6. Read the Goal before asking; never re-ask what was answered or shipped. `replied` means they chose no option: it is still yours to settle. 7. Give options when you have them. Each label names its choice in full (never "Option 2"); never add "Other". `pickMode`: one (default), many, rank. 8. A diagnosis says when, why and how it happens, then proposes one fix. 9. Give a report its `reply`: one line in THEIR voice for THAT report, so you learn whether they verified it or only received it. Required when it is delivered or its Goal is done. LENGTH: the question, message or answer is the one point, at most 80 characters; the rest goes in `units`, one idea each. Over a cap is refused by name and nothing is sent. Several results are several updates. UPDATES ask nothing. One reaches the person only when they asked for it, it answers something they said, or its Goal is done; else it is kept as progress. One that reaches them joins an open report card or a live call. RECEIVING: contact({}) waits ~45 s; contact({wait:false}) returns `events` at once. Confirm the one

输入参数waitanswersupdatesquestionsackEventIdscompletionsbumpQuestionIdswithdrawQuestionIdsquestionDependencies

manage_goals

Create, edit, assign, organize or close work. Every change here changes Goals; answering, withdrawing or asking Questions stays in contact. Each change applies independently: a refused one names why (`results[i].error`, e.g. goal_revision_conflict, goal_children_open, goal_not_found) and the rest still apply, so read every result: a partial result is never a complete success. Kinds: complete (goalId, message capped at 50 characters, units, reply, optional next-step options {label, hint}) closes and reports atomically, exactly as contact.completions; create (title, outcome, ownerId, parentGoalId, sourceEntryIds) returns the new Goal's id in `results[i].goalId`, in the order requested, to use in later calls (an outcome is one paragraph, at most 500 characters: split more into child Goals with parentGoalId); edit (title and/or outcome); state (open, completed, canceled); assign (ownerId); defer (until: the Goal waits until then and its owner is woken when it passes; null takes it back); move (parentGoalId, or null for a root: only this Goal moves); dependency (add or remove: goalId waits on dependsOnGoalId to start or to complete). A Goal cannot be completed while its required children or dependencies remain open: finish or move them first. Finishing the children does not prove the parent's own work is done. An edit applies at the version you last read: if someone changed the Goal since, it is refused as goal_revision_conflict, so read it again (get_goals) and reconsider. You may change any Goal of your person; a change puts you on it. Returns `ok` (every change applied), `results` per change (applied or failed), and `goals`, each changed Goal's id, state, title, outcome and revision.

输入参数changes必填

get_delivery

Read a Delivery in full: its whole ask, units, options and answers, plus current callState and callOutcome for a Call. For a Call, transcript: true adds what was said: each spoken line in order, who said it, and when from pickup, a page at a time. A line from the room, not the person, is marked room. Any agent of the same account may read it; another account is not disclosed. Reading never acknowledges or resends anything. Use this after a call or when receive names a Call you are waiting on.

输入参数afterdeliveryId必填transcript

get_goals

Read one to ten Goals by goalIds, returned in the same order under goals (a read never puts you on them). history applies to every requested Goal. A refused read fails the call with its original refusal; no partial result is presented as complete. Each Goal includes its ten most recent other contributors (names, latest entry headlines and times), outcome, state, revision, progress, blockers, the conversation on it (each question with its options and what was decided), `next`, the one step to take, and `more`, where to read further. A question in that conversation reads `open` (nothing yet), `answered` (a choice was made, and `answer` carries it), `replied` (they said something and the read settled the question on their words — NO option of yours was chosen, and the words are the reply line beside it, so read that before you act), or `closed`. The conversation carries everything the person said, every open question and your newest entry; your older entries are left out and counted — history: true reads every entry in full. Every Goal of your person is readable, whichever of their agents owns it; another account's Goals are not disclosed.

输入参数goalIds必填history

check_activity

Read your person's agents that contributed in the last 24 hours, newest first: at most 30 agents and their five most recently touched Goals, with their latest entry headline and time. Use get_goals to read a Goal and its other contributors before starting overlapping work. Read-only; no arguments.

无需输入参数。

send_feedback

Send feedback about Paigy itself (a bug report, an idea) straight to the Paigy team. Send it only when the person asked you to, or agreed when you offered: it goes to Paigy, never to the person, and nobody answers it here. Not for your work or a question for the person: use contact for those. Returns whether it was stored.

输入参数kindtext必填title

help

Start here: how to use Paigy, in full — pairing, listening, receiving, asking, updates and completions, Goals and calls. Pass a topic for one section. Read-only; needs no setup.

输入参数topic

listen

Am I listening for answers, and can Paigy resume this session? Takes no arguments. Returns status `listening` for harness delivery or a running listener with a ready wake adapter; `receiving` means a process is running but automatic resume is not confirmed (read its wake error or watch its output); `unpaired` means call configure; `start` gives the exact command to run NOW with your harness's Monitor tool (not a background command, which speaks only when it exits). Start it once. Codex queues into CODEX_THREAD_ID automatically when its CLI supports queue; PAIGY_ON_WAKE overrides it. A successful queue is not evidence the agent handled the answer: receive with contact({ wait: false }) and read the relevant Goal, then respond with contact. This tool never subscribes or starts anything itself.

无需输入参数。

版本历史

1
  1. v0.40.42最新Oct 29, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分