Skip to content

feat(mcp): add sampling request handler (1/3 for #10704) - #27130

Closed
cbcoutinho wants to merge 1 commit into
google-gemini:mainfrom
cbcoutinho:feat/mcp-sampling-handler
Closed

feat(mcp): add sampling request handler (1/3 for #10704)#27130
cbcoutinho wants to merge 1 commit into
google-gemini:mainfrom
cbcoutinho:feat/mcp-sampling-handler

Conversation

@cbcoutinho

@cbcoutinho cbcoutinho commented May 15, 2026

Copy link
Copy Markdown
Contributor

Summary

First of three PRs implementing MCP client sampling support per issue #10704. This PR adds only the pure core handler — no UI, no client wiring, no policy integration, no capability advertised to servers yet.

Background

The prior consolidated PR #12801 was closed in favor of a 3-PR breakdown agreed with @jackwotherspoon (comment), starting with the explicit ask to "extract the sampling logic into its own named function so we don't bloat connectToMcpServer."

Planned follow-ups (separate PRs):

  • PR 2: McpSamplingDialog + consent UI + CoreEvent.McpSamplingRequest event, with an isolated example harness (modeled on the ask-user dialog from feat: add AskUserDialog for UI component of AskUser tool #17344)
  • PR 3: Register the handler in connectToMcpServer, advertise sampling: {} capability, wrap with policy/approval, add the integration test

The transport memory-leak fix that originally rode along in #12801 has already shipped separately in #18054.

What's in this PR

packages/core/src/tools/mcp-sampling.ts — a single exported async function:

export async function handleSamplingRequest(
  request: CreateMessageRequest,
  config: Config,
  abortSignal: AbortSignal,
): Promise<CreateMessageResult>

What it does:

  • Converts MCP SamplingMessage[] → Gemini Content[]
    • text{ text } parts
    • image{ inlineData: { mimeType, data } } parts
    • audio → rejected with a clear error (deferred)
    • Unknown content types (e.g. tool_use from newer SDK revisions) → rejected
    • role: assistantmodel
  • Passes through optional generation params:
    • systemPromptsystemInstruction
    • maxTokensmaxOutputTokens
    • temperaturetemperature
    • stopSequencesstopSequences
  • Calls config.getContentGenerator() directly (intentionally bypasses GeminiClient so the agent's core system prompt does NOT leak into server-driven sampling)
  • Uses config.getModel(); modelPreferences hints from the request are ignored (per the RFC v1 — client retains model authority)
  • Maps FinishReason.MAX_TOKENS → MCP maxTokens; everything else → endTurn
  • Generates a fresh mcp-sampling-<uuid> prompt id per call

packages/core/src/tools/mcp-sampling.test.ts — 14 unit tests covering text + image, audio/unknown-type rejection, role mapping, conversation order, param pass-through, param omission, modelPreferences ignored, finish-reason mapping, empty/no-text candidate errors, and prompt-id uniqueness.

No changes to mcp-client.ts or anywhere else. The handler isn't reachable yet — wiring lives in PR 3.

Test plan

  • npm run typecheck -w @google/gemini-cli-core
  • npx eslint packages/core/src/tools/mcp-sampling.ts packages/core/src/tools/mcp-sampling.test.ts
  • npx vitest run packages/core/src/tools/mcp-sampling.test.ts — 14/14 pass
  • npx vitest run packages/core/src/tools/ — 533 pass, 2 pre-existing skipped, no regressions
  • End-to-end manual verification — N/A in this PR; handler is not wired

This PR was generated with the help of AI, and reviewed by a Human

@cbcoutinho
cbcoutinho requested a review from a team as a code owner May 15, 2026 21:21
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces the core handler logic for MCP client sampling support, fulfilling the first phase of the implementation plan. It focuses on the functional transformation between MCP sampling requests and Gemini generation calls, maintaining a clean separation of concerns by excluding UI components and transport wiring, which are reserved for subsequent PRs.

Highlights

  • Core Sampling Handler: Implemented the handleSamplingRequest function to process MCP sampling requests by mapping them to Gemini content generation calls.
  • Data Transformation: Added logic to convert MCP message formats (text, image) into Gemini-compatible content structures while explicitly rejecting unsupported types like audio.
  • Configuration Mapping: Ensured generation parameters such as system prompts, temperature, and stop sequences are correctly passed through to the underlying content generator.
  • Comprehensive Testing: Added 14 unit tests covering various scenarios including role mapping, parameter pass-through, error handling, and finish-reason conversion.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@google-cla

google-cla Bot commented May 15, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@github-actions

github-actions Bot commented May 15, 2026

Copy link
Copy Markdown

🛑 Action Required: Evaluation Approval

Steering changes have been detected in this PR. To prevent regressions, a maintainer must approve the evaluation run before this PR can be merged.

Maintainers:

  1. Go to the Workflow Run Summary.
  2. Click the yellow 'Review deployments' button.
  3. Select the 'eval-gate' environment and click 'Approve'.

Once approved, the evaluation results will be posted here automatically.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for the Model Context Protocol (MCP) sampling/createMessage request. It includes a new core handler, handleSamplingRequest, which converts MCP requests into Gemini API calls and maps the responses back to the MCP format. The implementation supports text and image content blocks while explicitly rejecting audio and unsupported types. Comprehensive unit tests have been added to verify role mapping, content conversion, parameter passing, and error handling. I have no feedback to provide as the implementation is solid and well-tested.

Implements the pure core of MCP sampling support: a single
`handleSamplingRequest()` function in `packages/core/src/tools/mcp-sampling.ts`
that converts an MCP `CreateMessageRequest` to a Gemini `ContentGenerator` call
and maps the response back to a `CreateMessageResult`.

This is the first of three planned PRs for google-gemini#10704, per maintainer guidance to
extract sampling logic into its own named function rather than inlining it in
`mcp-client.ts`. PR 2 will add the consent dialog/UI, PR 3 will register the
handler in `connectToMcpServer`, advertise the `sampling: {}` capability, and
wire in policy/approval.

Scope of this PR:
- text and image content blocks (audio + other types rejected with clear
  error messages — forward-compatible with future SDK revisions)
- pass-through of `systemPrompt`, `temperature`, `maxTokens`, `stopSequences`
- uses `config.getContentGenerator()` directly to bypass the agent's core
  system prompt (so the server's `systemPrompt` is honored cleanly)
- uses `config.getModel()`; `modelPreferences` hints are ignored per RFC v1
- maps Gemini `FinishReason.MAX_TOKENS` -> MCP `maxTokens`, everything else
  -> `endTurn`
- 14 unit tests, no changes to `mcp-client.ts` or any other file
@cbcoutinho
cbcoutinho force-pushed the feat/mcp-sampling-handler branch from 98bcb01 to 566b5b2 Compare May 15, 2026 21:27
@gemini-cli gemini-cli Bot added priority/p2 Important but can be addressed in a future release. area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality labels May 15, 2026
@cbcoutinho cbcoutinho closed this May 21, 2026
@sripasg sripasg added the size/l A large sized PR label Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality priority/p2 Important but can be addressed in a future release. size/l A large sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants