Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Twin Slack

БесплатноПоддерживается

Deterministic Slack Web API twin for agent testing — REST + MCP, SQLite-backed state.

GitHubEmbed

Описание

Deterministic Slack Web API twin for agent testing — REST + MCP, SQLite-backed state.

README

Pome

Pome Digital Twins

Test mode for your integrations, built for the way agents build.

CI npm node License

Documentation · Pome · CLI reference

Pome gives you local, stateful twins of GitHub, Slack, Stripe, Gmail and Linear. Your agent, or your own code, calls a twin the way it calls the real API, over REST or MCP. There is no test account, no OAuth app and no API key. Every request lands on a tape: the twin's own record of every call and what it changed. A step the agent only claimed appears on the tape as a step that did not happen. Stripe has a test mode. GitHub and Slack do not, and none of them hands you the tape.

How Pome works: start a twin, connect your agent, let it act, read the tape, then swap to the real API.

One command

You need Node.js 24 or newer. The twins run on Node's built-in SQLite.

npx @pome-sh/cli@latest twin start github

It prints:

Pome github twin listening at http://127.0.0.1:3333/s/standalone
Seed: the github twin's default (pass --seed <path>, or write one with `pome twin new-seed github`).
POME_GITHUB_REST_URL=http://127.0.0.1:3333/s/standalone
POME_GITHUB_MCP_URL=http://127.0.0.1:3333/s/standalone/mcp
POME_AUTH_TOKEN=eyJ…
Health check (no auth): curl http://127.0.0.1:3333/healthz

Connect your agent (pick one):

Claude Code:
  claude mcp add --transport http pome-github http://127.0.0.1:3333/s/standalone/mcp --header "Authorization: Bearer eyJ…"

Codex, .mcp.json and the SDK line below read the token from your shell. Export it once:
  export POME_GITHUB_REST_URL=http://127.0.0.1:3333/s/standalone POME_GITHUB_MCP_URL=http://127.0.0.1:3333/s/standalone/mcp POME_AUTH_TOKEN=eyJ…

Codex (append to ~/.codex/config.toml):
  [mcp_servers.pome-github]
  url = "http://127.0.0.1:3333/s/standalone/mcp"
  bearer_token_env_var = "POME_AUTH_TOKEN"
…

The output continues with a .mcp.json stanza and the line for the vendor's own SDK. The twin mints the token when it starts. It is not an account credential. The twin listens on port 3333, and --port picks another. It serves everything under /s/standalone, the one session a standalone twin has.

The twin starts with one repository, acme/api, and one open issue, so your agent has something to act on before you write a seed. State lives in the twin's process and is gone when you stop it. --seed decides where it starts. The twin also writes these values to .pome/twin-status.json in the folder you ran it from, readable only by you. .pome/ git-ignores itself.

Several twins at once is one command: twin start github slack linear. Each twin takes its own port. One connect block covers all of them. .pome/twin-status.json lists them under twins, and its top-level fields describe the twin you started last.

Connect your agent

Paste the block for your client, exactly as printed. Claude Code takes the one-liner. Codex takes the table. Any client that reads .mcp.json takes the stanza. The stanza reads the token from POME_AUTH_TOKEN in your shell, so run the printed export line first. Your own code takes the SDK line. GitHub's Octokit, Slack's WebClient, Stripe's client, googleapis for Gmail and Linear's SDK each get their own. The connect guide covers Cursor and the other clients.

If your client already has a real GitHub MCP server, the twin registers under its own name, pome-github. Disable the real one while you test. Otherwise the agent picks whichever it likes.

Then ask the agent for something small: "Open an issue in acme/api for the login page returning 500 after the deploy."

See what it actually did

npx @pome-sh/cli@latest twin tape --diff
github twin at http://127.0.0.1:3333/s/standalone — 3 requests

TIME          REQUEST            STATUS  FIDELITY  STATE
19:04:49.743  list_issues        200     semantic  read
19:04:53.762  create_issue       200     semantic  changed
19:05:00.780  add_issue_comment  404     semantic  no change  ← write did not land (404); error: Issue not found

3 requests: 1 changed state · 1 write did not land · 1 read

State diff since boot (seed → now):
  repositories                   ~1 changed: acme/api
  repositories[acme/api].issues  +1 added: #2

One line per request, REST or MCP. A call through Octokit shows as POST /repos/acme/api/issues. In the STATE column, changed means the write landed in the twin's state, and no change on a write is a step that did not happen. In the FIDELITY column, unsupported is a route the twin does not model, answered with 501 rather than a guess.

Here the agent listed the issues, created #2, then commented on issue #17, which does not exist. An agent that reports "commented" after that is what the tape is for. The diff is what the run left behind, measured against the state the twin booted with. --json prints the same as one object.

Run it in CI

The same command works in a GitHub Actions job. The job below starts the twin, waits for it, hands its address and token to your tests, and prints the tape at the end. Pin the version you tested. The CLI is pre-1.0 and @latest moves.

- uses: actions/setup-node@v4
  with:
    node-version: 24
- name: Start the GitHub twin
  run: |
    npx @pome-sh/[email protected] twin start github > twin.log 2>&1 &
    for i in $(seq 1 60); do curl -fsS http://127.0.0.1:3333/healthz >/dev/null 2>&1 && break; sleep 1; done
    echo "POME_GITHUB_REST_URL=$(jq -r .rest_url .pome/twin-status.json)" >> "$GITHUB_ENV"
    echo "POME_GITHUB_MCP_URL=$(jq -r .mcp_url .pome/twin-status.json)" >> "$GITHUB_ENV"
    echo "POME_AUTH_TOKEN=$(jq -r .auth_token .pome/twin-status.json)" >> "$GITHUB_ENV"
- run: npm test
- name: What the tests did
  if: always()
  run: npx @pome-sh/[email protected] twin tape --diff

The twin from the first step keeps running for the rest of the job. This repository's own CI starts its twins the same way. twin tape finds the twin through .pome/twin-status.json. There is no account and no secret in the repository: the twin mints the token on the runner, and the token dies with the twin. Your tests read POME_GITHUB_REST_URL and POME_AUTH_TOKEN the way they would read a real base URL and token.

Supported twins

Pome includes 5 digital twins and 115 MCP tools. Each twin publishes a route-by-route fidelity record. Every day Pome replays the same requests against the real vendor API, with its own accounts, and publishes the result per route at status.pome.sh.

Twin MCP tools Main API coverage Details
GitHub 36 Repositories, issues, pull requests, reviews, and merges Fidelity
Stripe 26 PaymentIntents, refunds, charges, balances, events, and x402 payments Fidelity
Slack 18 Channels, messages, threads, reactions, and search Fidelity
Gmail 13 Messages, drafts, threads, labels, and uploads Fidelity
Linear 22 GraphQL, OAuth with PKCE, and webhook registration Fidelity

Each route has one of these fidelity levels:

  • semantic: The route implements and tests provider behavior.
  • shape: The response has the provider's shape.
  • unsupported: The twin returns 501.

The twins answer requests. They do not call your app. No twin delivers webhooks today. Stripe's twin exposes /v1/events to poll. Linear's twin records webhook registrations and does not deliver them. A flow that starts from a vendor event needs you to post that event to your app yourself.

Swap to the real API

Three things change, and nothing else in your code should:

  1. The base URL. POME_GITHUB_REST_URL becomes https://api.github.com. The MCP URL becomes the vendor's own MCP server, or yours.
  2. The credential. The twin's bearer becomes a real token with real scopes.
  3. Vendor-side setup the twin never asked for: OAuth apps, app installation, webhook registration. Gmail needs a Google OAuth client. The twin does not.

A green run on a twin says your integration behaves against the API as far as the fidelity record covers it. It does not say the vendor will behave the same tomorrow. Run one smoke test against the real API after the swap.

Why not mocks, why not Emulate

Hand-written mocks Vercel Emulate Pome twins
State that persists across calls Whatever you wrote by hand Yes Yes
A tape of every request your code made Only if you wrote one No Yes
Fidelity measured against the vendor and published No No Yes, daily
MCP surface for agents No No Yes, 115 tools

The Emulate column comes from its README as of 2026-09-16. Emulate targets application code in a dev loop, and it is Apache-2.0 like this repo.

Going further

pome below is the same CLI. npm install -g @pome-sh/cli puts it on your PATH, or keep using npx @pome-sh/cli@latest. Everything above runs locally with no account. Hosted grading is optional. Nothing leaves your machine unless you use it, apart from the daily usage event (see Telemetry).

  • Your own world: pome twin new-seed github --out seed.json, edit it, then pome twin start github --seed seed.json. Several twins from one file: pome twin new-seed github slack --out seed.json, then pome twin start github slack --seed seed.json. See the local twin guide.
  • Graded tasks, locally: npx @pome-sh/cli@latest init scaffolds a project. pome run --local tasks/01-bug-happy-path.md records a run. pome inspect latest reads it. A local run records evidence and does not score.
  • Scoring: pome login, then pome run tasks/01-bug-happy-path.md records and grades in one hosted workflow. Or score a local tape with Braintrust or LangSmith, see integration-examples/.

Examples

  • agent-examples/ contains complete agents and graded tasks.
  • integration-examples/ connects Pome to Braintrust and LangSmith.
  • showcases/ demonstrates individual twin behaviors without an agent or grading.
  • skills/ contains skills that help coding agents author and run Pome tasks.

Repository layout

@pome-sh/cli contains the CLI and the twin runtimes. Users do not install the twin packages separately.

The shared runtime provides HTTP routing, bearer authentication, MCP dispatch, recording, and SQLite state. Each twin adds its provider-specific domain behavior.

See packages/README.md for the package map. See CONTRACT.md for the twin runtime contract.

Contributions are welcome, and the easiest first ones are seeds and showcases. CONTRIBUTING.md says where to start and what a pull request needs. A new twin is a package that satisfies the runtime contract in CONTRACT.md. A bug report is most useful with the tape attached (pome twin tape --json). A security problem goes to SECURITY.md, not to a public issue.

Telemetry

The CLI sends one anonymous usage event per day, at most. The event carries a random id, the CLI version, the OS, the Node major, and the command's name (twin start, init). The CLI mints the id once and keeps it in ~/.pome/telemetry.json. The event never carries an argument, a path, a repo name, a seed, a token or anything from a tape. The first send prints a one-line notice.

Turn it off with POME_TELEMETRY=0. The CLI also honours DO_NOT_TRACK=1. It sends nothing when CI is set, and nothing from a build made without an ingest key. The code is cli/src/cli/usageTick.ts.

Status and license

Pome is in beta. CLI behavior and dependencies can change before version 1.0.

This repository uses the Apache-2.0 license.

from github.com/pome-sh/digital-twins

Установить Twin Slack в Claude Desktop, Claude Code, Cursor

Рекомендуется · одна команда, все IDE
unyly install twin-slack

Ставит в Claude Desktop, Claude Code, Cursor и VS Code — сам разбирается с npx, uvx и сборкой из исходников.

Впервые? Поставь CLI: curl -fsSL https://unyly.org/install | sh

Или настроить вручную

Выполни в терминале:

claude mcp add twin-slack --env ANTHROPIC_API_KEY="" --env TOKEN="" --env TWIN_AUTH_SECRET="" -- npx -y @pome-sh/twin-slack

Пошаговые гайды: как установить Twin Slack

FAQ

Twin Slack MCP бесплатный?

Да, Twin Slack MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Twin Slack?

Да, требуются переменные окружения: ANTHROPIC_API_KEY, TOKEN, TWIN_AUTH_SECRET. Unyly подставит их в конфиг при установке.

Twin Slack — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Twin Slack в Claude Desktop, Claude Code или Cursor?

Открой Twin Slack на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Изменения

Версии и запрашиваемые доступы со временем.

  • Новая версия опубликована
  • Новая версия опубликована
  • Новая версия опубликована
  • Новая версия опубликована
  • Новая версия опубликована

Похожие MCP

Compare Twin Slack with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории communication