aloof-scooter-47164
02/17/2026, 5:15 PMtall-airline-16756
02/17/2026, 5:15 PMtall-airline-16756
02/17/2026, 5:15 PM_meta object to every tool call sent to a specific MCP server (per the MCP spec you linked).
Short answer from the LiveKit docs: we do not have a documented, built-in way to automatically inject an MCP _meta field into every outgoing tool call. LiveKit Agents support registering MCP servers via mcp_servers on an AgentSession, and you can configure connection details (headers/auth), but there’s no explicit example or documented hook for adding _meta to every tool request.
To help you further I need a bit more detail about your setup so I can suggest the right approach or a workaround:
• Which LiveKit SDK / language are you using (Node, Python, Go, etc.)?
• Are you registering the MCP server through mcp_servers on an AgentSession (yes/no)?
• Do you control the MCP client code that sends tool calls (i.e., can you modify the request payload before sending)?
• Is your goal to add identical _meta for all tools on that server, or to compute different _meta per-request (e.g., runtime context like job id, user id)?
Possible approaches we can explore depending on your answers:
• If you can modify the MCP client payload before sending, add _meta there programmatically so every tool call includes it.
• If the SDK exposes request hooks/middleware, add a middleware that injects _meta for calls targeting the specific MCP server.
• If neither is available, you can set server-specific headers or authentication fields (these are supported) and pass metadata via headers as an alternative, then translate them to _meta on the MCP server side if you control it.
Tell me your SDK/language and whether you can modify the client sending tool calls, and I’ll propose concrete code snippets or steps for the best-fit approach.
Sources: Tool definition and use | LiveKit Documentation | MCP Agent | LiveKit Documentation | Agent Builder | LiveKit Documentation | Job lifecycle | LiveKit Documentation | Agent session | LiveKit Documentationaloof-scooter-47164
02/17/2026, 5:23 PMmcp_servers on an AgentSession (yes/no)?
◦ yes
• Do you control the MCP client code that sends tool calls (i.e., can you modify the request payload before sending)?
◦ no, im relying on LiveKit for this but if need to modify the LiveKit code im open to do so if you guide me
• Is your goal to add identical _meta for all tools on that server, or to compute different _meta per-request (e.g., runtime context like job id, user id)?
◦ yes, would be a global conversation id from our systemtall-airline-16756
02/17/2026, 5:23 PMmcp_servers, you don't control the upstream MCP client payloads, and you want a global conversation ID injected as _meta on every tool call. I’ll walk you through two practical options: a quick, safe monkey-patch you can run in your app, and a longer-term, more maintainable forked SDK approach.
Short summary: LiveKit’s Python Agents do not provide a public hook to modify MCP tool-call JSON payloads. To add _meta you must either intercept the MCP client before calls are made (monkey-patch) or modify the SDK source (fork). Both approaches inject _meta into tool.use requests so your MCP server sees the global conversation id.
Option A — Monkey-patch (fast, minimal changes)
• When your process starts and before any MCP tool calls run, patch the internal MCP HTTP execution method to add _meta for tool.use requests.
• This is low-friction and reversible (patch runs in-process), but slightly brittle across SDK upgrades.
Example pattern (adapt to your codebase):
# run this early in your app, before creating AgentSession / making MCP calls
from livekit.agents.mcp import MCPServerHTTP
_original_execute_request = MCPServerHTTP._execute_request
def make_patched_execute(conversation_id: str):
async def _patched_execute_request(self, method: str, params=None, timeout: float = 30.0):
# Only inject for tool invocation RPCs
if method == "tool.use" and params is not None:
# preserve existing params, insert or merge _meta
params = dict(params)
meta = params.get("_meta", {})
meta.update({"conversation_id": conversation_id})
params["_meta"] = meta
return await _original_execute_request(self, method, params, timeout)
return _patched_execute_request
# set your global conversation id or fetch from context closure
GLOBAL_CONVERSATION_ID = "conv-12345"
MCPServerHTTP._execute_request = make_patched_execute(GLOBAL_CONVERSATION_ID)
Notes for this approach:
• Ensure this code runs before any MCP server discovery/tool use calls.
• If you need the conversation ID to vary per AgentSession (not global process-wide), you can:
◦ store the ID on the session object when creating it and access it via self inside the patched function if self has session context, or
◦ create different patched functions per session before creating that session (less common).
• Test carefully across SDK versions — method names or internals may change.
Option B — Fork & modify SDK (robust, maintainable)
• Clone the LiveKit Agents repo, modify the place that constructs/sends MCP RPCs (the MCP HTTP client), and add _meta injection there.
• Advantages: cleaner, less fragile, can be covered by tests and versioned with your code.
• High-level steps:
a. Fork repo (or vendor the package into your repo).
b. Locate the MCP HTTP client implementation file (where _execute_request or equivalent composes the JSON-RPC).
c. Add logic to merge in _meta for tool.use (example logic shown below).
d. Publish or install your modified package (e.g., pip install -e .) and use it in your app.
Conceptual patch snippet for SDK:
# pseudo-change inside the SDK's MCP request function
if method == "tool.use":
params.setdefault("_meta", {})
params["_meta"].update({"conversation_id": GLOBAL_CONVERSATION_ID})
# then send the request as usual
When to choose which:
• Use the monkey-patch if you want to try quickly and validate behavior against your MCP server.
• Use the fork if you need long-term stability, multiple environments, or want to add tests and CI coverage.
Other alternatives and considerations
• If you control the MCP server side, you could accept an equivalent identifier from HTTP headers (which LiveKit does support configuring) and map that into _meta on your server. This avoids touching client payloads but requires server-side translation.
• If you need a per-session (not per-process) conversation_id, let me know how you identify sessions and I’ll tailor the patch to read the session value rather than a single global constant.
• Make sure your conversation_id format and privacy requirements are acceptable for inclusion in tool call payloads.
Next step
• Do you want:
◦ a ready-to-run example that reads the conversation ID from an environment variable (monkey-patch version), or
◦ guidance for where exactly to change the SDK source (I can point to the file/method if you share your installed package version)?
Tell me which and I’ll provide the exact code tailored to your version and whether the ID should be process-global or session-scoped.
Sources: Tool definition and use | LiveKit Documentation | MCP Agent | LiveKit Documentationaloof-scooter-47164
02/17/2026, 5:25 PMtall-airline-16756
02/17/2026, 5:25 PMAgentSession (static headers), or inject headers dynamically by intercepting the MCP client before requests are sent (monkey-patch). I’ll show both approaches and when to use each.
What I’m responding to: adding a custom HTTP header on MCP server calls in the Python Agents SDK.
Option 1 — Set headers when registering the MCP server (static headers)
• When you register an MCP server via mcp_servers on AgentSession, you can provide connection/config info. The SDK supports configuring headers/auth for MCP server connections.
• Use this if your header is the same for all requests and can be supplied at session creation time (e.g., a static API key or static tenant id).
Example pattern (conceptual — adapt to your code):
from livekit.agents import AgentSession
from livekit.agents import mcp
mcp_server = mcp.MCPServerHTTP(
url="<https://your-mcp-server.com>",
headers={
"X-Conversation-ID": "conv-12345",
"Authorization": "Bearer your-token"
}
)
session = AgentSession(
mcp_servers=[mcp_server],
# other session params...
)
Notes:
• Put this code early, before any MCP discovery/tool use.
• This approach attaches the headers to the MCP server connection so all requests use them.
Option 2 — Inject headers dynamically by intercepting MCP client (dynamic headers)
• If you need the header to vary per request or per session (e.g., a conversation id that changes at runtime) and the SDK doesn’t expose a public hook, intercept the MCP client at the point it sends HTTP requests and add/edit headers there.
• This requires a small in-process patch (monkey-patch) before any MCP calls run.
Example monkey-patch pattern (run early in your app):
from livekit.agents.mcp import MCPServerHTTP
_original_execute_request = MCPServerHTTP._execute_request
def make_patched_execute(get_headers_fn):
async def _patched_execute_request(self, method: str, params=None, timeout: float = 30.0):
# allow original to build request data, but inject headers via self.http_client or equivalent
# Example: if the internal method accepts a headers kwarg or uses an httpx client:
headers = get_headers_fn() # function you provide to supply current headers
# attach headers onto self or pass through to the underlying HTTP call as required
# the exact spot to place headers depends on SDK internals; often the _execute_request
# method calls an HTTP client where headers can be supplied.
return await _original_execute_request(self, method, params, timeout)
return _patched_execute_request
# Example get_headers_fn could read an env var, session state, etc.
def current_headers():
return {"X-Conversation-ID": "conv-12345"}
MCPServerHTTP._execute_request = make_patched_execute(current_headers)
Important:
• The exact mechanism to attach headers depends on the SDK internals (where the HTTP request is actually performed). The monkey-patch should run before any MCP calls.
• This approach is more flexible but more brittle across SDK upgrades. If you need long-term stability, consider forking and changing the SDK source directly where the HTTP client call is performed.
Alternative (server-side translation)
• If you control the MCP server, another option is to accept an identifier via headers (which LiveKit supports configuring) and translate that into _meta server-side. This avoids altering SDK internals.
Which approach fits you?
• If your header is static per server/session: configure headers when creating the MCPServerHTTP / AgentSession (Option 1).
• If the header must change at runtime per request or per session and the SDK doesn’t provide a hook: use the monkey-patch to inject it dynamically (Option 2) or fork the SDK to add a proper hook.
If you want, tell me:
• whether the header is static or must change per session/request, and
• which LiveKit Agents package version you’re using
…and I’ll provide a concrete code snippet tailored to that version and to whether you need process-global or session-scoped headers.aloof-scooter-47164
02/17/2026, 5:26 PMaloof-scooter-47164
02/17/2026, 5:26 PMtall-airline-16756
02/17/2026, 5:28 PM