npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mcp-agent-portal

v1.0.0-alpha.4

Published

Unified Agent & MCP Control Plane — aggregator for AI agents and MCP tools

Readme

License: MIT Node.js

mcp-agent-portal

Unified MCP aggregator + AI agent runtime. A single MCP server that proxies any number of child MCP servers — your IDE sees one tools/list combined from all of them. Runs a web dashboard in parallel for visual management, agent chat, and live monitoring.

┌─────────────────────────────────┐
│  IDE Agent                      │  ← Claude, GPT, Gemini, etc.
│  (Antigravity / Cursor / ...)   │
└────────────┬────────────────────┘
             │ MCP (stdio)
┌────────────▼────────────────────┐
│  mcp-agent-portal                   │  ← This server
│  (MCP aggregator + web UI)      │
└──┬────────┬────────┬────────────┘
   │        │        │
   ▼        ▼        ▼
 project  agent    browser        ← Child MCP servers
 -graph   -pool    -x-mcp           (stdio, auto-spawned)

[!TIP] Add one entry to your MCP config and get access to every tool from every child server — no per-server configuration in the IDE.

Dual Mode

Agent Portal works in two modes simultaneously:

| Mode | Transport | What you see | |------|-----------|-------------| | IDE | stdio (JSON-RPC) | Unified tools/list, resources/list, prompts/list from all children | | Web | HTTP + WebSocket | Dashboard, Marketplace, AI Chat, Graph, live monitoring |

The IDE talks to mcp-agent-portal as a normal MCP server. The web UI runs in the background on a random port, accessible via portal.local (local gateway).

MCP Aggregation

When your IDE sends tools/call { name: "get_skeleton" }:

  1. Portal looks up get_skeleton in its toolsMapproject-graph
  2. Rewrites the request ID and forwards it to the child's stdin
  3. Child processes the call, responds on stdout
  4. Portal rewrites the ID back and sends the response to the IDE

The browser uses the same mechanism via POST /api/mcp-call.

Heterogeneous Agent Pool

[!NOTE] The adapter pool infrastructure (src/node/adapters/) is fully implemented with BaseAdapter, AdapterPool (acquire/release), and three functional adapters: gemini, claude, and opencode. All three use stream-json parsing with timeout and process group management.

Multiple CLI agents will run in parallel — not just one at a time. The pool is heterogeneous: different providers handle different tasks simultaneously.

┌───────────────────────────────────────────────────────┐
│                AGENT POOL (parallel)                  │
│                                                       │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│  │ Gemini#1 │ │ Gemini#2 │ │ Claude#1 │ │OpenCode │ │
│  │ codegen  │ │ refactor │ │ review   │ │ research│ │
│  └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬────┘ │
│       └──────┬─────┴──────┬─────┴──────┬──────┘     │
│              ▼            ▼            ▼             │
│  ┌─────────────────────────────────────────────────┐ │
│  │  MCP Tool Router — shared across all agents     │ │
│  │  local tools + proxied tools + remote tools     │ │
│  └─────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────┘

Each adapter type will have configurable capacity limits. The orchestrator can auto-select the best provider for a task:

  • Code generation → Gemini (fast, good with code)
  • Architecture review → Claude (deep reasoning)
  • Sensitive data → OpenCode (local, no cloud)
  • Bulk analysis → OpenRouter/Qwen (cheap, parallel)

Three Operating Modes

[!NOTE] Standalone and Client modes are fully implemented. Master mode accepts remote client connections via WebSocket (/ws/client) and aggregates their tools.

node index.js                  # standalone (default, implemented)
node index.js --connect wss:// # client — joins a master node (planned)
node index.js --master         # master — orchestrates client nodes (planned)

| Mode | What it does | Status | |------|-------------|--------| | Standalone | Spawns local child MCP servers, serves web UI, provides stdio MCP to IDE | ✅ Implemented | | Client | Connects to a master via WebSocket, registers its local tools, executes delegated tasks | ✅ Implemented | | Master | Aggregates tools from local children AND remote client nodes. IDE sees everything. | ✅ Implemented |

IDE ──stdio──→ Portal (master)
                ├── local: project-graph, agent-pool
                ├──WSS──→ Client A (machine-1): browser-x, crypto
                └──WSS──→ Client B (cloud-vm): terminal-x, context-x

[!IMPORTANT] In master mode, tools/list will include tools from all connected clients. Routing is transparent — the IDE won't know which machine handles the call.

Web Dashboard

Built-in web UI with extensible section registry:

| Section | Hash | Icon | Description | |---------|------|------|-------------| | Dashboard | #dashboard | dashboard | Server list, action board, agent chat | | AI Chat | #chat | smart_toy | Full-screen agent chat with adapter selection | | Marketplace | #marketplace | storefront | MCP server management — status, start/stop, tool explorer | | Topology | #topology | hub | Network visualization of connected nodes (local + remote) | | Tool Explorer | #tool-explorer | build | Browse tools/list per server with input schema viewer | | Explorer | #explorer | folder_open | File browser with code viewer and docs | | Graph | #graph | developer_board | Force-directed dependency graph (canvas) | | Follow | #follow | smart_toy | Combined graph + code + monitor view for live agent tracking | | Analysis | #analysis | analytics | Code quality health dashboard | | Monitor | #monitor | monitor_heart | Live event stream from all MCP servers | | Settings | #settings | settings | Portal configuration |

New sections are registered via RouterRegistry — MCP servers can inject their own UI panels at runtime.

Marketplace

Discover and manage MCP servers. The Marketplace panel shows all configured servers with live status, PID, and tool count. Planned features:

  • Add/remove servers via UI (edits mcp-agent-portal.json)
  • Tool explorer — browse tools/list per server
  • Start/stop/restart individual servers
  • Public registry (ClawHub-inspired)

CLI Adapters

[!NOTE] The adapter infrastructure is fully implemented in src/node/adapters/. All three adapters (Gemini, Claude, OpenCode) are functional with stream-json parsing, timeout handling, and detached process group management.

Abstract interface for any CLI agent runtime:

class BaseAdapter {
  async start() {}
  async chat(prompt) {}
  async *stream(prompt) {}
  async stop() {}
  getBuiltinTools() { return []; }
  getStatus() { return { id, type, status }; }
}

Concrete adapters:

| Adapter | CLI | Status | |---------|-----|--------| | gemini-adapter | gemini -p "prompt" --output-format stream-json | ✅ Functional | | claude-adapter | claude -p "prompt" --output-format stream-json | ✅ Functional | | opencode-adapter | OpenCode/Crush MCP host | ✅ Functional | | openrouter-adapter | Direct API calls | 🔴 Not started |

The AdapterPool will manage instances — acquire(type) gets an idle adapter or spawns a new one, release() returns it to the pool.

Plugin Architecture (External Integrations)

[!NOTE] Plugin architecture is implemented: PluginLoader scans and initializes plugins, supports { init, destroy, onAlert } interface. Telegram bot plugin is functional. Error alerting (crash → plugin dispatch) is wired.

The Agent Portal will support a modular Plugin System designed to bridge the portal's unified agent pool and MCP tools to external platforms (e.g., Telegram, Slack, GitHub).

Based on our reference implementations (like the local telegram-llm-bot), a plugin is an autonomous integration module that connects external channels to the portal's reasoning engine.

Core Responsibilities of a Plugin

  1. Channel Transport: Manages the connection to the external service (e.g., Telegraf for Telegram bots, Webhooks for Slack).
  2. Context Synchronization: Maintains conversation state. While standalone bots might use local XML/JSON files for context windows, Portal plugins can leverage the centralized context management to store and retrieve multi-day conversation histories.
  3. Agent Delegation: Instead of calling LLM APIs directly, plugins route user messages through the Portal's AdapterPool. The plugin asks the portal to execute a task, and the portal routes it to the appropriate CLI adapter (Gemini, Claude, or OpenCode).
  4. Action Interception (Inline Tools): Plugins can parse special output directives from the agents. For legacy agents or environments where strict JSON-RPC MCP isn't available, the agent can output text-based markers (e.g., ||readFile||/path/to/file|| or ||sendMessage||...). The plugin intercepts these markers, executes the corresponding local action (like reading a file uploaded to the chat), and injects the result back into the agent's context without exposing the raw markup to the end user.

Example: Telegram Bot Plugin

A Telegram plugin running within the portal operates as follows:

  • Input: Listens for @bot_name mentions, direct messages, or document uploads.
  • Context: Formats the recent chat history into the agent's context prompt.
  • Execution: Sends the prompt to the Portal Orchestrator (e.g., targeting the opencode-adapter for secure local execution).
  • Tooling: If a user uploads a document, the plugin saves it locally. If the agent needs to read it, it outputs ||readFile||/path/to/doc.txt||. The plugin reads the file, appends its content to the context, and re-prompts the agent seamlessly.
  • Output: Formats the final text (handling Markdown code blocks properly for Telegram's specific syntax) and sends it back to the chat.

By keeping plugins loosely coupled, the Agent Portal acts as the central brain, while plugins serve as the sensory inputs and outputs across different communication platforms.

Quick Start

Prerequisites: Node.js >= 20.

Add to your IDE's MCP configuration:

{
  "mcpServers": {
    "agent-portal": {
      "command": "npx",
      "args": ["-y", "mcp-agent-portal"]
    }
  }
}

That's it. On the next IDE restart the portal will download itself, spawn its child servers, and expose all tools.

[!TIP] The portal replaces individual project-graph-mcp and agent-pool-mcp entries in your MCP config — you only need this single entry.

Configuration

Optionally create ~/.gemini/agent-portal.json to customize child servers and adapters:

{
  "mode": "standalone",
  "mcpServers": {
    "project-graph": {
      "command": "npx",
      "args": ["-y", "project-graph-mcp"]
    },
    "agent-pool": {
      "command": "npx",
      "args": ["-y", "agent-pool-mcp"]
    }
  },
  "adapters": {
    "gemini": { "type": "gemini", "enabled": true, "maxInstances": 5 },
    "claude": { "type": "claude-code", "enabled": false, "maxInstances": 2 }
  }
}

Local Development

git clone https://github.com/rnd-pro/mcp-agent-portal
cd mcp-agent-portal
npm install
node index.js

MCP Ecosystem

Agent Portal aggregates the full RND-PRO MCP ecosystem:

| Server | Description | Status | |--------|-------------|--------| | project-graph-mcp | AST-based codebase analysis, navigation, documentation | ✅ Production | | agent-pool-mcp | Multi-agent delegation, pipelines, scheduling, peer review | ✅ Production | | browser-x-mcp | Browser automation, form testing | 🟡 Beta | | terminal-x-mcp | Multi-terminal automation with security validation | 🔴 Alpha | | context-x-mcp | Context enrichment with auto-topic detection | 🔴 Alpha | | crypto-mcp | Crypto market analysis, trend lines, auto-trading | 🟡 Beta |

[!IMPORTANT] Each child server runs as an independent process. Portal manages their lifecycle — auto-start on boot, log anomalies on crash, graceful shutdown on exit. Auto-restart on crash is planned but not yet implemented.

HTTP API

| Endpoint | Method | Description | |----------|--------|-------------| | /api/mcp-call | POST | Proxy an MCP call to a child server | | /api/instances | GET | List all registered MCP servers with status | | /api/project-info | GET | Portal metadata | | /api/server-status | GET | Uptime, server count, monitor count | | /api/stop | POST | Graceful shutdown | | /api/restart | POST | Restart portal | | /api/* | * | Fallback HTTP proxy to local-gateway backends |

Project Structure

mcp-agent-portal/
├── bin/mcp-agent-portal.js           # Restart wrapper (exit code 2 = respawn)
├── index.js                     # Entry point: web server + stdio MCP
├── package.json
├── eslint.config.js             # Flat ESLint config for IDE highlighting
├── packages/                    # Git submodules
│   ├── symbiote-node/           # UI framework (layout, canvas, themes)
│   ├── project-graph-mcp/       # Codebase analysis MCP
│   └── agent-pool-mcp/          # Agent orchestration MCP
├── src/node/
│   ├── config-store.js          # Config read/write utility (DRY)
│   ├── server/
│   │   ├── web-server.js        # HTTP server + route dispatch + static files
│   │   ├── api-routes.js        # Declarative API route map (CIT pattern)
│   │   ├── lint-service.js      # ESLint integration for server-side linting
│   │   ├── local-gateway.js     # DNS-like service discovery
│   │   └── web-server.ctx       # ← colocated documentation
│   ├── proxy/
│   │   ├── mcp-proxy.js         # MCPProxyManager (child lifecycle + auto-restart)
│   │   ├── mcp-multiplexer.js   # MCPMultiplexer (stdio ↔ children)
│   │   ├── mcp-proxy.ctx
│   │   └── mcp-multiplexer.ctx
│   ├── adapters/
│   │   ├── index.js             # resolveAdapter() registry
│   │   ├── base.js              # BaseAdapter interface
│   │   ├── gemini.js            # Gemini CLI adapter
│   │   ├── stubs.js             # Claude + OpenCode stubs
│   │   └── pool.js              # AdapterPool (acquire/release)
│   ├── plugins/
│   │   ├── plugin-loader.js     # Plugin discovery + lifecycle + alert dispatch
│   │   └── telegram/index.js    # Telegram bot plugin (chat + alerts)
│   └── discovery/
│       └── ws-client.js         # WebSocket client for --connect mode
├── web/                         # Frontend SPA
│   ├── app.js                   # Main app (RouterRegistry)
│   ├── router-registry.js       # Extensible section/panel registry
│   ├── state.js                 # Reactive state store + WS connection
│   ├── WsClient.js              # Static WS singleton (CIT pattern)
│   ├── components/              # code-block (with lint overlay), canvas-graph
│   └── panels/                  # 9 panel dirs + 6 standalone panels
├── test/
│   ├── unit/                    # node --test unit tests
│   └── integration/             # node --test API tests
└── tmp/                         # Drafts (gitignored)

[!TIP] Colocated .ctx — documentation files live next to their source (parser.ctx beside parser.js), not in a separate .context/ tree. This ensures agents see the file ↔ docs pairing immediately when listing a directory, without needing to know about a separate documentation tree.

Observability & Monitoring

Since Agent Portal acts as an aggregation hub for multiple child processes and parallel agents, observability is a core concern:

Implemented

  1. Process Lifecycle Tracking: The MCPProxyManager spawns child servers and tracks their PID and process state.

  2. Log Multiplexing & Live Telemetry: Standard error (stderr) streams from all child servers are logged to the portal's console. JSON-RPC messages from children are broadcast to connected WebSocket clients via broadcastMonitor(). The Web Dashboard's Monitor panel subscribes to this feed, providing a real-time event stream.

  3. Auto-Restart on Crash: Crashed child processes are automatically respawned with exponential backoff (1s → 2s → 4s → ... → 30s max). Crash counter resets after 10s of stable uptime. Crash events are broadcast to WebSocket monitors and dispatched to plugins.

  4. Error Notifications & Alerting: Crash events trigger pluginLoader.dispatchAlert(), which forwards alerts to all plugins implementing onAlert(). The Telegram plugin sends alerts to a configured alertChatId.

UI Error Highlighting (Server-Side Linting)

Server-side linting is fully implemented:

  1. Backend Integration: The /api/lint-file endpoint runs Node.js-based ESLint (lint-service.js) against the local file system using the project's eslint.config.js.
  2. UI Component (code-block.js): The code-viewer.js panel calls _lintCurrentFile() on every file load, passing results to code-block.setDiagnostics(). The _renderSquiggles() method renders absolutely positioned wavy underlines (red for errors, yellow for warnings) with hover tooltips showing rule IDs and messages.

Roadmap

Implementation phases in strict execution order. Each phase depends on the previous one being complete.

Phase 0 — Cross-Project Best Practices Refactoring ✅ (this repo)

[!IMPORTANT] This phase is prerequisite for all feature work. Without it, new code will inherit inconsistent patterns from upstream projects.

Align all related repositories to the unified coding standard defined in BEST-PRACTICES.md:

| # | Project | Key Refactoring | Priority | |---|---------|-----------------|----------| | 0.1 | mcp-agent-portal (this repo) | iso/node/ui/ source layout; let-first; single quotes; JSDoc @type on all exports | 🔴 Critical | | 0.2 | project-graph-mcp | Code style audit (let/const, arrow conventions); generate .ctx docs for every src/ file | 🔴 Critical | | 0.3 | agent-pool-mcp | Same code style audit; .ctx docs generation; verify plain-object patterns (no unnecessary classes) | 🔴 Critical | | 0.4 | symbiote-node | Verify Triple-File Partitioning; audit token-based theming; ensure iso/node/ui/ boundary compliance | 🟡 High | | 0.5 | browser-x-mcp | Code style pass; add .ctx docs | 🟢 Normal | | 0.6 | terminal-x-mcp | Code style pass; add .ctx docs | 🟢 Normal |

Per-project checklist (from BEST-PRACTICES §10):

  • [ ] let over const (const only for true constants: CONFIG_FILE, REQUIRED_FIELDS)
  • [ ] Single quotes + semicolons + 2-space indent
  • [ ] Arrow functions for callbacks; function only for named exports and hoisted helpers
  • [ ] Max 30 lines per utility file; split if larger
  • [ ] Plain objects for adapters/connectors — no class hierarchies
  • [ ] resolveX() registry pattern with error messages listing valid options
  • [ ] JSDoc @type inline casts; full @param/@returns blocks on public exports only
  • [ ] Emoji log prefixes (✅🟡🔴🔄)
  • [ ] Dual exports (named + default) on every module
  • [ ] Colocated .ctx — documentation generated next to source files (src/proxy/mcp-proxy.ctx), not in .context/
  • [ ] node --test — no test framework dependency (no Jest/Mocha/Vitest)
  • [ ] eslint.config.js matching conventional style for IDE highlighting only

Deliverable: All repos pass a unified style audit. .ctx docs generated. Ready for feature work.


Phase 1 — Portal Core Stabilization ✅

Harden the implemented MCP aggregator core:

| # | Task | Scope | |---|------|-------| | 1.1 | Auto-restart on crash | mcp-proxy.js: add respawn logic with exponential backoff in child.on('exit') | | 1.2 | Exit code 2 = restart | index.js: wrap in bin entry point that restarts on code 2 (config change via UI) | | 1.3 | Config validation | mcp-proxy.js: fail-fast with clear messages on missing command/args fields | | 1.4 | /api/lint-file endpoint | web-server.js: integrate ESLint for server-side linting | | 1.5 | Code viewer error overlay | code-block.js: squiggles/tooltips from lint results | | 1.6 | .ctx docs panel | Verify ctx-panel.js works with generated .ctx files from Phase 0 |

Deliverable: Rock-solid single-node portal with auto-healing, config validation, and error visualization.


Phase 2 — CLI Adapter Pool ✅ (core)

Implement the heterogeneous agent pool:

| # | Task | Scope | |---|------|-------| | 2.1 | src/adapters/ directory | Create with index.js registry (plain-object resolveAdapter() pattern) | | 2.2 | gemini-adapter | Port from agent-pool-mcpgemini CLI wrapper | | 2.3 | claude-adapter | Port from agent2agentclaude-code CLI wrapper | | 2.4 | opencode-adapter | Port from agicoder — OpenCode/Crush MCP host | | 2.5 | AdapterPool | acquire(type) / release() lifecycle, capacity limits from config | | 2.6 | AgentChat integration | Wire AgentChat panel to use AdapterPool instead of direct API calls |

Deliverable: Agent chat works with multiple LLM backends. Config adapters section is functional.


Phase 3 — Plugin System ✅

External integrations via loosely coupled plugins:

| # | Task | Scope | |---|------|-------| | 3.1 | Plugin loader | Scan plugins/ directory, load and register plugins at startup | | 3.2 | Plugin interface | { name, init(portal), destroy() } — portal injects API surface | | 3.3 | Telegram plugin | Port and adapt telegram-llm-bot as first reference plugin | | 3.4 | Error alerting via plugins | Connect Observability alerts → plugin dispatch (Telegram, Slack) |

Deliverable: Working Telegram bot that routes messages through Portal's adapter pool. Error alerts in Telegram.


Phase 4 — Distributed Mode ✅ (core)

Multi-node topology (client/master):

| # | Task | Scope | |---|------|-------| | 4.1 | CLI argument parsing | --connect, --master flags in index.js | | 4.2 | src/discovery/ | WebSocket client for connecting to master node | | 4.3 | Master aggregation | Extend MCPMultiplexer to accept remote tool registrations | | 4.4 | Topology panel | New #topology section — network visualization of connected nodes |

Deliverable: IDE on machine A uses tools from machine B transparently.


Phase 5 — Marketplace & Public Registry ✅ (local)

| # | Task | Scope | |---|------|-------| | 5.1 | Add/remove servers via UI | Marketplace edits mcp-agent-portal.json + triggers exit(2) restart | | 5.2 | Tool explorer | Browse tools/list per server with input playground | | 5.3 | Public registry API | ClawHub-inspired server discovery and one-click install |

Deliverable: Fully self-service MCP server management.

Related Projects

License

MIT © RND-PRO.com


Made with ❤️ by the RND-PRO team