We’re building a voice agent using LiveKit Agents ...
# ask-ai
e
We’re building a voice agent using LiveKit Agents (Python) and ran into a token bloat problem when integrating MCP servers like Google Calendar. The issue: Each MCP tool injects its full schema/definition into the prompt on every LLM call. For a voice agent, latency is critical — ideally we want to stay under ~2k tokens per request. But even adding a single tool like “Create Event” from Google Calendar MCP adds ~3k tokens on its own, which immediately blows past that budget. What we tried: We know about the
allowed_tools
filter to only expose specific tools instead of the full MCP server. We tried this, but even one tool from Google Calendar MCP adds ~3k tokens — so filtering tools alone doesn’t solve the problem. What we’re looking for: • Is there a way to reduce or compress the tool schema that gets injected into the prompt? • Has anyone written leaner custom wrappers around MCP tools to reduce token footprint? • Is there a pattern others use to balance MCP tool availability vs. latency in voice agents? Any advice or examples would be really helpful!
t
Thanks for reaching out, Aman. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — this is a great, specific question and I hear the pain: a single MCP tool adding thousands of tokens kills latency goals for voice agents. I’ll address each of your asks and give concrete, practical patterns you can adopt right away. Quick summary of the main constraint I’m responding to: • LiveKit Agents does not support compressing/modifying MCP tool schemas on the client automatically. MCP tool schemas are injected as-is and can be large. That means you’ll need an architectural change or a custom wrapper to reduce token footprint. What you can do (practical options, ordered from lowest to highest effort) 1) Use lightweight function tools (recommended — lowest token cost) • Instead of exposing the full MCP tool, implement small function tools that wrap only the exact fields you need (name, a very short description, and a minimal parameter list). • Benefits: you control every token in the schema; prompts drop from thousands of tokens to tens/hundreds. • When to use: if you only need a few operations (e.g., create_event, get_availability). • Example idea (Python pseudocode): ◦ Define a
create_calendar_event
function tool that takes only
title
,
start_time
,
duration_minutes
. ◦ Inside that tool call your Google Calendar REST client (or an internal proxy) to perform the real API call. • This approach is fast to implement and reliable for real-time voice flows. 2) Proxy + schema-stripping MCP server (medium effort) • Put a lightweight proxy between LiveKit and the upstream MCP server that: ◦ Fetches the full MCP schema from Google Calendar. ◦ Strips or rewrites fields that cause bloat (remove long descriptions, examples, unused properties, extra enums, verbose
required
lists). ◦ Serves a minimal, validated schema to your agent as if it were the MCP server. • Benefits: keeps integration with upstream MCP logic while controlling token size centrally. • When to use: when you want to preserve MCP behavior but control prompt size and maintain a single integration point for multiple agents. 3) Dynamically add/remove tools at runtime (low effort, good impact) • Start agents with zero or minimal tools. • Add calendar tools only when the conversation context actually requires scheduling (e.g., user intent = “schedule”, “book”, “create event”). • Remove the tool after the operation completes. • Use the
agent.update_tools()
pattern to load only the single tool you need at the moment. • Benefits: reduces the number of tool schemas in the prompt (helps more when you have many different MCPs). 4) Decompose agents / use handoffs (architectural) • Split responsibilities across focused agents: ◦ e.g., “voice-gateway” agent (no tools) → “scheduling agent” (only calendar tools). • When scheduling is needed, hand off the conversation to the scheduling agent. • Benefits: each agent’s prompt stays small and predictable; easier to reason about token budgets. • This also helps security/scope isolation for sensitive operations. 5) Hybrid: short prompt + tool-call metadata • Keep only a minimal tool description in the prompt and put more details (full schema, validation rules, examples) on your proxy server. • After the model picks a tool, your application can fetch details from the proxy to validate/complete the call server-side. The LLM only sees the small schema, server enforces correctness. • Benefit: the LLM works with a compact interface; your backend still has full richness to handle edge cases. Operational tips and micro-optimizations • Remove non-essential fields:
description
,
examples
, long enum lists, nested optional properties, and verbose
required
explanations. • Prefer simple parameter types (strings / ISO datetimes) and do server-side parsing/validation. • Avoid returning large example payloads inside tool schemas. • Log the actual schema sent to the model and estimate token counts so you can prioritize which fields to strip. • If you must keep a richer schema for developer discoverability, serve that on a separate developer endpoint — don’t include it in the model prompt. When a direct MCP integration isn’t feasible: wrap, proxy, or implement single-purpose function tools. • There is no built-in LiveKit mechanism that compresses MCP schemas automatically. • The fastest win is to replace MCP exposure with function tools or a proxied minimal schema. A suggested rollout plan 1. Identify the specific calendar operations you actually need for voice flows. 2. Implement 1–2 function tools for those operations (create_event, find_free_slots). 3. Measure token usage and latency end-to-end. 4. If you still need fuller MCP coverage later, add a proxy that serves stripped-down schemas and route your agents to it. 5. If many distinct capabilities are required, split agents and implement handoffs for predictable token budgets. If you’d like, I can help with next steps: • Review a real sample MCP tool schema you’re getting from Google Calendar and point out exactly what to strip to save the most tokens. • Provide a concrete Python function-tool template for your calendar operations. • Sketch a minimal proxy implementation (routes + schema transform) you can drop into a small server. Which would be most helpful: a tailored function-tool template for your specific calendar fields, or a quick review of one of the large MCP tool JSON blobs you’re seeing so I can mark high-impact reductions? Sources: Tool definition and use | LiveKit Documentation | Workflows | LiveKit Documentation | Groq LLM plugin guide | LiveKit Documentation