Skip to content

OLS-3185: spec changes for sandbox MCP server support#94

Open
onmete wants to merge 1 commit into
openshift:mainfrom
onmete:OLS-3185-spec-mcp-sandbox
Open

OLS-3185: spec changes for sandbox MCP server support#94
onmete wants to merge 1 commit into
openshift:mainfrom
onmete:OLS-3185-spec-mcp-sandbox

Conversation

@onmete

@onmete onmete commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add LIGHTSPEED_MCP_SERVERS env var to the operator contract in configuration.md
  • Add MCP header resolution rules (ServiceAccountToken, Secret, Client source types)
  • Add Streamable HTTP transport requirement (SSE deprecated at MCP protocol level)
  • Add mcp_servers field to ProviderQueryOptions in provider-contract.md
  • Add per-provider MCP wiring rules (Claude, Gemini, OpenAI) — rules 27-29
  • Add mcp.py module to architecture module map

Design decisions

From OLS-3185 design interview:

  • Transport: Streamable HTTP (SSE deprecated since March 2025)
  • Header resolution: SA token from projected path, Secret from mounted files, Client skipped
  • All three providers wired via native SDK MCP clients
  • SDKs manage their own connections — sandbox translates config only

Test plan

  • Spec review — behavioral rules are consistent with existing patterns
  • No code changes — spec only

Made with Cursor

Add behavioral rules for parsing LIGHTSPEED_MCP_SERVERS env var,
resolving MCP headers (ServiceAccountToken, Secret), and wiring
MCP servers into all three provider SDKs via Streamable HTTP transport.

Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 2, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 2, 2026

Copy link
Copy Markdown

@onmete: This pull request references OLS-3185 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the feature request to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Add LIGHTSPEED_MCP_SERVERS env var to the operator contract in configuration.md
  • Add MCP header resolution rules (ServiceAccountToken, Secret, Client source types)
  • Add Streamable HTTP transport requirement (SSE deprecated at MCP protocol level)
  • Add mcp_servers field to ProviderQueryOptions in provider-contract.md
  • Add per-provider MCP wiring rules (Claude, Gemini, OpenAI) — rules 27-29
  • Add mcp.py module to architecture module map

Design decisions

From OLS-3185 design interview:

  • Transport: Streamable HTTP (SSE deprecated since March 2025)
  • Header resolution: SA token from projected path, Secret from mounted files, Client skipped
  • All three providers wired via native SDK MCP clients
  • SDKs manage their own connections — sandbox translates config only

Test plan

  • Spec review — behavioral rules are consistent with existing patterns
  • No code changes — spec only

Made with Cursor

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot requested review from blublinsky and harche July 2, 2026 19:21
@openshift-ci

openshift-ci Bot commented Jul 2, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign raptorsun for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Added guidance for MCP server configuration and supported environment settings.
    • Documented how MCP connections are handled across supported AI providers, including header resolution and transport requirements.
    • Clarified sandbox behavior and the expected flow for passing MCP server settings through agent requests.

Walkthrough

Three specification documents are updated to describe MCP (Model Context Protocol) server integration: a new mcp.py module concept for parsing LIGHTSPEED_MCP_SERVERS, a new ProviderQueryOptions.mcp_servers contract field, provider-specific wiring rules for Claude/Gemini/OpenAI, and configuration behavior rules for env vars, header resolution, and transport restrictions.

Changes

MCP Specification Documentation

Layer / File(s) Summary
Provider contract: mcp_servers option and provider wiring rules
.ai/spec/what/provider-contract.md
Adds ProviderQueryOptions.mcp_servers field spec and required Claude/Gemini/OpenAI SDK wiring behaviors, including allowed_tools wildcard expansion for Claude.
Provider architecture: mcp.py module and data-flow updates
.ai/spec/how/provider-architecture.md
Documents a new mcp.py module and parse_mcp_servers(), updates the /v1/agent/run data flow to pass mcp_servers, and updates Claude integration notes.
Configuration spec: env vars, parsing rules, and surface docs
.ai/spec/what/configuration.md
Adds LIGHTSPEED_MCP_SERVERS env var, JSON parsing and header resolution rules (ServiceAccountToken, Secret, Client), Streamable HTTP-only transport rule, configuration surface paths, and a planned-changes note for Client header resolution.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the spec-only MCP server support changes and names the main area affected.
Description check ✅ Passed The description clearly matches the PR changes, including env vars, MCP rules, provider wiring, and the architecture module map.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.ai/spec/what/configuration.md:
- Around line 79-87: The MCP header schema and resolution rules for
LIGHTSPEED_MCP_SERVERS allow Secret headers without a secretName, but the
sandbox cannot resolve them reliably. Update the configuration spec around the
MCP server/header definitions so secretName is mandatory whenever header.source
is Secret, and adjust the MCP header resolution guidance to use a deterministic
secret file/key path instead of “first file” in the Secret case. Reference the
MCP server config and header resolution sections so the schema and behavior stay
aligned.

In @.ai/spec/what/provider-contract.md:
- Line 61: The Claude MCP handling in the provider contract needs to avoid
unsafe wildcard expansion for `allowed_tools`. In the MCP server processing for
`ClaudeAgentOptions(mcp_servers={...})`, make sure each server name used in the
`mcp__<name>__*` pattern is validated or escaped so glob metacharacters cannot
over-match; apply this where the adapter builds `allowed_tools` for configured
MCP servers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 57937998-f688-432c-b725-c88230b1f0eb

📥 Commits

Reviewing files that changed from the base of the PR and between 11438f2 and 2dc774e.

📒 Files selected for processing (3)
  • .ai/spec/how/provider-architecture.md
  • .ai/spec/what/configuration.md
  • .ai/spec/what/provider-contract.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/lightspeed-agentic-operator (manual)

Comment on lines +79 to +87
20. **MCP server configuration.** When `LIGHTSPEED_MCP_SERVERS` is set, the sandbox MUST parse it as a JSON array of MCP server entries. Each entry has the shape `{"name": string, "url": string, "timeout": int, "headers": [{"name": string, "source": string, "secretName"?: string}]}`. The sandbox MUST build SDK-native MCP client configs from this array and pass them into provider adapters via `ProviderQueryOptions.mcp_servers` (see `provider-contract.md`). When the env var is absent or empty, no MCP servers are configured.

21. **MCP header resolution.** For each header in an MCP server entry, the sandbox MUST resolve the value based on the `source` field:

| `source` | Resolution |
|---|---|
| `ServiceAccountToken` | Read the projected SA token from `/var/run/secrets/kubernetes.io/serviceaccount/token` and format as `Bearer <token>`. |
| `Secret` | Read the first file from `/var/secrets/mcp/<secretName>/` where `secretName` is the `secretName` field on the header entry. |
| `Client` | Skip — not resolved by the sandbox. Reserved for future client-passthrough flows. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make secretName required for Secret headers.

The schema currently allows secretName to be omitted, but Secret resolution depends on it. Also, resolving the "first file" from a mount is nondeterministic if the secret has multiple keys. Require the field for source=Secret and pin a deterministic file/key path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.ai/spec/what/configuration.md around lines 79 - 87, The MCP header schema
and resolution rules for LIGHTSPEED_MCP_SERVERS allow Secret headers without a
secretName, but the sandbox cannot resolve them reliably. Update the
configuration spec around the MCP server/header definitions so secretName is
mandatory whenever header.source is Secret, and adjust the MCP header resolution
guidance to use a deterministic secret file/key path instead of “first file” in
the Secret case. Reference the MCP server config and header resolution sections
so the schema and behavior stay aligned.


26. **OpenAI client.** The OpenAI adapter constructs an async OpenAI client with optional base URL override from environment (see `configuration.md`).

27. **MCP — Claude.** When `mcp_servers` is non-empty, the Claude adapter MUST pass them as `ClaudeAgentOptions(mcp_servers={...})` using `"type": "http"` (Streamable HTTP) entries with `url` and `headers` from the resolved config. The adapter MUST add `mcp__<name>__*` wildcard patterns to `allowed_tools` for each configured MCP server so the SDK can invoke discovered tools.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Escape MCP server names before expanding allowed_tools.

mcp__<name>__* is a glob pattern. If name contains wildcard chars, the pattern can over-match and expose tools from the wrong server. Constrain the name format or escape metacharacters before interpolation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.ai/spec/what/provider-contract.md at line 61, The Claude MCP handling in
the provider contract needs to avoid unsafe wildcard expansion for
`allowed_tools`. In the MCP server processing for
`ClaudeAgentOptions(mcp_servers={...})`, make sure each server name used in the
`mcp__<name>__*` pattern is validated or escaped so glob metacharacters cannot
over-match; apply this where the adapter builds `allowed_tools` for configured
MCP servers.

@openshift-ci

openshift-ci Bot commented Jul 2, 2026

Copy link
Copy Markdown

@onmete: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/images 2dc774e link true /test images

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants