octoport
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@octoportshow me the live tool call log"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
π octoport
See every MCP tool call your AI agents make β and exactly where they fail.
A local-first debugger, flight recorder, and control layer for MCP.
npx octoport up --openYour agents call MCP tools all day. When something breaks β an expired OAuth token, a crashing server, a tool that silently changed its schema β you get a vague client error and zero visibility. octoport sits on the path of every MCP call and turns that darkness into a live, diagnosable record:
15:04:12 Claude Code β github / create_pull_request WRITE Β· MEDIUM β 381ms
15:04:18 Claude Code β supabase / execute_sql DATABASE_WRITE Β· MEDIUM β 4.2s AUTH Β· token_expired
15:04:30 Cursor β playwright / browser_click UNKNOWN Β· LOW β 12.7sLive Activity β every call, live: client, identity, server, tool, latency, risk badge, and a canonical failure diagnosis. The home screen.
Failure diagnosis β every failed call is classified deterministically into a canonical taxonomy (
AUTH Β· token_expired,NETWORK Β· dns,SERVER Β· circuit_open, β¦) instead of a raw stack trace.Reliability β per server and per tool: success rate, p50/p95/p99, timeout and auth-failure counts, top failure categories, and deterministic anomaly alerts (consecutive failures, restart loops, latency spikes).
octoport doctorβ "why won't this MCP setup work?" answered with evidence and a concrete fix, in the CLI and the dashboard (same engine).Tool surface integrity β every server's tool catalog is snapshotted and diffed. A server that quietly grows
delete_repositorytriggers a risk-classified warning you must Accept β or Block the tool for every client with one click.Local-first privacy β everything stays on your machine in SQLite. Secret-looking argument keys are redacted before they ever hit disk, and metadata-only mode (
logPayloads: false) never stores args/results at all. The dashboard always states which mode is active.
Quickstart β one command, then it's all web
npx octoport up --openThe dashboard walks you through the rest:
We found your MCP servers β octoport scans your Claude Code / Claude Desktop / Cursor / Windsurf / VS Code configs (global and project-scoped).
Connect your AI client β copy one snippet per client.
Make a test call β and watch it appear in Live Activity, live.
Optionally clean up the now-duplicate direct entries (per-file preview, timestamped backups, restorable from Settings).
From then on your clients talk to one endpoint, and octoport sees everything:
add/edit/toggle servers centrally, and new servers propagate to every connected
client live (tools/list_changed), no restarts.
Until the npm package is published, run from source:
git clone https://github.com/nullarch/octoport && cd octoport && npm install && npm run build && node dist/cli.js up --open
Start at login:
octoport autostart # launchd (macOS) / systemd --user (Linux) / schtasks (Windows)
octoport autostart --removePort 6286 is "OCTO" on a phone keypad. Change it with octoport up --port <n>.
Related MCP server: MCPHub
When MCP breaks
$ octoport doctor
SERVER
β github: error β AUTH Β· token_expired
The credential has expired β re-authenticate.
raw: Error POSTing to endpoint (HTTP 401): Unauthorized
fix: Reauthorize "github": revoke the stored grant (Servers β github β Grants)
and authorize again, or refresh the credential in its headers/env.Doctor checks the environment (Node, config permissions), your clients
(detected configs, whether they point at the hub, whether a session ever
connected), every server (status, classified failure, stderr tail, last
successful call), and the gateway (tokens, privacy mode, policy, IdP
reachability). --json for scripts; the dashboard's Doctor tab runs the same
engine.
One endpoint for everything
Under the observability layer, octoport is a full MCP gateway β that's why it sees every call:
One endpoint β N clients Γ M servers becomes 1 Γ M.
Process supervision β stdio servers run as child processes with crash isolation, jittered backoff restart, start/call timeouts, a circuit breaker after 8 straight failures, and a per-server stderr ring buffer.
Hosted servers with OAuth β add a hosted MCP URL; if it wants OAuth the server card shows Authorize (PKCE, one-time state, dynamic client registration). Tokens live in your config dir,
0600.Full catalog aggregation β tools, prompts (
server__prompt), and resources (URIs pass through, reads routed to the owning server). The call log records all three kinds.Server-initiated requests relayed β
sampling/elicitation/rootsanswered by the client whose call is executing on that server.Named access tokens β one per person or machine; revoking kills live sessions on the spot. Scopes:
admin(dashboard) vsmcp(endpoint).Local security by default β
127.0.0.1binding, Host/Origin validation (DNS-rebinding protection), per-install bearer token. The MCP Inspector RCE (CVE-2025-49596) happened because a localhost tool skipped exactly these.Blocked tools β a per-server denylist (globs) enforced at
tools/listand on every call; the "Block" button on surface-change warnings writes it.
Remote access (optional, explicit)
octoport never exposes itself beyond loopback unless you say so, twice.
Recommended: Tailscale. Keep the default loopback bind, or bind the tailnet address; nothing touches the public internet:
octoport up --host 100.x.y.z --allow-host hub.tailnet-name.ts.net --behind-proxyReverse proxy (Caddy) with a real domain. octoport does not terminate TLS β your proxy does:
# Caddyfile
hub.example.com {
reverse_proxy 127.0.0.1:6286
}octoport up --allow-host hub.example.com --behind-proxy --public-url https://hub.example.com--public-url makes snippets, the dashboard, and OAuth callbacks use the
external address; the dashboard WebSocket switches to wss:// on HTTPS.
GET /healthz answers without a token for proxy health checks. A non-loopback
bind refuses to start without --allow-host and --behind-proxy;
X-Forwarded-Host is deliberately ignored.
Small team setup: run octoport on a shared box behind Tailscale, one named token per teammate, and Live Activity becomes a team-level "which agent did what" record.
Organization mode (experimental)
Status: functional, not yet pilot-verified. The organization gateway is feature-complete for a first pilot and covered by the test suite (including user-boundary attack repros), but has not yet been run end-to-end against a real IdP and real MCP clients in production. Treat it as alpha. Personal mode is stable.
One MCP endpoint for every employee: IT registers servers once, employees add one URL and sign in with company SSO, access follows group profiles, per-user services are authorized individually, and every call is centrally audited under a verified identity.
Company SSO (generic OIDC).
// config.json
"oidc": {
"issuer": "https://login.example.com/realms/acme",
"audience": "octoport", // aud your IdP mints for this hub
"groupsClaim": "groups", // default
"adminGroups": ["platform-admins"] // these groups may open the dashboard
}Tokens validate against the IdP's JWKS (discovery, cache, rotation; RS256/384/
512 + ES256/384; iss/aud/exp/nbf enforced). Unauthenticated requests get a
WWW-Authenticate challenge pointing at
/.well-known/oauth-protected-resource (RFC 9728). Add loginClientId for a
browser Sign in with SSO flow (/login, Authorization Code + PKCE).
Disable the account at the IdP and access dies β octoport has no user database
of its own, on purpose.
Profiles (group-based access). Once any profile exists the MCP surface is
default-deny. Enforced at tools/list and on every call; denials are logged.
Settings has a policy simulator ("what would this identity see?").
"profiles": {
"backend-engineer": {
"groups": ["engineering"],
"servers": ["github", "jira", "sentry"],
"denyTools": ["kubernetes__delete_*"] // globs on public names; deny wins
},
"ci": { "tokens": ["github-actions"], "servers": ["github"] }
}Per-user OAuth downstream. "credentialMode": "per_user_oauth" gives
every identity its own connection and OAuth grant β employee A's GitHub is
never employee B's GitHub. Employees self-serve at /my; admins can
revoke any grant (kills its live connection). Secrets can be references
(file://β¦, vault://β¦) instead of literals.
Central audit. Every row records the verified subject, including policy
denials. Admin actions get their own event trail (GET /api/events, Audit
tab); GET /metrics serves Prometheus.
Deployment: Dockerfile + deploy/docker-compose.yml
(+ a Keycloak demo); guides in
docs/deploy.md and docs/idp.md; design in
docs/threat-model.md.
Commands
Command | What it does |
| Start the hub |
| Diagnose client/server/gateway problems, with fixes |
| Start at login (launchd/systemd) |
| CLI import (the wizard does this too) |
| Print connection snippets |
| Inspect or export the call log |
| List tokens / rotate the default token (live rotation: dashboard β Rotate) |
Data & privacy principles
Local-first by default β SQLite on your machine,
0600.Metadata-only is first-class:
logPayloads: falsestores no args/results.Secrets are redacted before persistence, in every mode.
The dashboard always states exactly what is stored.
Catalog snapshots store hashes, not tool descriptions/schemas.
What octoport is not
Not a finished enterprise governance product. SSO, profiles, per-user OAuth, and verified audit exist (see Organization mode), but there's no SCIM, no tenant separation, and no compliance claims yet.
Not agent mind-reading. octoport sees transport truth β what was called, what failed, what changed. It does not claim to know why a model chose a tool; that requires client-side context it doesn't collect today.
Not a context optimizer for Claude Code. Claude Code ships native MCP tool search; octoport doesn't compete with it.
Not magic. Tool names are namespaced
server__tool(capped at 48 chars with deterministic hashing) and routed through a mapping table β never string-parsed back.
Known limitations (v0.10)
Server-initiated relay (sampling/elicitation/roots) on a shared server uses in-flight correlation, and refuses when two identities call it at once (mark such servers
per_user_oauthto use those features safely).Catalog snapshots/diffs cover shared servers; per-user servers can legitimately show different surfaces per identity and are not snapshotted.
Config edits outside the dashboard need a restart (dashboard changes apply hot); rotate a token live from Settings β Rotate.
autostartrequires a permanent install (npm i -g octoportor a repo checkout) β refuses to point launchd at an ephemeral npx cache.Personal-mode tokens are full-admin by default; org mode uses scoped (
admin/mcp) tokens, per-user OAuth, and profiles.
Support expectations
MIT-licensed, provided as is β a solo-maintained project, so no response-time promises. Issues and PRs are welcome and read; small, focused PRs with tests have the best odds. If you need guarantees, fork freely.
Development
npm install
npm test # 207 tests: unit + E2E incl. mock-OAuth, mock-OIDC, mock-Vault
npm run build
node dist/cli.js up --openThe telemetry/event schema is documented in docs/events.md. Product direction and priorities live in PIVOT.md (it supersedes ROADMAP.md for ordering); the organization-gateway details stay in ROADMAP.md.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for building and testing AI agents with multi-model experimentation and insights.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Real-time chat hub for AI agents β Claude Code, Cursor, Cline, Codex over MCP or REST.
Nifty's MCP server β exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceMCP Hub aggregates and proxies multiple Model Context Protocol servers into a unified Streamable HTTP interface. It allows users to combine diverse stdio, SSE, and HTTP-based servers while providing tool namespacing, health monitoring, and secure authentication.1,038
- FlicenseNot gradedqualityDmaintenanceA centralized management platform that aggregates multiple Model Context Protocol (MCP) servers into a single unified endpoint for AI agents. It provides a web interface for hot-swappable tool management, proxying of existing servers, and AI-powered generation of custom MCP plugins.1
- AlicenseNot gradedqualityDmaintenanceMCPGate aggregates multiple MCP servers into a single unified endpoint, enabling centralized tool management with granular filtering, automatic namespacing, and observability. Features a real-time web dashboard and optional PostgreSQL-backed audit trails for monitoring and controlling AI tool access across local and remote deployments.23Apache 2.0
- AlicenseNot gradedqualityBmaintenanceSelf-hosted MCP proxy and aggregation platform. Register multiple upstream MCP servers and expose them through a single unified endpoint with namespace routing, multi-transport support (HTTP/SSE, stdio, OpenAPIβMCP), per-tool overrides, and a web admin UI.16MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nullarch/octoport'
If you have feedback or need assistance with the MCP directory API, please join our Discord server