Skip to content

Include header in custom_provider to merge MCP tools#46

Merged
samdoran merged 1 commit into
rhel-lightspeed:mainfrom
r0x0d:allow-lcs-merge-tools
Apr 15, 2026
Merged

Include header in custom_provider to merge MCP tools#46
samdoran merged 1 commit into
rhel-lightspeed:mainfrom
r0x0d:allow-lcs-merge-tools

Conversation

@r0x0d

@r0x0d r0x0d commented Apr 15, 2026

Copy link
Copy Markdown
Member

With the current addition of
lightspeed-core/lightspeed-stack#1435, we can now specify the X-LCS-MMerge-Server-Tools header to allow LCS to merge the mcp tools calls and prevent the server-side mcp tools to leak on the client side

Summary by CodeRabbit

  • Chores
    • Updated proxy provider configuration to include an internal request header.
    • Enables improved integration with merge and server tooling for proxy requests.

With the current addition of
lightspeed-core/lightspeed-stack#1435, we can
now specify the X-LCS-MMerge-Server-Tools header to allow LCS to merge
the mcp tools calls and prevent the server-side mcp tools to leak on the
client side
@r0x0d
r0x0d requested a review from a team as a code owner April 15, 2026 13:33
@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 852033bd-43f9-41fa-bd7b-0325e4199f7d

📥 Commits

Reviewing files that changed from the base of the PR and between d293874 and 6860c61.

📒 Files selected for processing (2)
  • data/development/goose/custom_providers/custom_goose-proxy.json
  • data/release/goose/custom_goose-proxy.json
✅ Files skipped from review due to trivial changes (1)
  • data/development/goose/custom_providers/custom_goose-proxy.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • data/release/goose/custom_goose-proxy.json

Walkthrough

The custom_goose-proxy provider configuration in both release and development data files now sets headers to an object containing X-LCS-Merge-Server-Tools: "true" instead of null, adding that HTTP header to the proxy provider requests.

Changes

Cohort / File(s) Summary
Proxy Configuration
data/release/goose/custom_goose-proxy.json, data/development/goose/custom_providers/custom_goose-proxy.json
Changed headers from null to { "X-LCS-Merge-Server-Tools": "true" } in both release and development provider JSON files, adding the X-LCS-Merge-Server-Tools HTTP header.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a header to the custom_provider configuration to enable MCP tools merging, which is the core modification across both configuration files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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

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

@r0x0d
r0x0d force-pushed the allow-lcs-merge-tools branch from d293874 to 6860c61 Compare April 15, 2026 13:34

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@data/release/goose/custom_goose-proxy.json`:
- Around line 19-21: The chat_completions endpoint in src/goose_proxy/v1.py must
accept the incoming Request object and merge its headers into the hardcoded
headers before creating/passing headers to httpx.AsyncClient; update the
chat_completions function signature to include a fastapi.Request (or
starlette.requests.Request) parameter, read request.headers, copy/normalize them
into a dict, then merge (with hardcoded headers taking precedence where needed,
e.g., "X-LCS-Merge-Server-Tools") and pass the merged headers to the AsyncClient
request call so incoming headers are forwarded to the lightspeed-stack backend.
🪄 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: Pro Plus

Run ID: 3a565b43-6485-450e-80b8-d3ca33f8c62b

📥 Commits

Reviewing files that changed from the base of the PR and between d006595 and d293874.

📒 Files selected for processing (1)
  • data/release/goose/custom_goose-proxy.json

Comment on lines +19 to +21
"headers": {
"X-LCS-Merge-Server-Tools": "true"
},

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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for code that reads headers from the configuration file

# Search for code that accesses the 'headers' field from config/settings
rg -n -C3 '\b(config|settings|provider).*headers\b' --type=py

# Search for where custom_goose-proxy.json is loaded/parsed
rg -n -C3 'custom_goose-proxy\.json' --type=py

# Search for httpx.AsyncClient initialization to see all header usage
ast-grep --pattern 'httpx.AsyncClient($$$)'

Repository: rhel-lightspeed/goose-proxy

Length of output: 515


🏁 Script executed:

#!/bin/bash
# Search for where provider configuration is loaded/parsed
rg -n 'provider\|backend\|config' --type=py -A 3 | head -100

# Search for all JSON config file references
fd -type f -name '*.json' | xargs grep -l 'headers'

# Search for get_http_client function and its callers
rg -n 'get_http_client' --type=py -B 5 -A 10

# Look for provider configuration class definitions
ast-grep --pattern 'class Provider { $$$ }'

Repository: rhel-lightspeed/goose-proxy

Length of output: 3591


🏁 Script executed:

#!/bin/bash
# Find get_settings function definition
rg -n 'def get_settings\|from.*get_settings' --type=py

# Find settings/config related files
fd -type f -name '*settings*' -o -name '*config*'

# Look for backend class definition
rg -n 'class Backend' --type=py -A 10

# Search for where custom_goose-proxy.json is used in the entire repo
fd -type f | xargs grep -l 'custom_goose-proxy.json'

Repository: rhel-lightspeed/goose-proxy

Length of output: 1187


🏁 Script executed:

#!/bin/bash
# View the full Backend class definition
cat -n src/goose_proxy/config.py | head -150

# Find get_settings function
rg -n 'def get_settings' 

# Find where json files are loaded
rg -n 'custom_goose-proxy\.json'

Repository: rhel-lightspeed/goose-proxy

Length of output: 6691


🏁 Script executed:

#!/bin/bash
# View get_settings function
sed -n '155,200p' src/goose_proxy/config.py

# Check if there's any JSON loading in goose-proxy code
rg -n 'json\|JSON' src/goose_proxy/ --type=py

# Search the entire repo to understand what custom_goose-proxy.json is for
rg -n 'custom_goose-proxy' -B 3 -A 3

Repository: rhel-lightspeed/goose-proxy

Length of output: 4664


🏁 Script executed:

#!/bin/bash
# View the full custom_goose-proxy.json file to understand its structure
cat -n data/release/goose/custom_goose-proxy.json

# Also check the development version
cat -n data/development/goose/custom_providers/custom_goose-proxy.json

Repository: rhel-lightspeed/goose-proxy

Length of output: 1752


🏁 Script executed:

#!/bin/bash
# Search for any handling of X-LCS-Merge-Server-Tools header
rg -n 'X-LCS-Merge-Server-Tools'

# Search for header reading in v1.py request handlers
rg -n 'request\.' src/goose_proxy/v1.py -A 3

# Search for all header processing in the codebase
rg -n 'headers' src/goose_proxy/ -B 2 -A 2

Repository: rhel-lightspeed/goose-proxy

Length of output: 896


🏁 Script executed:

#!/bin/bash
# View chat_completions endpoint fully to see how request is handled
sed -n '86,110p' src/goose_proxy/v1.py

# Check if there's any code that reads incoming request headers
rg -n 'request\.' src/goose_proxy/ -B 2 -A 2 | head -50

# Search for translate_request to see what happens with the request
rg -n 'def translate_request' src/goose_proxy/ -A 15

Repository: rhel-lightspeed/goose-proxy

Length of output: 4317


🏁 Script executed:

#!/bin/bash
# Check if list_models endpoint shows how to capture Request object
sed -n '103,120p' src/goose_proxy/v1.py

# Check all endpoint signatures to see if any capture Request object
rg -n '@router\.' src/goose_proxy/v1.py -A 3

# Search for any middleware or dependency that could read headers
rg -n 'Request\|Header' src/goose_proxy/ -B 2 -A 2

# Look for any code that might use X-LCS-Merge-Server-Tools or similar headers
rg -n 'merge\|tools\|leak' src/goose_proxy/ -i

Repository: rhel-lightspeed/goose-proxy

Length of output: 926


🏁 Script executed:

#!/bin/bash
# Check git history for this file to understand the context
git log --oneline data/release/goose/custom_goose-proxy.json | head -5

# Check if there's any README or documentation about X-LCS-Merge-Server-Tools
rg -n 'Merge.*Tool\|MCP.*tool\|leak' . -i -type f

# Check if there's any FastAPI middleware that could process headers
rg -n 'app\.middleware\|@app\.' src/goose_proxy/ -A 5

# Look for main.py or where the FastAPI app is created
fd 'main\|app' src/goose_proxy/ -type f

Repository: rhel-lightspeed/goose-proxy

Length of output: 347


🏁 Script executed:

#!/bin/bash
# Check the git commit that added this header
git show 6860c61

# Search for any code that processes incoming request headers
rg -n 'request\.headers\|Headers' src/goose_proxy/ -B 2 -A 2

# Look for main app file
cat -n src/goose_proxy/main.py 2>/dev/null || cat -n src/goose_proxy/__main__.py 2>/dev/null || fd 'main' src/goose_proxy/

Repository: rhel-lightspeed/goose-proxy

Length of output: 50386


🏁 Script executed:

#!/bin/bash
# Check if goose-proxy forwards request headers to the backend
# Look at how requests are made to the backend
sed -n '50,100p' src/goose_proxy/v1.py

# Look for create_response and stream_response functions
rg -n 'def create_response\|def stream_response' src/goose_proxy/ -A 10

Repository: rhel-lightspeed/goose-proxy

Length of output: 1845


🏁 Script executed:

#!/bin/bash
# Check if chat_completions endpoint can access request headers
rg -n 'async def chat_completions' src/goose_proxy/v1.py -A 20

# Check if Request object is available via FastAPI dependency
rg -n 'from fastapi import' src/goose_proxy/ 

# Check if any endpoint accesses request.headers
rg -n '\.headers' src/goose_proxy/

Repository: rhel-lightspeed/goose-proxy

Length of output: 1236


🏁 Script executed:

#!/bin/bash
# Check if there's any code that reads request headers from incoming requests
rg -n 'request\.headers\|Request\)' src/goose_proxy/v1.py -B 2 -A 5

# Check the full chat_completions signature more carefully
sed -n '86,105p' src/goose_proxy/v1.py

# Look for middleware that might process headers
fd -type f -name '*.py' -path 'src/goose_proxy/*' -exec grep -l 'middleware\|add_middleware' {} \;

# Check app.py to see how the app is configured
cat src/goose_proxy/app.py

Repository: rhel-lightspeed/goose-proxy

Length of output: 1791


Implementation incomplete: incoming request headers are not forwarded to the backend.

The X-LCS-Merge-Server-Tools header configuration in custom_goose-proxy.json instructs GOOSE to send this header to goose-proxy. However, the chat_completions endpoint in src/goose_proxy/v1.py does not capture or read incoming request headers, so they are never forwarded to the lightspeed-stack backend where this header is needed for merging MCP tools.

The endpoint signature must be updated to accept a Request parameter and merge incoming headers with the hardcoded headers before passing them to httpx.AsyncClient. Without this, the PR's objective (merge MCP tools, prevent server-side tool leakage) will not be achieved.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data/release/goose/custom_goose-proxy.json` around lines 19 - 21, The
chat_completions endpoint in src/goose_proxy/v1.py must accept the incoming
Request object and merge its headers into the hardcoded headers before
creating/passing headers to httpx.AsyncClient; update the chat_completions
function signature to include a fastapi.Request (or starlette.requests.Request)
parameter, read request.headers, copy/normalize them into a dict, then merge
(with hardcoded headers taking precedence where needed, e.g.,
"X-LCS-Merge-Server-Tools") and pass the merged headers to the AsyncClient
request call so incoming headers are forwarded to the lightspeed-stack backend.

@samdoran
samdoran merged commit 86a20ac into rhel-lightspeed:main Apr 15, 2026
23 of 24 checks passed
@r0x0d
r0x0d deleted the allow-lcs-merge-tools branch April 15, 2026 13:57
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.

2 participants