Skip to content

feat(agent): forward configured MCP servers#903

Closed
carterusedulm2-maker wants to merge 3 commits into
openabdev:mainfrom
carterusedulm2-maker:feat/agent-mcp-servers
Closed

feat(agent): forward configured MCP servers#903
carterusedulm2-maker wants to merge 3 commits into
openabdev:mainfrom
carterusedulm2-maker:feat/agent-mcp-servers

Conversation

@carterusedulm2-maker
Copy link
Copy Markdown

@carterusedulm2-maker carterusedulm2-maker commented May 22, 2026

Discord Discussion URL: https://discord.com/channels/1504115981566345299/1507357234156540026/1507357234156540026

Summary

  • Add [agent.mcp_servers] config and convert stdio/http/sse MCP servers into ACP mcpServers.
  • Forward configured MCP servers through both session/new and session/load.
  • Redact MCP env/header values from ACP send debug logs while preserving the actual outbound payload.
  • Document generic MCP config and add Helm values/render tests.

Notes

  • Cargo.lock package version is synced from 0.8.3 to 0.8.4 because upstream Cargo.toml already reports 0.8.4 and cargo check updates the lockfile.
  • Runtime-only MemPalace sync scripts, host configs, systemd units, and validation state are intentionally not included.

Validation

  • cargo check
  • cargo test (403 passed)
  • cargo clippy -- -D warnings
  • git diff --check
  • helm lint charts/openab
  • helm template test charts/openab
  • helm template test charts/openab --set agents.kiro.enabled=false
  • helm unittest charts/openab (10 suites / 100 tests passed)

@github-actions github-actions Bot added closing-soon PR missing Discord Discussion URL — will auto-close in 3 days pending-maintainer and removed closing-soon PR missing Discord Discussion URL — will auto-close in 3 days labels May 22, 2026
@shaun-agent
Copy link
Copy Markdown
Contributor

shaun-agent commented May 22, 2026

OpenAB PR Screening

This is auto-generated by the OpenAB project-screening flow for context collection and reviewer handoff.
Click 👍 if you find this useful. Human review will be done within 24 hours. We appreciate your support and contribution 🙏

Screening report done. posted screening comment and moved the project item to `PR-Screening`.

GitHub comment: #903 (comment)
Project action: openabdev/1 item PVTI_lADOEFbZWM4BUUALzgtiSEQ moved Incoming -> PR-Screening

Intent

Forward configured MCP servers from OpenAB config into ACP sessions so deployers can make agent tools available without runtime-only host wiring. The operator-visible problem is missing or inconsistent MCP delivery to agent execution.

Feat

Feature. Adds [agent.mcp_servers], supports stdio/http/sse server definitions, sends ACP mcpServers on session/new and session/load, redacts MCP env/header values in debug logs, and documents/tests the config plus Helm rendering.

Who It Serves

Deployers and agent runtime operators first. Maintainers benefit from typed config, documented examples, and chart tests around a new integration surface.

Rewritten Prompt

Add typed MCP server configuration for agents. Parse stdio, HTTP, and SSE MCP definitions; render them from Helm values into config.toml; convert them into ACP mcpServers; include them in both new and loaded sessions; redact secret env/header values from debug logs without changing the outbound payload. Cover config parsing, ACP conversion, log redaction, and Helm rendering with focused tests and docs.

Merge Pitch

This fills a real MCP integration gap and keeps the behavior at the ACP boundary. Risk is moderate because it touches config, payload construction, Helm, and logging. Reviewers will likely focus on complete secret redaction and whether session/load forwarding is intentional for existing sessions.

Best-Practice Comparison

OpenClaw partially applies: this improves explicit delivery routing by carrying MCP config through the gateway/runtime payload. Durable job persistence, retries, isolated executions, and run logs are outside this PR.

Hermes Agent partially applies: session requests become more self-contained, which matches the scheduled-prompt principle. Daemon ticks, file locking, atomic state, and fresh scheduled sessions do not directly apply here.

Implementation Options

  1. Conservative: land config/docs first, then ACP forwarding after extra redaction tests. Lower runtime risk, slower user value.
  2. Balanced: merge this generic MCP forwarding PR after targeted review of redaction, session/load, and Helm output. Best immediate value.
  3. Ambitious: build full MCP runtime management with per-agent routing, probes, run logs, and failure reporting. Useful later, too broad now.

Comparison Table

Option Speed Complexity Reliability Maintainability User Impact Fit for OpenAB now
Conservative Medium Low High High Delayed Good if risk tolerance is low
Balanced Fast Medium Good with review Good Immediate Best fit
Ambitious Slow High Better later Risky now Strong later Poor as one PR

Recommendation

Take the balanced path. Have Masami or Pahud verify redaction and session/load semantics, then advance this PR. Keep runtime-specific MCP sync scripts, host units, and operational validation as follow-up PRs.

Copy link
Copy Markdown
Contributor

@CHC-Agent CHC-Agent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: PR #903 — feat(agent): forward configured MCP servers

LGTM with minor fix 🟡 — Format matches ACP spec; stdio verified working with codex-acp. HTTP/SSE blocked by agent-side deserialization bugs (not an OpenAB issue).

What This PR Does

Adds [agent.mcp_servers] config to OpenAB, converts stdio/http/sse MCP server definitions into ACP mcpServers array, forwards them in both session/new and session/load, and redacts secret env/header values from debug logs.

How It Works

Config is parsed from TOML into AgentMcpServerConfig structs, converted to ACP JSON-RPC format (array of server objects with name, command/url, env/headers as name-value arrays per ACP spec), and included in session setup requests. Log redaction operates on a parsed clone of the outbound JSON so the actual payload is unaffected.

E2E Verification

Deployed PR#903 to OrbStack k8s with a mock MCP server pod (HTTP + SSE endpoints) and a mock stdio script, tested against two ACP agents:

Agent stdio http
codex-acp 0.14.0 ✅ session created, agent responded ❌ deserialization error
kiro-cli 2.4.0 ❌ connection closed ❌ connection closed

Details:

  • codex-acp accepts the PR's stdio format (including name and env fields) and operates normally. HTTP fails with:
    JSON-RPC error -32602: Invalid params
    {"error": "data did not match any variant of untagged enum McpServer", "phase": "deserialization"}
    
  • kiro-cli rejects any mcpServers entry containing fields beyond command+args. Minimal format [{"command":"x","args":[]}] works, but adding name or env:[] causes the process to crash without returning a JSON-RPC error. Root cause from kiro-cli internal log (/tmp/kiro-log/kiro-chat.log):
    Connection error: Parse error: {
      "error": "data did not match any variant of untagged enum McpServer",
      "phase": "deserialization"
    }
    
    OpenAB only sees connection closed.
  • Both agents advertise mcpCapabilities.http: true but fail to deserialize HTTP server entries.

The PR's output format matches the ACP spec exactly. The failures are agent-side implementation gaps.

Findings

# Severity Finding Status
1 🟡 Helm inline-table keys for env/headers are unquoted — special chars produce invalid TOML Fixed: {{ $k }}{{ $k | toJson }}

Suggested Follow-ups (not blocking)

  • File kiro-cli issue: ACP mcpServers deserialization rejects spec-compliant fields (name, env), crashes without JSON-RPC error response
  • File codex-acp issue: HTTP transport in mcpServers fails deserialization despite advertising mcpCapabilities.http: true
  • Consider documenting which agents have been verified to work with MCP forwarding

Question for Author

The PR's validation section lists static checks (cargo test, helm unittest, etc.) but no end-to-end verification with an actual ACP agent. Which agent(s) did you test MCP forwarding against? We found that codex-acp 0.14.0 works with stdio, but kiro-cli 2.4.0 crashes on the same payload. Knowing your target agent would help confirm the expected compatibility scope.

Verification
  • cargo test: 403 passed
  • cargo clippy -- -D warnings: pass
  • helm lint: pass
  • helm unittest: 10 suites / 100 tests passed
  • E2E (codex-acp + stdio): ✅ full round-trip verified

cc @chaodu-agent

@carterusedulm2-maker
Copy link
Copy Markdown
Author

Thanks for the review and the E2E matrix.

I pushed e063fac to quote Helm inline-table keys with toJson for [agent].env, MCP env, and MCP headers, plus a regression test covering keys with - and .. Local chart validation after the fix:

  • helm lint charts/openab
  • helm unittest charts/openab (101 tests)
  • helm template test charts/openab
  • helm template test charts/openab --set agents.kiro.enabled=false
  • git diff --check

For the compatibility question: my author-side target was codex-acp with stdio MCP forwarding. The host runtime that motivated this PR is OpenAB -> codex-acp -> a stdio mempalace-mcp server configured through [agent.mcp_servers]; that path was validated with passive/live MemPalace canaries after OpenAB restart. I did not validate HTTP/SSE end-to-end before opening the PR, and I did not target kiro-cli compatibility beyond emitting the ACP mcpServers shape from OpenAB.

Your findings match the intended scope: OpenAB should forward spec-shaped MCP server definitions and avoid leaking MCP env/header values in logs; agent-side transport/deserialization gaps for HTTP/SSE or stricter clients should be tracked separately. I agree it would be useful to document the currently verified agent matrix; for this PR I would phrase it as stdio verified with codex-acp, while HTTP/SSE payload rendering is covered by config/Helm/unit tests but awaits compatible agent support.

@chaodu-agent

This comment has been minimized.

@carterusedulm2-maker
Copy link
Copy Markdown
Author

Addressed the requested changes in e2259c5.

  • F1: parse_config() already expands ${VAR} before TOML parsing, so the normal file/URL config load path was not passing literals. I still added defensive expansion inside MCP env/headers ACP serialization so direct AgentConfig::acp_mcp_servers() construction is covered too, with a regression test for both stdio env and remote headers.
  • F2: renamed the new MCP unit tests to the test_<scenario>_<expected_outcome> style.
  • F3: changed redact_acp_log_data to suppress raw log data on JSON parse/serialization failure and added a malformed-JSON regression test proving a credential-bearing payload is not returned.

Validation:

  • cargo test (405 passed)
  • cargo clippy -- -D warnings
  • git diff --check

@chaodu-agent
Copy link
Copy Markdown
Collaborator

Closing this PR — the approach conflicts with OpenAB's design philosophy.

Reason

OpenAB intentionally does not manage or inject agent-level configuration. The project's direction is for each agent to self-discover and self-configure its own MCP servers (via its native config files, mounted volumes, or built-in discovery mechanisms). OAB's role is limited to spawning agents and routing messages — it should not dictate which MCP servers an agent uses.

Injecting mcpServers through the ACP session/new payload moves configuration ownership from the agent into the host, which is the opposite of the self-discovery model we want to follow.

What would be welcome instead

A contribution that helps agents discover their own MCP configuration autonomously — for example, documentation on how to mount agent-native config files in K8s, or an init-container pattern that bootstraps each agent's home directory with its own MCP settings.


Thank you for the thorough implementation and for addressing all prior review findings. The code quality was solid — this is purely a design-direction decision.

— 超渡法師 (coordinator), on behalf of the maintainer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants