# https://github.com/rnd-pro/mcp-agent-portal Project Manual

Generated at: 2026-06-21 01:33:16 UTC

## Table of Contents

- [Overview and System Architecture](#page-overview)
- [MCP Gateway and Tool Orchestration](#page-mcp-gateway)
- [Agent Runtime and CLI Adapters](#page-agent-runtime)
- [Web Dashboard and Frontend](#page-web-dashboard)

<a id='page-overview'></a>

## Overview and System Architecture

### Related Pages

Related topics: [MCP Gateway and Tool Orchestration](#page-mcp-gateway), [Agent Runtime and CLI Adapters](#page-agent-runtime)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/README.md)
- [package.json](https://github.com/rnd-pro/mcp-agent-portal/blob/main/package.json)
- [src/node/agents/frontmatter.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/frontmatter.js)
- [src/node/agents/agent-parser.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/agent-parser.js)
- [src/node/proxy/mcp-multiplexer.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-multiplexer.js)
- [src/node/proxy/workflow-board-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/workflow-board-tools.js)
- [src/node/proxy/portal-orchestrator-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/portal-orchestrator-tools.js)
- [src/node/proxy/orchestration-development-map.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/orchestration-development-map.js)
- [src/node/proxy/tool-index.ctx.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/tool-index.ctx.md)
- [src/node/server/marketplace-registry.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/marketplace-registry.js)
- [src/node/server/demo-mode.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/demo-mode.js)
- [src/node/server/local-gateway.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/local-gateway.js)
</details>

# Overview and System Architecture

`mcp-agent-portal` is a Node.js-based **Unified Agent & MCP Control Plane** that aggregates AI agents and Model Context Protocol (MCP) tools behind a single portal surface. According to [package.json](https://github.com/rnd-pro/mcp-agent-portal/blob/main/package.json), the project is published as the binary `mcp-agent-portal` and currently ships as `1.0.0-alpha.5`. The README frames the portal as an opinionated runtime that combines project-local skills, marketplace MCP servers, workflow boards, and a browser UI for orchestrating agents at the chat level ([README.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/README.md)).

## Purpose and Scope

The portal is positioned as both an **MCP server** and a **control plane for agents**. It exposes meta-tools that an LLM client (such as Claude Code or OpenCode) can call to discover, route, and supervise work performed by other MCP servers and subagents.

Concretely, the portal publishes a set of meta-tools — including `discover_tools`, `call_tool`, `get_portal_status`, and `create_chat` — described in [src/node/proxy/mcp-multiplexer.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-multiplexer.js). These tools are how an upstream agent inspects what the portal can do, which public servers are connected, and how to spawn a new chat session. Behind them, the multiplexer forwards calls to a curated catalogue of MCP servers — filesystem, GitHub, Slack, PostgreSQL, SQLite, Brave Search, Fetch, Sequential Thinking, Google Maps, Google Drive, Sentry, and Linear — as enumerated in [src/node/server/marketplace-registry.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/marketplace-registry.js).

The scope therefore covers four concerns that the rest of this page references:

1. **Agent definition** — Markdown files under `.agent-portal/agents/*.md` parsed by [src/node/agents/agent-parser.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/agent-parser.js).
2. **Skill composition** — YAML frontmatter plus `{{skill:NAME}}` placeholders handled by [src/node/agents/frontmatter.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/frontmatter.js).
3. **MCP multiplexing** — A proxy that re-exposes child MCP server tools through a unified surface, documented in [src/node/proxy/tool-index.ctx.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/tool-index.ctx.md).
4. **Orchestration and workflow control** — Tools such as `workflow_board` and orchestrator meta-tools defined in [src/node/proxy/workflow-board-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/workflow-board-tools.js) and [src/node/proxy/portal-orchestrator-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/portal-orchestrator-tools.js).

## High-Level Architecture

The portal is structured as a Node.js backend that serves a bundled web UI, hosts an MCP proxy, and exposes a project-local `.agent-portal/` workspace. The local gateway component described in [src/node/server/local-gateway.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/local-gateway.js) routes HTTP traffic to the correct backend port and injects a `<base href>` for path-prefix hosting. A `demo-mode` module in [src/node/server/demo-mode.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/demo-mode.js) provides a fully self-contained runtime with hard-coded sample agents, skills, files, and API responses — useful for evaluating the UI without configuring a real workspace.

```mermaid
flowchart LR
  Client[LLM Client / Browser] -->|MCP JSON-RPC| Portal[mcp-agent-portal]
  Client -->|HTTP/WS| WebUI[Web UI bundle]
  Portal -->|tools/list, call_tool| Mux[MCP Multiplexer]
  Mux -->|stdio / sse| S1[Filesystem MCP]
  Mux -->|stdio / sse| S2[GitHub MCP]
  Mux -->|stdio / sse| S3[Other Marketplace Servers]
  Portal --> Orch[Portal Orchestrator Tools]
  Portal --> WB[Workflow Board Tool]
  Orch --> DevMap[(Development Map)]
  WB --> Board[(Column / Item State)]
  Portal --> Agents[(.agent-portal/agents/*.md)]
  Portal --> Skills[(.agent-portal/skills/*.md)]
```

The diagram captures the request flow described above: a client first talks to the portal, which then fans out to child MCP servers, the orchestrator, the workflow board, and the on-disk agent and skill libraries.

## Core Subsystems

### Agent and Skill Parsing

Agent definitions live as Markdown with YAML frontmatter. The parser in [src/node/agents/agent-parser.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/agent-parser.js) supports a documented schema (`name`, `description`, `role`, `icon`, `color`, `resource_group`, `provider`, `model`, `models[]`, `skills[]`, `visibleAgents[]`) and resolves skill composition in two ways: a `skills: [X, Y]` array is **prepended** before the agent body, while `{{skill:Z}}` is resolved **inline at the placement position**. The underlying frontmatter parser in [src/node/agents/frontmatter.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/frontmatter.js) handles scalars, inline and multiline arrays, inline objects, and nested objects — a deliberate subset that is sufficient for agent and skill files.

### MCP Multiplexer and Tool Index

The multiplexer in [src/node/proxy/mcp-multiplexer.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-multiplexer.js) presents a unified `tools/list` and `call_tool` surface to upstream clients while internally tracking the origin of each tool. The accompanying notes in [src/node/proxy/tool-index.ctx.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/tool-index.ctx.md) state that the index is **cached**, **rebuilt** by calling `tools/list` on each child server, and **augmented** with user-defined tag maps from configuration. Search supports keyword, tag, and server-name filters, as reflected in the `discover_tools` input schema.

### Orchestration and the Development Map

The orchestrator module in [src/node/proxy/portal-orchestrator-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/portal-orchestrator-tools.js) emits **prompt hints** and **activity classifications** that help upstream agents repair stalled workflows. It produces a structured payload — `activityMap`, `subagentMap`, `taskMap`, `toolMap`, and `promptHintMap` — built by [src/node/proxy/orchestration-development-map.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/orchestration-development-map.js). The map is bounded (e.g. `SUBAGENT_LIMIT`, `TASK_LIMIT`, `TOOL_EVENT_LIMIT`) and exposes task liveness, latest tool, tool durations, and per-node bucket sizes. A `compact` versus `full` detail mode lets callers trade context budget for completeness.

### Workflow Board

Workflow control is exposed as a single multiplexed tool, `workflow_board`, in [src/node/proxy/workflow-board-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/workflow-board-tools.js). It accepts an `action` dispatch (`create_item`, `update_item`, `decompose`, `update_board`, `control_board`, `update_column`, `delete_item`, `transition`, plus event and recovery variants) and returns JSON-encoded results through the standard MCP `content` array. The board owns columns, items, automation rules, resource groups, approval modes, and an event log.

## Local Development and Operations

According to the README, the canonical local flow is `npm install && npm run build && npm start`. The `build` step produces the production browser bundle in `dist/web`; the server prefers that bundle and falls back to `web/` when it is missing, with `AGENT_PORTAL_WEB_ROOT` available as an override for container builds ([README.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/README.md)). [package.json](https://github.com/rnd-pro/mcp-agent-portal/blob/main/package.json) also defines `npm run dev` for source-module development against `web/`, plus a battery of `test:unit`, `test:integration`, `test:audit`, and `xr:*` smoke diagnostics.

Two deployment-time concerns are worth highlighting. First, the `.agent-portal/` directory is intentionally designed to be a **private submodule**; the README documents the per-developer step of setting `submodule..agent-portal.url` before `git submodule update --init .agent-portal`. Second, the same pattern applies to the bundled MCP server submodules under `packages/`. Both are required for full local functionality.

## Common Failure Modes

A few failure modes are visible directly in the source:

- **Empty or malformed frontmatter.** `parseMarkdownFrontmatter` throws when content is not a non-empty string and returns `null` when the `---` delimiters are missing ([src/node/agents/frontmatter.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/frontmatter.js)). Agents authored without a leading `---` block will not pick up metadata.
- **Stale tool index.** The cached registry in the multiplexer only refreshes when explicitly rebuilt; topology changes in a child server will not be reflected until the index is invalidated ([src/node/proxy/tool-index.ctx.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/tool-index.ctx.md)).
- **Blocked file paths in demo mode.** The demo-mode file walker explicitly blocks `.env`, `.git`, `.ssh`, `node_modules`, `secrets`, and `tmp` segments and caps reads at 96 KiB ([src/node/server/demo-mode.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/demo-mode.js)). Requests for those paths are silently dropped.
- **Context-budget blowups.** The full development map can exceed an upstream agent's context window, which is why `get_portal_status` defaults to a bounded `compact` view ([src/node/proxy/mcp-multiplexer.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-multiplexer.js)).

## See Also

- `package.json` — scripts, binary, and module entry points
- `README.md` — quickstart, submodules, and skill directory layout
- `src/node/agents/agent-parser.js` — agent and skill composition rules
- `src/node/proxy/mcp-multiplexer.js` — meta-tool surface exposed to clients
- `src/node/proxy/portal-orchestrator-tools.js` — orchestrator hints and repair logic
- `src/node/server/marketplace-registry.js` — bundled MCP server catalogue

---

<a id='page-mcp-gateway'></a>

## MCP Gateway and Tool Orchestration

### Related Pages

Related topics: [Overview and System Architecture](#page-overview), [Agent Runtime and CLI Adapters](#page-agent-runtime), [Web Dashboard and Frontend](#page-web-dashboard)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/node/proxy/mcp-multiplexer.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-multiplexer.js)
- [src/node/proxy/portal-orchestrator-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/portal-orchestrator-tools.js)
- [src/node/proxy/tool-index.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/tool-index.js)
- [src/node/proxy/tool-index.ctx.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/tool-index.ctx.md)
- [src/node/proxy/mcp-tool-visibility.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-tool-visibility.js)
- [src/node/proxy/workflow-board-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/workflow-board-tools.js)
- [src/node/server/marketplace-registry.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/marketplace-registry.js)
- [src/node/server/web-server.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/web-server.js)
- [src/node/agents/agent-parser.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/agent-parser.js)
- [src/node/agents/frontmatter.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/frontmatter.js)
- [package.json](https://github.com/rnd-pro/mcp-agent-portal/blob/main/package.json)
- [README.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/README.md)
</details>

# MCP Gateway and Tool Orchestration

## Overview

The MCP Gateway is the unified orchestration entry point of `mcp-agent-portal`. It presents a single MCP-compatible facade to external clients (IDEs, the portal web UI, and CLI tools) while spawning and supervising multiple child MCP servers in the background. According to the project README, "Agent Portal is the public orchestration entrypoint. External MCP clients use portal tools such as `create_chat`, `resume_chat`, `get_chat_task_result`, `get_orchestrator_status`, and `get_development_map`; raw Agent Pool tools stay internal to the portal runtime and are blocked from public discovery and `call_tool`." Source: [README.md]()

The gateway combines three concerns:

1. A multiplexed tool surface — public orchestrator tools merged with whitelisted child tools.
2. A development map — bounded telemetry returned alongside every orchestration response (`subagentMap`, `activityMap`, `taskMap`, `toolMap`, `latestTools`, usage totals, liveness).
3. An adapter and plugin layer — heterogeneous CLI adapters (Antigravity, Claude, Codex, OpenCode) and external plugins (Telegram, Slack, GitHub).

## Architecture

The gateway runs as a detached singleton backend; multiple IDE windows attach to the same stdio pipe so child MCP servers are not duplicated. Source: [README.md](). The proxy manager spawns children (`project-graph-mcp`, `agent-pool-mcp`, marketplace servers) and forwards `tools/list`, `tools/call`, and notifications. Source: [src/node/proxy/mcp-multiplexer.js]()

```mermaid
flowchart LR
    A[IDE / Web UI / CLI] -->|stdio or HTTP| B[MCP Gateway]
    B --> C[Orchestrator Meta Tools]
    B --> D[ToolIndex]
    B --> E[Workflow Board Tools]
    C --> F[Development Map]
    D --> G[project-graph-mcp]
    D --> H[agent-pool-mcp]
    D --> I[Marketplace Servers]
    B --> J[Adapter Pool]
    J --> K[antigravity / claude / codex / opencode]
```

## Tool Index and Discovery

The `ToolIndex` class maintains a cached registry of tools exposed by every child MCP server. It rebuilds by calling `tools/list` on each child server with a 5-second timeout (`CHILD_TOOLS_LIST_TIMEOUT_MS`), storing entries keyed by tool name with the originating server attached. The class also tracks failures and a per-tag name map for filter queries. Source: [src/node/proxy/tool-index.js]()

Filtering is layered on top of the index:

- **Server-level** — only servers for which `isPublicMcpToolServer(name)` returns true are indexed. The `agent-pool` server is hard-coded as internal (`INTERNAL_MCP_TOOL_SERVERS`). Source: [src/node/proxy/mcp-tool-visibility.js]()
- **Tool-level** — a denylist (`INTERNAL_MCP_TOOL_NAMES`) hides delegation, scheduling, pipeline, group, script, and workflow-board primitives so they cannot leak into external discovery or be invoked through `call_tool`. Source: [src/node/proxy/mcp-tool-visibility.js]()

The web server maintains its own short-lived cache (`TOOL_CACHE_TTL = 10_000` ms) that mirrors the index for HTTP `tools/list` responses. When the cache is cold, `_collectAllTools` triggers `_refreshToolCache` and awaits its completion before returning. Source: [src/node/server/web-server.js]()

## Orchestrator Meta Tools

The portal exposes a fixed set of orchestrator tools that wrap index lookup, child invocation, chat lifecycle, and development map inspection. Each entry follows an MCP-compatible `inputSchema` and is wired through `portal-orchestrator-tools.js`. Source: [src/node/proxy/portal-orchestrator-tools.js]()

| Tool | Purpose |
| --- | --- |
| `discover_tools` | Search by keyword, tag, or server across the public tool surface. |
| `call_tool` | Invoke a public tool on a connected child MCP server by name. |
| `get_portal_status` | Server health, tool counts, tags, system load, telemetry. |
| `get_development_map` | Bounded orchestration map (`subagentMap`, `activityMap`, `taskMap`, `toolMap`, `latestTools`). |
| `create_chat` / `resume_chat` / `get_chat_task_result` | Manage Agent Chat sessions through the orchestrator. |
| `get_orchestrator_status` | Runtime liveness and task-state errors. |
| `list_workflows` / `get_board_state` | Surface the workflow board under the same gateway. |

The descriptions explicitly state that "Agent Pool tools are internal to Agent Portal and are not callable through this meta-tool." Source: [src/node/proxy/mcp-multiplexer.js](). Workflow board actions (`create_item`, `update_item`, `decompose`, `update_board`, `control_board`, `update_column`, `transition`, `delete_item`) are routed through `handleWorkflowBoardTool` inside the same facade. Source: [src/node/proxy/workflow-board-tools.js]()

## Marketplace Registry

The marketplace ships with a curated `REGISTRY` of trusted MCP servers grouped into four categories: `rnd-pro`, `official`, `google`, and `community`. Each entry includes `command`, `args`, `source`, and an optional `envHint` listing required environment variables. Notable entries include `project-graph` and `agent-pool` (rnd-pro), the official `filesystem`, `github`, `slack`, `postgres`, `sqlite`, `brave-search`, `fetch`, and `sequential-thinking` servers, plus `google-maps` and `gdrive`. Two community entries — `sentry` and `linear` — round out the catalogue. Source: [src/node/server/marketplace-registry.js]()

Consumers query the registry through `findInRegistry(name)` and `getRegistryByCategory()`. Source: [src/node/server/marketplace-registry.js]()

## Agent and Skill Composition

Agents and skills are loaded from `.agent-portal/agents/*.md` and `.agent-portal/skills/*.md`. The parser supports a YAML frontmatter schema (`name`, `description`, `role`, `icon`, `color`, `resource_group`, `provider`, `model`, `models`, `skills`, `visibleAgents`) plus two composition modes:

- `skills: [X, Y]` — skill content is prepended before the agent body.
- `{{skill:Z}}` — placeholder resolved inline where it appears. Source: [src/node/agents/agent-parser.js]()

Frontmatter parsing handles scalars, inline arrays, multiline arrays, inline objects, and nested objects, returning `{ meta, frontmatter, body }` so downstream consumers do not need to re-parse. Source: [src/node/agents/frontmatter.js]()

## Configuration and Operations

The `package.json` defines the `mcp-agent-portal` binary, the production build (`npm run build` produces `dist/web`), `npm start`, `npm run dev` for source-module development against `web/`, and the test suites (`test:unit`, `test:integration`, `test:audit`). Source: [package.json](). A user-level `~/.agent-portal/agent-portal.json` overrides `mcpServers`, `adapters`, and (optionally) an `anthropicGateway` block with `defaultModel`, `plannerModel`, and per-provider `apiKeyEnv` references. Source: [README.md]()

## Common Failure Modes

- **Empty public surface** — when no child server reports tools, the gateway falls back to the cached list and emits only `META_TOOLS`. A crashed child disappears from the index until the proxy respawns it.
- **Internal tool leakage** — calls to `delegate_task`, `consult_peer`, or workflow-board primitives through `call_tool` are blocked by `isInternalMcpToolName`. Source: [src/node/proxy/mcp-tool-visibility.js]()
- **Stale cache** — the 10-second web-server cache can serve a slightly outdated list during topology changes; the context note recommends rebuilding the index after child server topology changes. Source: [src/node/proxy/tool-index.ctx.md]()

## See Also

- Web Dashboard and Routing
- Adapter Pool and Runtime Agents
- Workflow Board Tools
- Marketplace and Plugin System

---

<a id='page-agent-runtime'></a>

## Agent Runtime and CLI Adapters

### Related Pages

Related topics: [Overview and System Architecture](#page-overview), [MCP Gateway and Tool Orchestration](#page-mcp-gateway), [Web Dashboard and Frontend](#page-web-dashboard)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/node/adapters/index.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/adapters/index.js)
- [src/node/agents/agent-parser.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/agent-parser.js)
- [src/node/agents/frontmatter.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/frontmatter.js)
- [src/node/proxy/mcp-multiplexer.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-multiplexer.js)
- [src/node/proxy/portal-orchestrator-tools.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/portal-orchestrator-tools.js)
- [src/node/proxy/orchestration-development-map.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/orchestration-development-map.js)
- [src/node/server/api-routes-projects.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/api-routes-projects.js)
- [package.json](https://github.com/rnd-pro/mcp-agent-portal/blob/main/package.json)
- [README.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/README.md)
</details>

# Agent Runtime and CLI Adapters

## Overview

The Agent Runtime and CLI Adapters layer in `mcp-agent-portal` connects Agent Portal's MCP control plane to concrete LLM execution backends. It is composed of two cooperating subsystems: the **adapter index** under `src/node/adapters/`, which exposes per-provider runtime metadata (model catalogs, resource groups, CLI discovery), and the **agent parser** under `src/node/agents/`, which loads agent definitions from project-local Markdown files. The orchestrator tools in `src/node/proxy/` consume this metadata at runtime to spawn chats, dispatch subagents, and feed the bounded development map back to the calling model (Source: [README.md](); [src/node/adapters/index.js:1-80]()).

The package entry point is `bin/mcp-agent-portal.js`; running `npm start` boots the detached singleton backend, while `npm run test:unit` and `npm run test:integration` exercise this layer end-to-end (Source: [package.json:5-21]()).

## Adapter Index and Provider Resolution

`src/node/adapters/index.js` is the registry that downstream consumers (UI, orchestrator, marketplace) query for adapter metadata. It exports `getDefaultProviderModels()`, which currently returns the Claude model catalog (`CLAUDE_CODE_MODEL_CATALOG`) for the `claude` provider, and `getEffectiveModels(provider)`, which composes the effective model list for a provider using a layered priority:

1. user-configured models from `getStateGraph().getAllProviderModels()`
2. CLI-discovered models for `opencode` (`_cliModels`) and `antigravity` (`_antigravityModels`)
3. built-in `DEFAULT_MODELS` (e.g. `['default']` for `antigravity`)

Human-readable model names come from `CLAUDE_CODE_MODEL_NAMES` and the `_openRouterMetadata` map, so the same `val` can surface as a friendly `text` in the cascading select (Source: [src/node/adapters/index.js:1-80]()).

The adapter index also exposes `setPortalRoot(root)`, `resolveAgentRoot()`, and `getAgentList()`. `getAgentList()` caches the result for 5 seconds and re-resolves the `.agent-portal/agents` and `.agent-portal/skills` directories on cache miss; `invalidateAgentList()` forces a rebuild (Source: [src/node/adapters/index.js:80-120]()).

### Resource Group Preferences

`loadResourceGroupPreferences()` reads `resource-groups.json` and returns three artifacts consumed by the UI:

- `byProvider` — preferred model IDs per provider (e.g. `claude → ["opus-4.6"]`)
- `defaultModel` — the first encountered model, used as the form default
- `groups[]` — full group entries with `provider`, `model`, `profiles`, `rotation_mode`, `approval_mode`, `policy`, `max_agents`, and `timeout`

The UI uses this data to build the cascading select `pool → Agent → Provider → Model → ChatType` (Source: [src/node/adapters/index.js:120-180]()).

## Agent Parser and Frontmatter

`src/node/agents/agent-parser.js` parses `.agent-portal/agents/*.md` files into runtime agent entities. Each file uses YAML frontmatter whose supported schema includes `name`, `description`, `role`, `icon`, `color`, `resource_group`, `provider`, `model`, `models[]`, `skills[]`, and `visibleAgents[]` (Source: [src/node/agents/agent-parser.js:1-16]()).

Skills are composed in two distinct ways:

- `skills: [X, Y]` — the resolved content of skills `X` and `Y` is prepended **before** the agent body
- `{{skill:Z}}` — skill `Z` is resolved **inline** at the position where the placeholder appears in the body

Skill lookups are cached for 2 seconds in `_skillCache` and recomputed by walking `.agent-portal/skills/` recursively on cache miss (Source: [src/node/agents/agent-parser.js:23-50]()).

The companion frontmatter parser in `src/node/agents/frontmatter.js` is intentionally minimal but covers scalars, inline arrays, multiline arrays, inline objects, and nested objects, which is sufficient for the agent and skill files. It returns `{ meta, frontmatter, body }` and throws if the input is not a non-empty string (Source: [src/node/agents/frontmatter.js:1-40]()).

## Chat Routing and Runtime Hooks

The MCP multiplexer exposes a flat `create_chat` tool whose inputs include:

- `name` — chat title
- `adapter` — runtime adapter (`pool`, `antigravity`, …). Optional; default is the Agent Portal orchestrator
- `agent` / `agent_slug` — role slug. Root Agent Portal chats route through the orchestrator; specialist slugs apply **only** to child chats with `parentChatId`
- `parentChatId` — when present, the new chat is a subagent of an existing chat

(Source: [src/node/proxy/mcp-multiplexer.js:1-50]()).

After every orchestration step, `src/node/proxy/orchestration-development-map.js` emits a bounded `development map` plus structured `promptHints`. The hints fall into categories such as `tooling` (e.g. "Review latest tool activity") and `review` (e.g. "Aggregate subagent outputs"), each carrying a `chatId` / `taskId` / `priority` for the next agent step. Tooling hints are escalated to `priority: 'high'` while a tool is in `running` state (Source: [src/node/proxy/orchestration-development-map.js:1-50](); [src/node/proxy/portal-orchestrator-tools.js:1-40]()).

The HTTP API in `src/node/server/api-routes-projects.js` exposes `GET /api/cli/config` and `POST /api/cli/config`, which persist per-project CLI overrides via `sg.setGlobalCli(...)` and `sg.updateProject(projectId, { cli })`. This lets the adapter layer swap providers without restarting the detached backend (Source: [src/node/server/api-routes-projects.js:1-30]()).

```mermaid
flowchart LR
  UI[Portal UI<br/>Cascading Select] --> MC[MCP Multiplexer<br/>create_chat]
  MC -->|adapter, agent, parentChatId| ORC[Portal Orchestrator]
  ORC -->|parse .agent-portal/agents/*.md| AP[agent-parser.js]
  ORC -->|getEffectiveModels(provider)| AI[adapter index.js]
  AI -->|CLAUDE_CODE_MODEL_CATALOG<br/>DEFAULT_MODELS<br/>_cliModels| CL[claude / opencode /<br/>antigravity / pool]
  ORC -->|development map + promptHints| DM[orchestration-development-map.js]
  DM --> UI
```

## See Also

- [Project Graph MCP](https://github.com/rnd-pro/project-graph-mcp) — AST-based codebase analysis used as a downstream MCP server
- [Agent Pool MCP](https://github.com/rnd-pro/agent-pool-mcp) — internal execution runtime that the `pool` adapter wraps
- [Symbiote Engine](https://github.com/RND-PRO/symbiote-engine) — runtime, CLI, registry, persistence, and handlers
- [MCP Multiplexer and Gateway Tools](./mcp-multiplexer-and-gateway-tools.md)
- [Agent Frontmatter Schema Reference](./agent-frontmatter-schema.md)

---

<a id='page-web-dashboard'></a>

## Web Dashboard and Frontend

### Related Pages

Related topics: [Overview and System Architecture](#page-overview), [MCP Gateway and Tool Orchestration](#page-mcp-gateway), [Agent Runtime and CLI Adapters](#page-agent-runtime)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [web/index.html](https://github.com/rnd-pro/mcp-agent-portal/blob/main/web/index.html)
- [web/app.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/web/app.js)
- [web/router-registry.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/web/router-registry.js)
- [web/state.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/web/state.js)
- [web/dashboard-state.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/web/dashboard-state.js)
- [web/style.css](https://github.com/rnd-pro/mcp-agent-portal/blob/main/web/style.css)
- [src/node/server/web-server.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/web-server.js)
- [src/node/server/demo-mode.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/demo-mode.js)
- [src/node/proxy/tool-index.ctx.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/tool-index.ctx.md)
- [src/node/proxy/mcp-multiplexer.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/proxy/mcp-multiplexer.js)
- [src/node/agents/agent-parser.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/agent-parser.js)
- [src/node/agents/frontmatter.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/agents/frontmatter.js)
- [src/node/server/marketplace-registry.js](https://github.com/rnd-pro/mcp-agent-portal/blob/main/src/node/server/marketplace-registry.js)
- [README.md](https://github.com/rnd-pro/mcp-agent-portal/blob/main/README.md)
</details>

# Web Dashboard and Frontend

## Overview and Scope

The Web Dashboard is the browser-resident control surface of **mcp-agent-portal**. It renders the project's agents, skills, workflows, runtime telemetry, and (optionally) spatial / WebXR panels for the host Node.js portal. The dashboard is served by the same Node process that hosts the MCP proxy and orchestrator tools, so the UI, public MCP servers, and Agent Pool tools share a single origin and lifecycle. Source: [README.md:1-20]()

The UI is intentionally framework-light: plain ES-module JavaScript rendered into a static `index.html` shell and styled by a single global stylesheet. This keeps the front end auditable and easy to embed in container builds. Source: [web/index.html:1-1](), [web/style.css:1-1]()

In the public demo mode, the dashboard reads from the `demo/mock-data.js` fixture set (chats, groups, pipelines, tools, skeleton, skills, workflows) instead of a real workspace, so reviewers can inspect the layout without exposing private repository URLs or runtime state. Source: [src/node/server/demo-mode.js:1-40]()

## Bootstrap and Module Layout

The browser entry point is `web/app.js`. It composes the providers (router, state, panels) that populate the DOM, and the router registry wires individual route keys to the panel modules that should render them. Source: [web/app.js:1-1](), [web/router-registry.js:1-1]()

Two state modules split responsibility:

| Module | Responsibility |
| --- | --- |
| `web/state.js` | Global app state — current chat, active route, connected MCP servers, user preferences. |
| `web/dashboard-state.js` | Dashboard-specific derived state — panel visibility, development-map snapshots, prompt-hint suggestions consumed by the orchestrator UI. |

Source: [web/state.js:1-1](), [web/dashboard-state.js:1-1]()

State is kept in memory rather than persisted to `localStorage` in the default build; this avoids leaking chat contents and tool arguments when the page reloads, which is the expected behavior for a portal that mediates agent execution. Source: [src/node/server/web-server.js:38-60]()

## Routing, Panels, and Surfaces

`router-registry.js` maps URL fragments or hash routes to render functions. The registry is the only place that knows which panel owns which route, so adding a new surface (for example, an additional graph lens) requires registering one entry rather than editing the bootstrap. Source: [web/router-registry.js:1-1]()

In demo mode, the panel composition is described declaratively as a graph of `cluster` and `panel` nodes with `focusPath` pointers into the source modules that produce them, which is how the public demo keeps panels aligned with the real runtime contract without re-implementing it. Source: [src/node/server/demo-mode.js:300-340]()

The same surface is reused for spatial rendering. The README documents a `#spatial?project=agent-portal&target=graph&texture=strict` route that switches panels into HTML-in-Canvas textures and a `production-spatial-ready` XR gate. Source: [README.md:80-110]()

The dashboard exposes several user-facing panels backed by the MCP multiplexer:

- **Agents / Skills** — populated from `.agent-portal/agents/*.md` and `.agent-portal/skills/`, parsed by `agent-parser.js` and `frontmatter.js` (scalars, inline arrays, multiline arrays, inline objects, nested objects). Source: [src/node/agents/agent-parser.js:1-30](), [src/node/agents/frontmatter.js:1-20]()
- **Tools** — driven by `tool-index.js`, which rebuilds a cached registry by calling `tools/list` on each connected public MCP server and supports keyword, tag, and server-name filters. Source: [src/node/proxy/tool-index.ctx.md:1-10]()
- **Chat / Runtime** — surfaces `create_chat`, `get_portal_status`, and the bounded development map returned by the orchestrator (compact by default; `detail: "full"` returns the complete map). Source: [src/node/proxy/mcp-multiplexer.js:1-40]()
- **Marketplace** — reads the static registry grouped by category (`official`, `google`, `community`, …) and surfaces required environment hints such as `BRAVE_API_KEY` or `LINEAR_API_KEY`. Source: [src/node/server/marketplace-registry.js:1-60]()

## Server Integration and Build Pipeline

The dashboard is served by `src/node/server/web-server.js`. `serveStaticFile` resolves a request path against `WEB_DIR`, `packages/`, reviewed vendor directories, and shared iso helpers; directories fall back to `index.html`, and the handler answers both `GET` and `HEAD`. Source: [src/node/server/web-server.js:30-60]()

Two root resolutions matter for deployments:

1. `npm run build` produces a production bundle in `dist/web`. Normal MCP / server starts prefer that bundle when it exists and otherwise fall back to the `web/` source directory. Source: [README.md:25-40]()
2. Setting `AGENT_PORTAL_WEB_ROOT` overrides both, which is the supported way to point a container build at a prebuilt UI directory. Source: [README.md:25-40]()

Unknown `/api/` requests are proxied to a backend MCP server (defaulting to `project-graph`), so the same origin can host the UI and the public MCP traffic behind one port. Source: [src/node/server/web-server.js:60-90]()

## Common Failure Modes

- **Stale UI in production.** If `dist/web` was built against an older Node module graph, symptom panels may render empty. Rebuild with `npm run build` and verify the bundle timestamp, or unset `AGENT_PORTAL_WEB_ROOT` to fall back to `web/`. Source: [README.md:25-40]()
- **403 Forbidden vendor.** The static handler refuses to serve from vendors that are not on the allow-list; the request path must resolve under `WEB_DIR`, `packages/`, a reviewed vendor, or a shared iso helper. Source: [src/node/server/web-server.js:30-60]()
- **Empty panels in XR mode.** When HTML-in-Canvas texture upload is unavailable on the checking browser, the strict-mode status is `XR texture gate: blocked:html-in-canvas-unsupported` and `Three rendered panels: 0/4`; this is an expected pre-headset diagnostic state, not a runtime failure. Source: [README.md:80-110]()
- **Tool list drift.** `tool-index.js` only rebuilds its cache after child-server topology changes; if a recently attached MCP server's tools do not appear, force a rebuild or restart so `tools/list` is reissued. Source: [src/node/proxy/tool-index.ctx.md:5-10]()

## See Also

- MCP Proxy and Multiplexer
- Agent Parser and Skill Resolution
- XR / Spatial Surfaces
- Marketplace MCP Registry

---

<!-- evidence_pipeline_checked: true -->

---

## Pitfall Log

Project: rnd-pro/mcp-agent-portal

Summary: Found 7 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Configuration risk - Configuration risk requires verification.

## 1. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/rnd-pro/mcp-agent-portal

## 2. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/rnd-pro/mcp-agent-portal

## 3. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/rnd-pro/mcp-agent-portal

## 4. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/rnd-pro/mcp-agent-portal

## 5. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/rnd-pro/mcp-agent-portal

## 6. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/rnd-pro/mcp-agent-portal

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/rnd-pro/mcp-agent-portal

<!-- canonical_name: rnd-pro/mcp-agent-portal; human_manual_source: deepwiki_human_wiki -->
