Skip to main content

MCP management + inspector + monitoring CLI: discover, configure, run, inspect and monitor MCP servers across AI clients.

Project description

Tappy

One CLI to manage, inspect and monitor every MCP server you run.

Works across Claude Desktop, Claude Code, Cursor — and any client with an mcpServers config.

CI PyPI Python License: MIT

Install · Quick start · CLI reference · User Guide · Changelog


What is Tappy?

MCP servers are the plugins that give AI tools their real-world powers — filesystem access, GitHub, databases, web search, custom APIs. But each AI client stores its servers in its own JSON config file, in its own place, with no way to see whether a server actually works or what it exposes.

Tappy is the control panel for all of it — a fast, scriptable CLI that reads every client's config into one view and lets you:

  • see every server across every client at a glance,
  • edit them safely (with backups and validation, never raw JSON),
  • inspect them over the real MCP protocol — list their tools/resources/prompts and even call a tool to test it,
  • monitor their health and latency live (tappy status, tappy watch),
  • standardize a server set across a whole team.

Everything is a command, so it drops straight into scripts, dotfiles and CI — every data command supports --json and meaningful exit codes.

Why Tappy exists

Managing MCP servers today means:

  • Scattered configclaude_desktop_config.json, ~/.claude.json, .cursor/mcp.json… all different, all edited by hand.
  • No visibility — you can't tell which servers start, which are healthy, or what tools they expose without launching a client and hoping.
  • Risky edits — one stray comma silently breaks a server.
  • No team story — everyone configures their own servers slightly differently.
  • Security blind spots — a server can quietly change the tools it offers after you've trusted it ("rug-pull").

Tappy fixes each of these with one tool that speaks the MCP protocol and treats your config files with care.

Features

Configuration & discovery

  • Auto-discovers servers across Claude Desktop, Claude Code (user + project) and Cursor — plus any custom config path.
  • Normalized model — stdio, HTTP and SSE servers presented the same way.
  • One unified viewtappy list shows every server across every client; tappy add / remove / enable / disable edit them without hand-touching JSON.

Safe operations

  • Non-destructive writes — only the mcpServers section is touched; everything else in the file is preserved.
  • Atomic + backed up — every change is written atomically and a timestamped backup is saved to ~/.tappy/backups/ first.
  • Diff preview before anything is written (--dry-run).
  • One-command rollbacktappy restore <client> puts back the latest backup.
  • Enable / disable a server in place without deleting it.

Inspection & debugging (a terminal MCP Inspector)

  • Live status over the real MCP protocol: ● running / ○ stopped / ⚠ error with handshake latency.
  • Capability listing — a server's actual tools, resources and prompts (with input schemas).
  • Tool runner — invoke any tool with JSON/key=value args and see the raw response.
  • Ad-hoc inspection — point Tappy at a server that isn't installed anywhere yet via --command / --url.

Monitoring

  • tappy status — a one-shot health snapshot of every server: NAME / CLIENT / TRANSPORT / STATUS / LATENCY / TOOLS, with a running / total summary. Servers are probed concurrently.
  • tappy watch — a live, auto-refreshing monitor: the same table, re-probed on an interval, updating in place until you press Ctrl-C. Newly added/removed servers appear as you change configs.
  • tappy probe — a single server's health + latency in one line, for healthchecks.

Security

  • Tool-definition pinning — Tappy fingerprints each server's tools the first time it trusts them and warns you if they change later, catching post-approval tool mutation ("rug-pull" / tool poisoning).
  • Secret env/header values are masked in all output.

Team registry

  • A single git-tracked tappy.team.json as the source of truth for approved servers.
  • tappy apply provisions it into everyone's local clients.
  • tappy lint reports drift and exits non-zero on unapproved servers — a ready-made CI gate.
  • tappy sync copies a server from one client to another.

Install

Requires Python 3.11+. The PyPI package is tappy-mcp; it installs the tappy command.

pip install tappy-mcp

Or, to keep it isolated in its own environment (recommended for CLI tools):

pipx install tappy-mcp        # or: uv tool install tappy-mcp

Run without installing (the npx equivalent)

Tappy is a Python tool, so its "run-it-instantly" command is uvx (from uv) — the Python world's npx:

uvx tappy-mcp ps              # downloads + runs in a throwaway env, nothing to install
uvx tappy-mcp inspect <name>

Verify a normal install with:

tappy --version
tappy help
Install from source (for development)
git clone https://github.com/aadhil96/tappy.git
cd tappy
uv venv && uv pip install -e ".[dev]"   # or: pip install -e ".[dev]"

Quick start

tappy list            # every server across every client
tappy status          # ...with live health, latency and tool counts
tappy inspect <name>  # full report for one server
tappy help            # grouped overview of every command

If you only have one server configured, the inspector commands don't need a name at all — tappy inspect, tappy tools, tappy probe etc. just use it.

New to Tappy? The User Guide is a hands-on manual covering every command, common workflows, scripting, and troubleshooting.

CLI reference

Every data command supports --json (machine-readable) and uses meaningful exit codes, so it drops straight into scripts and CI:

Exit code Meaning
0 success
1 error — target not found, server unreachable, or a failed check (verify on changed tools, lint on unapproved servers, status --fail-on-down)
2 usage error (unknown command / bad flags)

All probing commands accept --timeout SECONDS (default 20) for slow-starting servers.

Manage

tappy list                         # all servers across every client
tappy clients                      # discovered client config files
tappy add fs -- npx -y @modelcontextprotocol/server-filesystem .   # add a stdio server
tappy add api --url https://example.com/mcp                        # add a remote server
tappy enable fs        # / tappy disable fs
tappy remove fs
tappy add fs --dry-run -- npx -y @scope/server .   # preview the change as a diff, write nothing
tappy restore --list   # show backups; restore a client's latest with: tappy restore claude_desktop

Tip: put the stdio command after -- so args like -y aren't mistaken for flags.

Every write is backed up to ~/.tappy/backups/ first, so any change is reversible with tappy restore <client>.

When a server name lives in more than one config of the same client (e.g. Claude Code's project ./.mcp.json and user ~/.claude.json), narrow it with --path:

tappy disable github --path .mcp.json     # the project one, not the user one

Point Tappy at a config it doesn't know natively by listing it in $TAPPY_CONFIG (OS-path-separated), and it shows up everywhere list/status do:

export TAPPY_CONFIG=~/.config/some-client/mcp.json

Monitor

tappy status                       # health snapshot of every server
tappy status -a                    # include disabled servers
tappy status --json                # machine-readable, for dashboards/CI
tappy status --fail-on-down        # exit non-zero if any server is unreachable (CI healthcheck)
tappy watch                        # live monitor, refreshes every 5s
tappy watch --interval 2           # refresh faster
tappy watch --no-stream            # one snapshot and exit

status/watch probe servers concurrently over the real MCP protocol — STATUS reflects an actual handshake, not just whether the config exists. (Familiar if you've used docker ps, but it talks MCP, not containers.)

Secure (catch tool "rug-pulls")

A server can quietly change the tools it advertises after you've trusted it. Pin the tools you approve, then verify later — tappy status also flags drift automatically.

tappy pin weather                  # record a fingerprint of the current tools
tappy verify weather               # re-check; exit 1 if the tools changed (CI gate)

inspect shows the pin status inline, and status prints a footer warning if any pinned server's tools have drifted.

Inspect (the MCP Inspector part)

tappy inspect fs                   # status + tools + resources + prompts + fingerprint
tappy inspect                      # name optional when exactly one server is configured
tappy tools fs --json              # tools with their input schemas
tappy resources fs                 # list resources
tappy prompts fs                   # list prompts
tappy probe fs                     # one-line health + latency
tappy call fs read_file -a path=README.md          # invoke a tool
tappy call fs read_file --input '{"path":"x"}'     # ...or pass JSON args
tappy read fs file:///etc/hosts                    # read a resource's actual contents
tappy prompt fs review -a lang=python              # render a prompt's messages

# inspect something not installed anywhere yet:
tappy inspect --command npx --args "-y @modelcontextprotocol/server-everything"

tappy speaks the full inspector surface: tools/resources/prompts list what a server exposes, and call/read/prompt exercise each of the three MCP primitives.

Team workflow

tappy registry --init --from-client claude_desktop   # create tappy.team.json, seeded
tappy registry                                        # show the approved server set
tappy apply --dry-run                                 # preview changes
tappy apply                                           # provision into local clients (backed up)
tappy lint                                            # report drift (exit 1 = CI gate)
tappy sync github --from claude_desktop --to cursor   # copy a server between clients

Registry path resolves from --registry$TAPPY_REGISTRY./tappy.team.json~/.tappy/tappy.team.json. Commit tappy.team.json; teammates run tappy apply.

Because the registry is meant to be committed, seeding from a client never writes real secrets: env/header values are templated as ${KEY} placeholders, which each developer fills in locally after apply.

Architecture

Every command is a thin shell over one shared core, so management, inspection and monitoring all see the same data the same way.

tappy/
├── __main__.py       # console entry point
├── cli.py            # argparse CLI: management + inspector + monitoring
├── output.py         # rich tables (incl. status/watch monitor) + --json renderers
└── core/             # the shared engine
    ├── models.py         # normalized ServerDef / HealthStatus
    ├── config_store.py   # discovery + safe (atomic, backed-up) writes
    ├── adapters/         # one per client: claude_desktop, claude_code, cursor, generic
    ├── mcp_probe.py      # speaks MCP: initialize, list, call_tool, read_resource, get_prompt, probe_many, fingerprint
    ├── resolve.py        # resolve a target by name or ad-hoc flags
    ├── registry.py       # team registry: load / apply / lint / sync
    └── security.py       # tool-definition pinning store

Built with: Python · the official mcp SDK · Rich.

Development

pytest                # run the test suite
ruff check .          # lint
python -m tappy ...   # equivalent to the `tappy` command

# opt in to the (slow, network) integration tests against a real MCP server:
TAPPY_INTEGRATION=1 pytest -m integration

CI (GitHub Actions) runs ruff and the test suite on Python 3.11–3.13 for every push and pull request. Release history lives in the changelog.

Publishing (maintainers)

The distribution name on PyPI is tappy-mcp; the import package and CLI command are both tappy.

pip install -e ".[dev]"          # includes build + twine
python -m build                  # creates dist/*.whl and dist/*.tar.gz
twine check dist/*               # validate metadata + README rendering
twine upload dist/*              # publish to PyPI (use TestPyPI first if unsure)

Bump version in pyproject.toml before each release and tag it (git tag v0.1.0).

Roadmap

  • watch history / sparklines (latency trend over time)
  • Secrets → OS keychain
  • Log tailing (stderr + client log files)
  • Marketplace / registry install of popular servers

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tappy_mcp-0.1.0.tar.gz (44.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tappy_mcp-0.1.0-py3-none-any.whl (40.4 kB view details)

Uploaded Python 3

File details

Details for the file tappy_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: tappy_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 44.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tappy_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6f62622e147c14932e80fdebb0fe84360c390373d4b835033c7236362fae015f
MD5 0057a495708fe15d72de9b2ff2505eb4
BLAKE2b-256 167a82546d58c3e3cecd6635b390aa30ede8818e16355a0e93d7333f0971b341

See more details on using hashes here.

File details

Details for the file tappy_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: tappy_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 40.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tappy_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b3123f1b1039b39ab857270285d66bf3ba27ae5afae38d90d535c8557448aacc
MD5 31c144715863d6411039c09579f4d6a3
BLAKE2b-256 88f7fb87bf366ae474dd39c94fe580d1a7a263b4e204a4fce25d6f15671207d9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page