From 18d3c8c7506d44f71d881f4659e193da46d55911 Mon Sep 17 00:00:00 2001 From: Juber Shaikh <40266375+CodeWithJuber@users.noreply.github.com> Date: Thu, 13 Aug 2026 23:08:22 +0400 Subject: [PATCH 1/2] fix: make the marketplace manifest installable, resolve the binary at runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `.claude-plugin/marketplace.json` was not a marketplace manifest — it held display metadata (tagline, tags, icon) and none of the three fields the format requires, so `claude plugin marketplace add CodeWithJuber/connector-hub` had nothing to read. Rewritten with `name`, `owner`, and a `plugins` array whose single entry points at the repo root. `claude plugin validate .` now passes. The plugin's `.mcp.json` also pointed straight at `crates/target/release/connector-hub`. Plugin hosts install by cloning, so that path never exists at install time and the server failed to start with no useful message. Added `bin/connector-hub-mcp`, which resolves a binary from `$CONNECTOR_HUB_BIN`, the release build, the debug build, or `$PATH`, and otherwise exits with the exact cargo command to run. It also pins `CONNECTOR_HUB_SPECS_DIR` to the checkout's own `specs/`, so a binary built elsewhere still loads this checkout's catalogue. Manifests bumped to 2.2.0; parity check still passes. Verified: launcher serves MCP from an unrelated cwd and returns all 24 providers / 301 operations; `connector-hub validate` and `claude plugin validate .` both pass. --- .claude-plugin/marketplace.json | 34 +++++++++++++++++++----------- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- .mcp.json | 2 +- bin/connector-hub-mcp | 37 +++++++++++++++++++++++++++++++++ kimi.plugin.json | 2 +- 6 files changed, 63 insertions(+), 16 deletions(-) create mode 100755 bin/connector-hub-mcp diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a52c053..2de29b0 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,15 +1,25 @@ { "name": "connector-hub", - "version": "2.1.0", - "tagline": "One hub for every external service — 24 providers, 301 operations, spec-driven and auditable.", - "tags": [ - "connectors", - "api", - "mcp", - "automation", - "devops" - ], - "icon": "plug", - "homepage": "https://github.com/CodeWithJuber/connector-hub", - "repository": "https://github.com/CodeWithJuber/connector-hub" + "version": "2.2.0", + "description": "Spec-driven connector orchestration — 24 providers, 301 operations, type-safe execution contract with audit ledger.", + "owner": { + "name": "Connector Hub contributors", + "url": "https://github.com/CodeWithJuber" + }, + "plugins": [ + { + "name": "connector-hub", + "source": "./", + "version": "2.2.0", + "description": "Spec-driven connector orchestration — 24 providers, 301 operations, type-safe execution contract with audit ledger.", + "homepage": "https://github.com/CodeWithJuber/connector-hub", + "keywords": [ + "connectors", + "api", + "mcp", + "automation", + "devops" + ] + } + ] } diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 5b67f46..11027da 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "connector-hub", - "version": "2.1.0", + "version": "2.2.0", "description": "Spec-driven connector orchestration — 24 providers, 301 operations, type-safe execution contract with audit ledger.", "author": { "name": "Connector Hub contributors", diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 5b67f46..11027da 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "connector-hub", - "version": "2.1.0", + "version": "2.2.0", "description": "Spec-driven connector orchestration — 24 providers, 301 operations, type-safe execution contract with audit ledger.", "author": { "name": "Connector Hub contributors", diff --git a/.mcp.json b/.mcp.json index 9c98404..ab91b1b 100644 --- a/.mcp.json +++ b/.mcp.json @@ -1,7 +1,7 @@ { "mcpServers": { "connector-hub": { - "command": "${CLAUDE_PLUGIN_ROOT}/crates/target/release/connector-hub", + "command": "${CLAUDE_PLUGIN_ROOT}/bin/connector-hub-mcp", "args": [ "mcp" ], diff --git a/bin/connector-hub-mcp b/bin/connector-hub-mcp new file mode 100755 index 0000000..9764b56 --- /dev/null +++ b/bin/connector-hub-mcp @@ -0,0 +1,37 @@ +#!/bin/sh +# Locate and run the connector-hub binary. +# +# Plugin hosts (Claude Code, Codex, Kimi) install this repo by cloning it, so +# there is no compiled binary at install time. This resolves one in the places +# it is actually likely to be, and fails with an actionable message otherwise. +# +# Order: $CONNECTOR_HUB_BIN, release build, debug build, $PATH. +ROOT="${CLAUDE_PLUGIN_ROOT:-$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)}" + +if [ -n "$CONNECTOR_HUB_BIN" ] && [ -x "$CONNECTOR_HUB_BIN" ]; then + BIN="$CONNECTOR_HUB_BIN" +elif [ -x "$ROOT/crates/target/release/connector-hub" ]; then + BIN="$ROOT/crates/target/release/connector-hub" +elif [ -x "$ROOT/crates/target/debug/connector-hub" ]; then + BIN="$ROOT/crates/target/debug/connector-hub" +elif command -v connector-hub >/dev/null 2>&1; then + BIN="$(command -v connector-hub)" +else + echo "connector-hub: no binary found." >&2 + echo " Build it: cd $ROOT/crates && cargo build --release" >&2 + echo " Or point CONNECTOR_HUB_BIN at an existing build." >&2 + exit 1 +fi + +# The catalogue is data, not code — make sure this checkout's specs are used +# even when the binary came from somewhere else on the filesystem. +if [ -z "$CONNECTOR_HUB_SPECS_DIR" ] && [ -d "$ROOT/specs" ]; then + CONNECTOR_HUB_SPECS_DIR="$ROOT/specs" + export CONNECTOR_HUB_SPECS_DIR +fi + +if [ $# -eq 0 ]; then + exec "$BIN" mcp +else + exec "$BIN" "$@" +fi diff --git a/kimi.plugin.json b/kimi.plugin.json index f12d967..56502a1 100644 --- a/kimi.plugin.json +++ b/kimi.plugin.json @@ -1,6 +1,6 @@ { "name": "connector-hub", - "version": "2.1.0", + "version": "2.2.0", "description": "Spec-driven connector orchestration — 24 providers, 301 operations, type-safe execution contract with audit ledger.", "author": { "name": "Connector Hub contributors", From 6f7345c5f1eaea554875876d0b87d96f3a8b4936 Mon Sep 17 00:00:00 2001 From: Juber Shaikh <40266375+CodeWithJuber@users.noreply.github.com> Date: Thu, 13 Aug 2026 23:09:33 +0400 Subject: [PATCH 2/2] fix: load shared credentials file in the launcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MCP hosts launch stdio servers with a bare environment, so a plugin-installed hub started with no provider credentials at all — every call returned ConfigurationRequired even when the keys existed in the user's shell profile. The launcher now sources $CONNECTOR_HUB_ENV, defaulting to ~/.config/connector-hub/env, before exec. One file per machine instead of the same key pasted into every agent's MCP config. Documented in the README, including why an empty-string value is worse than a commented-out one. --- README.md | 20 ++++++++++++++++++++ bin/connector-hub-mcp | 11 +++++++++++ 2 files changed, 31 insertions(+) diff --git a/README.md b/README.md index 7c4fbb4..9a470c7 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,26 @@ connector-hub audit-verify audit.jsonl See `docs/adr/0004-audit-ledger-format.md` for the format specification. +## Credentials + +Connectors read credentials from the environment. MCP hosts launch stdio +servers with a bare environment, so `bin/connector-hub-mcp` sources +`~/.config/connector-hub/env` (override with `CONNECTOR_HUB_ENV`) before exec. +One file, shared by every agent on the machine: + +```sh +mkdir -p ~/.config/connector-hub +cat > ~/.config/connector-hub/env <<'EOF' +GITHUB_TOKEN="ghp_..." +HETZNER_API_TOKEN="..." +EOF +chmod 600 ~/.config/connector-hub/env +``` + +Leave unused variables commented out rather than set to `""` — an empty string +reads as configured, which turns a clean `ConfigurationRequired` into a 401 +from the provider. + ## Security model - Credentials live in environment variables or an encrypted store. Never in diff --git a/bin/connector-hub-mcp b/bin/connector-hub-mcp index 9764b56..d2c4ab6 100755 --- a/bin/connector-hub-mcp +++ b/bin/connector-hub-mcp @@ -8,6 +8,17 @@ # Order: $CONNECTOR_HUB_BIN, release build, debug build, $PATH. ROOT="${CLAUDE_PLUGIN_ROOT:-$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)}" +# Credentials. MCP hosts launch servers with a bare environment, so provider +# keys have to come from somewhere other than the user's shell profile. One +# file, shared by every host on the machine, keeps a key in a single place +# rather than duplicated across each agent's config. +ENV_FILE="${CONNECTOR_HUB_ENV:-${XDG_CONFIG_HOME:-$HOME/.config}/connector-hub/env}" +if [ -f "$ENV_FILE" ]; then + set -a + . "$ENV_FILE" + set +a +fi + if [ -n "$CONNECTOR_HUB_BIN" ] && [ -x "$CONNECTOR_HUB_BIN" ]; then BIN="$CONNECTOR_HUB_BIN" elif [ -x "$ROOT/crates/target/release/connector-hub" ]; then