Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"name": "bridge-mcp",
"source": "./plugin",
"description": "Secure SSH bridge for remote server management — 357 tools across 75 groups (Linux, Windows, Docker, Kubernetes, cloud) over one SSH connection. CLI-first for 10-32x token savings vs MCP; MCP transport also available.",
"version": "1.19.0",
"version": "1.19.1",
"category": "devops",
"author": {
"name": "muchiny",
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- **Plugin 1.19.1** (binary unchanged): enriched the `bridge` and `discover`
skill `description` frontmatter with concrete trigger phrases (docker,
kubernetes, systemd, logs, metrics, ports, host names) so Claude auto-invokes
them more reliably, per Anthropic's skill-authoring guidance. Fixed stale
counts in the `discover` skill (75 groups, 9 protocols — dropped the removed
ZeroMQ/NATS/MQTT/SNMP/NETCONF stubs).

## [1.19.0] - 2026-06-19

### Added
Expand Down
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# MCP SSH Bridge
# Bridge MCP

<!-- markdownlint-disable MD033 -->
<div align="center">

<img src="dxt/icon.svg" alt="MCP SSH Bridge" width="96" height="96">
<img src="dxt/icon.svg" alt="Bridge MCP" width="96" height="96">

[![CI](https://github.com/muchiny/bridge-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/muchiny/bridge-mcp/actions/workflows/ci.yml)
[![Crates.io](https://img.shields.io/crates/v/bridge-mcp?style=flat-square&logo=rust)](https://crates.io/crates/bridge-mcp)
Expand All @@ -15,7 +15,7 @@
**A Rust MCP server for secure remote infrastructure management — 357 tools, 9 protocols.**

```
Claude Code ◄──JSON-RPC──► MCP SSH Bridge ◄──9 protocols──► Your Infrastructure
Claude Code ◄──JSON-RPC──► Bridge MCP ◄──9 protocols──► Your Infrastructure
```

</div>
Expand Down Expand Up @@ -151,6 +151,16 @@ git clone https://github.com/muchiny/bridge-mcp && cd bridge-mcp && make release

</details>

> **Claude Code plugin (one command).** Install the plugin from the marketplace — it registers the `/bridge-mcp:bridge` and `/bridge-mcp:discover` skills, the MCP server, and a binary-bootstrap hook:
>
> ```bash
> claude plugin marketplace add muchiny/bridge-mcp
> claude plugin install bridge-mcp@muchiny
> cargo install --git https://github.com/muchiny/bridge-mcp --features full # the binary the plugin drives
> ```
>
> The skills auto-trigger when you mention a remote host, Docker, Kubernetes, services, logs, ports, etc.

### 2. Configure

```bash
Expand Down Expand Up @@ -200,11 +210,11 @@ bridge-mcp status

## Architecture

MCP SSH Bridge sits between Claude Code and your infrastructure. It routes commands through 9 protocol adapters with built-in security validation, output sanitization, and audit logging.
Bridge MCP sits between Claude Code and your infrastructure. It routes commands through 9 protocol adapters with built-in security validation, output sanitization, and audit logging.

```mermaid
graph LR
CC[Claude Code] -->|JSON-RPC stdio or Unix socket| BR[MCP SSH Bridge]
CC[Claude Code] -->|JSON-RPC stdio or Unix socket| BR[Bridge MCP]

BR --> SEC[Security<br/>Validator · Sanitizer · Audit]
SEC --> ER[Executor Router]
Expand Down
2 changes: 1 addition & 1 deletion plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bridge-mcp",
"version": "1.19.0",
"version": "1.19.1",
"description": "357-tool SSH bridge for secure remote server management. Execute commands on air-gapped Linux, Windows, Docker, Kubernetes hosts via SSH from Claude Code.",
"author": {
"name": "muchiny",
Expand Down
3 changes: 2 additions & 1 deletion plugin/hooks/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"hooks": [
{
"type": "command",
"command": "command -v bridge-mcp >/dev/null 2>&1 && echo 'Bridge MCP ready. Use /bridge-mcp:bridge to manage remote hosts, or /bridge-mcp:discover to explore 357 tools.' || echo '⚠️ Bridge MCP plugin loaded, but the bridge-mcp binary was not found on PATH. Install it: cargo install --git https://github.com/muchiny/bridge-mcp --features full'"
"command": "command -v bridge-mcp >/dev/null 2>&1 && echo 'Bridge MCP ready. Use /bridge-mcp:bridge to manage remote hosts, or /bridge-mcp:discover to explore 357 tools.' || { echo '⚠️ bridge-mcp binary not found — auto-installing (prebuilt download)…'; BRIDGE_MCP_BOOTSTRAP_AUTO=1 bash \"${CLAUDE_PLUGIN_ROOT}/scripts/install.sh\"; }",
"timeout": 90
}
]
}
Expand Down
102 changes: 102 additions & 0 deletions plugin/scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env bash
# Bridge MCP binary bootstrap.
#
# Installs the `bridge-mcp` binary that the plugin drives. Strategy:
# 1. already on PATH -> nothing to do
# 2. prebuilt release asset -> download + extract (fast, no Rust toolchain)
# 3. cargo install --git -> build from source (fallback; needs Rust)
#
# Safe to re-run (idempotent). Installs to ~/.local/bin.
set -euo pipefail

REPO="muchiny/bridge-mcp"
BIN="bridge-mcp"
DEST="${HOME}/.local/bin"
# When set (e.g. auto-run from the SessionStart hook), never block on a
# multi-minute `cargo` build — print the manual command instead.
AUTO="${BRIDGE_MCP_BOOTSTRAP_AUTO:-}"

if command -v "${BIN}" >/dev/null 2>&1; then
echo "✔ ${BIN} already installed: $("${BIN}" --version 2>/dev/null || echo present)"
exit 0
fi

mkdir -p "${DEST}"

# Map the current platform to a release asset name.
os="$(uname -s)"
arch="$(uname -m)"
asset=""
case "${os}" in
Linux)
case "${arch}" in
x86_64 | amd64) asset="${BIN}-linux-x86_64.tar.gz" ;;
aarch64 | arm64) asset="${BIN}-linux-arm64.tar.gz" ;;
esac
;;
Darwin)
case "${arch}" in
arm64) asset="${BIN}-macos-arm64.tar.gz" ;;
esac
;;
esac

install_prebuilt() {
[ -n "${asset}" ] || return 1
command -v curl >/dev/null 2>&1 || return 1
local url="https://github.com/${REPO}/releases/latest/download/${asset}"
local tmp
tmp="$(mktemp -d)"
echo "↓ Downloading prebuilt binary: ${url}"
if ! curl -fsSL "${url}" -o "${tmp}/bin.tar.gz"; then
rm -rf "${tmp}"
return 1
fi
# Verify the checksum when available (and sha256sum exists).
if command -v sha256sum >/dev/null 2>&1 &&
curl -fsSL "${url}.sha256" -o "${tmp}/bin.sha256" 2>/dev/null; then
local want got
want="$(awk '{print $1}' "${tmp}/bin.sha256")"
got="$(sha256sum "${tmp}/bin.tar.gz" | awk '{print $1}')"
if [ "${want}" != "${got}" ]; then
echo "✗ checksum mismatch (expected ${want}, got ${got})"
rm -rf "${tmp}"
return 1
fi
fi
tar -xzf "${tmp}/bin.tar.gz" -C "${tmp}"
install -m 0755 "${tmp}/${BIN}" "${DEST}/${BIN}"
rm -rf "${tmp}"
}

install_cargo() {
if ! command -v cargo >/dev/null 2>&1; then
echo "✗ No prebuilt for ${os}/${arch} and cargo is not installed."
echo " Install Rust (https://rustup.rs) or grab a binary from:"
echo " https://github.com/${REPO}/releases/latest"
return 1
fi
echo "⚙ No prebuilt for ${os}/${arch}; building from source (a few minutes)…"
cargo install --git "https://github.com/${REPO}" --features full
}

if install_prebuilt; then
echo "✔ Installed ${BIN} -> ${DEST}/${BIN}"
elif [ -n "${AUTO}" ]; then
# Auto mode (hook): no prebuilt for this platform — don't block on a build.
echo "ℹ No prebuilt binary for ${os}/${arch}. Build it manually (needs Rust):"
echo " cargo install --git https://github.com/${REPO} --features full"
exit 0
elif install_cargo; then
echo "✔ Installed ${BIN} via cargo"
else
echo "✗ bridge-mcp install failed. See https://github.com/${REPO}#install"
exit 1
fi

case ":${PATH}:" in
*":${DEST}:"*) ;;
*) echo "⚠ ${DEST} is not on your PATH — add: export PATH=\"${DEST}:\$PATH\"" ;;
esac

"${DEST}/${BIN}" --version 2>/dev/null || "${BIN}" --version 2>/dev/null || true
12 changes: 9 additions & 3 deletions plugin/skills/bridge/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
---
name: bridge
version: 1.19.1
description: |
Use when the user says "bridge", "remote", "ssh", "run on host", "check host",
"configure host", "setup bridge", or wants to manage remote servers via CLI.
Provides guided SSH bridge setup, status checks, and tool execution.
Use when the user wants to run a command on or manage a remote host over SSH —
a server, Raspberry Pi, VM, NAS, network switch, or air-gapped machine.
Triggers: "check/manage my server", "run X on host Y", "ssh into / exec on
host", "restart nginx on prod", "docker ps / containers on", "kubectl / k8s
pods / helm on the cluster", "tail the logs on", "disk usage / cpu / memory /
processes on host", "what's listening on port", "is host reachable", "service
status", "configure / validate the bridge". Drives the bridge-mcp CLI (357 SSH
tools) — guided setup, status checks, and tool execution.
user-invocable: true
argument-hint: "[status|config|tool-name] [args...]"
---
Expand Down
13 changes: 9 additions & 4 deletions plugin/skills/discover/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
---
name: discover
version: 1.19.1
description: |
Use when the user wants to explore available tools, find tools by category,
or learn what bridge-mcp can do. Progressive discovery workflow.
Use when the user wants to explore, search, or learn what bridge-mcp can do:
"what tools are available", "list bridge tools", "find a tool for X", "show
docker / kubernetes / systemd / network tools", "search tools for logs /
firewall / packages / databases", "which tool groups exist", "what can the
bridge do". Progressive discovery across the 357 tools and 75 groups, with
token-efficient describe-tool output.
user-invocable: true
argument-hint: "[group-name|search-term]"
---
Expand Down Expand Up @@ -33,6 +38,6 @@ telling you which params (jq_filter, columns, limit, etc.) apply for token-effic

## Tips for the user

- **74 groups**: docker, kubernetes, systemd, networking, firewall, packages, users, cron, logs, files, etc.
- **75 groups**: docker, kubernetes, systemd, networking, firewall, packages, users, cron, logs, files, etc.
- **Token-efficient**: always use `columns`, `limit`, or `jq_filter` params to reduce output
- **13 protocols**: SSH, WinRM, Telnet, K8s Exec, Serial, AWS SSM, Azure, GCP, ZeroMQ, NATS, MQTT, SNMP, NETCONF
- **9 protocols**: SSH, WinRM, PSRP, Telnet, K8s Exec, Serial, AWS SSM, Azure, GCP
Loading