Skip to content

LCORE-1838: Wire MCP require approval#1774

Merged
tisnik merged 1 commit into
lightspeed-core:mainfrom
asimurka:wire_mcp_require_approval
May 25, 2026
Merged

LCORE-1838: Wire MCP require approval#1774
tisnik merged 1 commit into
lightspeed-core:mainfrom
asimurka:wire_mcp_require_approval

Conversation

@asimurka
Copy link
Copy Markdown
Contributor

@asimurka asimurka commented May 20, 2026

Description

Wires configured MCP approval policy to MCP creation process. Distinguishes between simple (string) and complex policies.

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement
  • Benchmarks improvement

Tools used to create PR

Identify any AI code assistants used in this PR (for transparency and review context)

  • Assisted-by: Cursor

Related Tickets & Documents

Checklist before requesting a review

  • I have performed a self-review of my code.
  • PR has passed all pre-merge test jobs.
  • If it is a core feature, I have added thorough tests.

Testing

  • Please provide detailed steps to perform tests related to this code change.
  • How were the fix/results from this change verified? Please provide relevant screenshots or results.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed approval-filter handling so generated tools respect server approval settings (supports legacy and structured approval configs), ensuring correct require_approval behavior.
  • Tests

    • Added unit tests validating default and configured approval behaviors and structured approval translations.

Review Change Stack

@asimurka asimurka marked this pull request as draft May 20, 2026 08:46
@asimurka
Copy link
Copy Markdown
Contributor Author

Needs rebase on #1773

@asimurka asimurka requested a review from jrobertboos May 20, 2026 08:46
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Warning

Review limit reached

@asimurka, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 1 review of capacity. Refill in 42 minutes and 25 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 426ff414-b7e0-48cc-a8b8-4b2ec2414fc5

📥 Commits

Reviewing files that changed from the base of the PR and between 11cd6a0 and 0d1165c.

📒 Files selected for processing (3)
  • src/app/endpoints/responses_telemetry.py
  • src/utils/responses.py
  • tests/unit/utils/test_responses.py

Walkthrough

The PR updates MCP tool construction in Responses to derive require_approval from ModelContextProtocolServer.require_approval (supporting string and structured ApprovalFilter forms), adds tests for the behavior, and fixes a telemetry import path.

Changes

MCP Approval Filter Configuration Propagation

Layer / File(s) Summary
Approval Filter Integration in MCP Tool Construction
src/utils/responses.py
Import ApprovalFilter and change MCP tool construction to read require_approval from mcp_server config, supporting both string form ("always"/"never") and structured ApprovalFilter(always=..., never=...) form.
Unit Tests for require_approval Handling
tests/unit/utils/test_responses.py
Add aliased Llama Stack ApprovalFilter import and local config ApprovalFilter import; extend TestGetMCPTools with assertions for default "never" and new async tests validating propagation of string and filter-based require_approval configs.
Telemetry import path update
src/app/endpoints/responses_telemetry.py
Change ResponsesContext import to come from models.common.responses.contexts instead of models.common.responses.responses_context.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • tisnik
  • max-svistunov
  • jrobertboos
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'LCORE-1838: Wire MCP require approval' directly and clearly describes the main change: wiring the MCP require_approval configuration into the MCP tool creation process.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@asimurka asimurka force-pushed the wire_mcp_require_approval branch from 00b9cc2 to ffe86fe Compare May 20, 2026 10:37
Comment thread src/utils/responses.py
)
tools.append(
InputToolMCP(
type="mcp",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Set up by the model automatically

Copy link
Copy Markdown
Contributor

@jrobertboos jrobertboos left a comment

Choose a reason for hiding this comment

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

LGTM

@asimurka asimurka force-pushed the wire_mcp_require_approval branch from ffe86fe to 542be8b Compare May 20, 2026 15:53
@asimurka asimurka marked this pull request as ready for review May 20, 2026 15:54
@asimurka asimurka requested a review from tisnik May 20, 2026 15:55
Copy link
Copy Markdown
Contributor

@tisnik tisnik left a comment

Choose a reason for hiding this comment

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

LGTM

@asimurka asimurka force-pushed the wire_mcp_require_approval branch from 542be8b to 11cd6a0 Compare May 25, 2026 06:55
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/utils/responses.py`:
- Around line 736-748: The explicit MCP tool path doesn’t propagate the server’s
require_approval mapping, so tools passed via
apply_mcp_headers_to_explicit_tools can bypass the ApprovalFilter; update
apply_mcp_headers_to_explicit_tools to copy/convert mcp_server.require_approval
into the tool (same mapping logic used where get_mcp_tools constructs
InputToolMCP: if require_approval is a string keep it, else build
ApprovalFilter(always=..., never=...)) and ensure
InputToolMCP.server_label/server_url are paired with the require_approval value;
add a regression test exercising resolve_tool_choice (or
resolve_client_tool_choice) that supplies an explicit tool from an MCP server
configured with "always" or an ApprovalFilter and asserts the resulting tool has
the require_approval policy applied.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: f43f80ee-04e5-4ca1-bbd3-74f9fcdd1ce5

📥 Commits

Reviewing files that changed from the base of the PR and between 542be8b and 11cd6a0.

📒 Files selected for processing (3)
  • src/app/endpoints/responses_telemetry.py
  • src/utils/responses.py
  • tests/unit/utils/test_responses.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: spectral
  • GitHub Check: unit_tests (3.13)
  • GitHub Check: unit_tests (3.12)
  • GitHub Check: E2E: library mode / ci / group 1
  • GitHub Check: E2E: server mode / ci / group 2
  • GitHub Check: E2E: library mode / ci / group 2
  • GitHub Check: E2E: library mode / ci / group 3
  • GitHub Check: E2E: server mode / ci / group 1
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-on-pull-request
  • GitHub Check: E2E Tests for Lightspeed Evaluation job
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.py: Use absolute imports for internal modules: from authentication import get_auth_dependency
Llama Stack imports: Use from llama_stack_client import AsyncLlamaStackClient
Check constants.py for shared constants before defining new ones
All modules must start with descriptive docstrings explaining purpose
Use logger = get_logger(__name__) from log.py for module logging
All functions must have complete type annotations for parameters and return types, use modern syntax (str | int), and include descriptive docstrings
Use snake_case with descriptive, action-oriented names for functions (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying function parameters
Use async def for I/O operations and external API calls
Use standard log levels with clear purposes: debug() for diagnostic info, info() for program execution, warning() for unexpected events, error() for serious problems
All classes must have descriptive docstrings explaining purpose and use PascalCase with standard suffixes: Configuration, Error/Exception, Resolver, Interface
Abstract classes must use ABC with @abstractmethod decorators
Follow Google Python docstring conventions with required sections: Parameters, Returns, Raises, and Attributes for classes

Files:

  • src/app/endpoints/responses_telemetry.py
  • src/utils/responses.py
src/app/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/app/**/*.py: FastAPI dependencies: Import from fastapi module for APIRouter, HTTPException, Request, status, Depends
Use FastAPI HTTPException with appropriate status codes for API endpoints and handle APIConnectionError from Llama Stack

Files:

  • src/app/endpoints/responses_telemetry.py
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.py: Use pytest for all unit and integration tests; do not use unittest
Use pytest.mark.asyncio marker for async tests

Files:

  • tests/unit/utils/test_responses.py
🧠 Learnings (2)
📚 Learning: 2026-04-06T20:18:07.852Z
Learnt from: major
Repo: lightspeed-core/lightspeed-stack PR: 1463
File: src/app/endpoints/rlsapi_v1.py:266-271
Timestamp: 2026-04-06T20:18:07.852Z
Learning: In the lightspeed-stack codebase, within `src/app/endpoints/` inference/MCP endpoints, treat `tools: Optional[list[Any]]` in MCP tool definitions as an intentional, consistent typing pattern (used across `query`, `responses`, `streaming_query`, `rlsapi_v1`). Do not raise or suggest this as a typing issue during code review; changing it in isolation could break endpoint typing consistency across the codebase.

Applied to files:

  • src/app/endpoints/responses_telemetry.py
📚 Learning: 2026-02-23T14:56:59.186Z
Learnt from: asimurka
Repo: lightspeed-core/lightspeed-stack PR: 1198
File: src/utils/responses.py:184-192
Timestamp: 2026-02-23T14:56:59.186Z
Learning: In the lightspeed-stack codebase (lightspeed-core/lightspeed-stack), do not enforce de-duplication of duplicate client.models.list() calls in model selection flows (e.g., in src/utils/responses.py prepare_responses_params). These calls are considered relatively cheap and removing duplicates could add unnecessary complexity to the flow. Apply this guideline specifically to this file/context unless similar performance characteristics and design decisions are documented elsewhere.

Applied to files:

  • src/utils/responses.py
🔇 Additional comments (1)
src/app/endpoints/responses_telemetry.py (1)

14-14: Approve ResponsesContext import path update in src/app/endpoints/responses_telemetry.py

  • Search found no remaining from models.common.responses.responses_context import ... / import * references, so the rename to models.common.responses.contexts appears consistently applied.

Comment thread src/utils/responses.py
@asimurka asimurka force-pushed the wire_mcp_require_approval branch from 11cd6a0 to 0d1165c Compare May 25, 2026 07:13
@tisnik tisnik merged commit 98629bd into lightspeed-core:main May 25, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants