Skip to content

refactor: improve execution tool guidance for script execution#431

Merged
Jazzcort merged 1 commit into
rhel-lightspeed:mainfrom
Jazzcort:improve-toolcall-result-instruction
May 21, 2026
Merged

refactor: improve execution tool guidance for script execution#431
Jazzcort merged 1 commit into
rhel-lightspeed:mainfrom
Jazzcort:improve-toolcall-result-instruction

Conversation

@Jazzcort
Copy link
Copy Markdown
Contributor

This commit refactors MCP app detection and enhances the tool feedback loop to guide clients toward the correct execution tools.

Key changes:

  • Extracted _use_mcp_app_for_client from server.py into a public use_mcp_app_for_client utility in mcp_app.py for cross-module reuse.
  • Added a _pick_execution_tool helper in run_script.py to dynamically determine the right tool (run_script, run_script_interactive, or run_script_with_confirmation) based on script flags (readonly, needs_confirmation) and client capabilities.
  • Updated validate_script to explicitly instruct the client on which execution tool to use next in its text response.
  • Improved the error message in run_script to dynamically suggest the appropriate confirmation tool if the script requires confirmation but was called incorrectly.

@Jazzcort Jazzcort requested a review from a team as a code owner April 23, 2026 20:03
@github-actions
Copy link
Copy Markdown

For team members: test commit eb0c6cc in internal GitLab

@Jazzcort
Copy link
Copy Markdown
Contributor Author

Note: Returning needs_confirmation: true in the structured_content sometimes is not enough for the chat model to use the confirmation tool right a way. Without this patch, it's highly likely the chat model will still call run_script and hit the tool call error and then call the confirmation tool. This patch might also improve the situation when the flow just stops after validate_script without calling execution tool.

@subpop
Copy link
Copy Markdown
Member

subpop commented Apr 24, 2026

I like this idea.

@Jazzcort
Copy link
Copy Markdown
Contributor Author

Let me fix the tests! 😁

@panyamkeerthana
Copy link
Copy Markdown
Contributor

panyamkeerthana commented Apr 24, 2026

Great idea! This should guide the model into the next step of the loop😁 Just curious, which model were you using to validate the new guidance?

@Jazzcort Jazzcort force-pushed the improve-toolcall-result-instruction branch from eb0c6cc to 2fbc786 Compare April 24, 2026 18:23
@github-actions
Copy link
Copy Markdown

For team members: test commit 2fbc786 in internal GitLab

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/linux_mcp_server/tools/run_script.py 75.00% 1 Missing and 1 partial ⚠️
src/linux_mcp_server/mcp_app.py 96.29% 0 Missing and 1 partial ⚠️
Flag Coverage Δ
unittests 97.20% <92.50%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/linux_mcp_server/server.py 92.99% <100.00%> (-0.80%) ⬇️
src/linux_mcp_server/mcp_app.py 96.66% <96.29%> (-3.34%) ⬇️
src/linux_mcp_server/tools/run_script.py 96.31% <75.00%> (-0.96%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Jazzcort
Copy link
Copy Markdown
Contributor Author

@panyamkeerthana I use gemini-3.1-pro-preview most of the time for chat model.

@Jazzcort
Copy link
Copy Markdown
Contributor Author

I think I'll wait for some feedback on this. If it ends up quite positive and we want to merge this into main, I'll work on the test coverage then. 😁

Copy link
Copy Markdown
Contributor

@owtaylor owtaylor left a comment

Choose a reason for hiding this comment

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

Looks like a nice cleanup and improvement! I think we can make it a bit cleaner by using get_context() rather than feeding around client_params.

I was worried when I started looking at it it would be a big conflict with #457, but I think it won't be bad whichever lands first.

Comment thread src/linux_mcp_server/mcp_app.py Outdated
MCP_UI_EXTENSION = "io.modelcontextprotocol/ui"


def use_mcp_app_for_client(client_params: InitializeRequestParams):
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.

Passing around client_params gets really tedious. We can use fastmcp's get_context() which gets the current context (async safely), but can't avoid client_params entirely because get_context() won't work in on_initialize, as far as I recall.

Suggested change
def use_mcp_app_for_client(client_params: InitializeRequestParams):
def use_mcp_app_for_client(client_params: InitializeRequestParams | None = None):
if client_params is None:
client_params = get_context().session.client_params

Comment on lines +372 to +379
def _pick_execution_tool(readonly: bool, needs_confirmation: bool, use_mcp_app: bool):
if not needs_confirmation and readonly:
return "run_script"

if use_mcp_app:
return "run_script_interactive"
else:
return "run_script_with_confirmation"
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.

Don't see why readonly is needed here - that should already be reflected in needs_confirmation.

Suggested change
def _pick_execution_tool(readonly: bool, needs_confirmation: bool, use_mcp_app: bool):
if not needs_confirmation and readonly:
return "run_script"
if use_mcp_app:
return "run_script_interactive"
else:
return "run_script_with_confirmation"
def _pick_execution_tool(needs_confirmation: bool):
if not needs_confirmation:
return "run_script"
elif use_mcp_app_for_client():
return "run_script_interactive"
else:
return "run_script_with_confirmation"

# Verify that this script doesn't require confirmation
if script_details.needs_confirmation:
raise ToolError("This script requires confirmation. Use run_script_with_confirmation instead of run_script.")
raise ToolError(f"This script requires confirmation. Use {confirmation_tool_name} instead of run_script.")
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.

Suggested change
raise ToolError(f"This script requires confirmation. Use {confirmation_tool_name} instead of run_script.")
raise ToolError(f"This script requires confirmation. Use {_pick_execution_tool(True)} instead of run_script.")

This commit refactors MCP app detection and enhances the tool feedback loop to guide
clients toward the correct execution tools.

Key changes:
* Extracted `_use_mcp_app_for_client` from `server.py` into a public
  `use_mcp_app_for_client` utility in `mcp_app.py` for cross-module reuse.
* Added a `_pick_execution_tool` helper in `run_script.py` to dynamically determine
  the right tool (`run_script`, `run_script_interactive`, or
  `run_script_with_confirmation`) based on script flag (needs_confirmation) and
  client capabilities.
* Updated `validate_script` to explicitly instruct the client on which execution tool
  to use next in its text response.
* Improved the error message in `run_script` to dynamically suggest the appropriate
  confirmation tool if the script requires confirmation but was called incorrectly.
@Jazzcort Jazzcort force-pushed the improve-toolcall-result-instruction branch from 2fbc786 to 3a455cb Compare May 21, 2026 15:07
@github-actions
Copy link
Copy Markdown

For team members: test commit 3a455cb in internal GitLab

@Jazzcort
Copy link
Copy Markdown
Contributor Author

Not sure if I should move hide_app_tools_for_client into mcp_app.py 🤔

@Jazzcort Jazzcort requested a review from owtaylor May 21, 2026 15:32
@owtaylor
Copy link
Copy Markdown
Contributor

Not sure if I should move hide_app_tools_for_client into mcp_app.py 🤔

I'm fine with it that way.

Copy link
Copy Markdown
Contributor

@owtaylor owtaylor left a comment

Choose a reason for hiding this comment

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

LGTM

@Jazzcort Jazzcort merged commit 867d26b into rhel-lightspeed:main May 21, 2026
35 checks passed
@Jazzcort
Copy link
Copy Markdown
Contributor Author

Thanks for reviewing! 😁

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.

4 participants