1jehuang / 1jehuang/jcode

Provider profiles cannot send custom HTTP headers (needed to opt out of gateway-side MCP tool injection)

Open
#933 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: no enhancement priority: medium triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Problem

Named provider profiles ([providers.X]) can customize the request body via extra_body (#341) but have no way to attach custom HTTP headers. Some OpenAI-compatible gateways make per-request behavior decisions based on headers, and clients that can't send them are stuck with gateway-global config.

Concrete case: Bifrost's MCP auto tool injection. When a Bifrost gateway has MCP clients connected, it appends those tools to every inference request's tools array (gateway-side names like exa_mcp-web_search_exa). Bifrost's default execution mode is stateless, so calls to those tools come back to the caller unexecuted. jcode — which registers its own MCP tools (e.g. bridged to the same gateway's /mcp endpoint via stdio) — then receives calls to tool names it doesn't own and refuses them. The model sees two names for the same tool and picks the unexecutable one.

Bifrost's documented per-request opt-out is an empty x-bf-mcp-include-tools header (deny-all). There is currently no way to make jcode send it, so jcode's correctness depends on a gateway-wide setting (mcp_disable_auto_tool_inject), which the client should not have to rely on.

Proposal

Add extra_headers to named provider profiles, mirroring extra_body:

[providers.bifrost]
type = openai-compatible
base_url = http://bifrost:4000/v1
extra_headers = { x-bf-mcp-include-tools =  }  # empty = deny-all injection opt-out
  • Attached to every chat/completions request, after jcode's own headers.
  • Empty values are preserved (present-but-empty is the opt-out signal).
  • Invalid header names are logged and skipped at construction rather than failing provider init.

Related: #761 (native Streamable HTTP MCP would make the bridge unnecessary, but the header need is orthogonal).

Implementation ready: branch on my fork (marko-k0/jcode, feat/provider-extra-headers), with unit + wire-level tests.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing named provider profile handling and the existing extra_body support. Then inspect the unit and wire-level tests mentioned in the issue, using the proposed Bifrost header behavior as the acceptance case. Done means profiles can preserve valid empty header values, skip invalid names with a log, and attach headers to chat/completions requests.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, backend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.