Problem Statement
The current Tavily integration relies on MCP transport/runtime wiring, which has become a reliability and maintenance burden for this bot. The integration path is harder to debug, introduces additional transport/protocol complexity, and creates operational ambiguity when failures happen (startup discovery, runtime reconnect behavior, transport compatibility).
The team wants a hard cutover to a simpler direct Tavily API integration using Semantic Kernel plugin functions, with raw JSON responses and predictable failure behavior.
Solution
Replace the MCP-based Tavily path with a direct HTTP Tavily API plugin registered in Semantic Kernel.
The new plugin will expose the same core tool names used today (tavily_search, tavily_extract, tavily_crawl, tavily_map), but implemented as first-party bot plugin functions that call Tavily REST endpoints directly.
The bot will remove all MCP-specific runtime/configuration/test surface area. Tavily tool failures will return structured error JSON (not throw) so the conversation can continue and the model can reason about retries/fallbacks.
The v1 cutover intentionally excludes async Tavily Research orchestration.
User Stories
- As a bot operator, I want Tavily search to work without MCP transport dependencies, so that production behavior is easier to reason about.
- As a bot operator, I want startup to avoid remote MCP tool discovery, so that boot reliability improves.
- As a bot operator, I want to remove dormant/legacy integration paths, so that long-term maintenance cost drops.
- As a developer, I want Tavily tools to be normal Semantic Kernel functions, so that debugging is straightforward.
- As a developer, I want direct control over HTTP request/response handling, so that retries and error behavior are explicit.
- As a developer, I want tool outputs in raw Tavily JSON, so that no information is lost and formatting can evolve later.
- As a developer, I want structured JSON errors from tool calls, so that the LLM can recover gracefully without hard failures.
- As a developer, I want Tavily endpoint configuration with a safe default, so that local testing and future endpoint migration are easy.
- As a developer, I want transient retry behavior on 429/5xx/network faults, so that short-lived outages do not immediately fail user requests.
- As a user in Discord, I want Tavily-powered answers to remain available through the same tool names, so that response quality and behavior stay familiar.
- As a user in Discord, I want failed Tavily calls to still produce meaningful responses, so that I am not blocked by generic crash messages.
- As a maintainer, I want
tavily_research excluded from v1, so that we avoid incomplete async orchestration/state handling.
- As a maintainer, I want MCP code and tests fully removed, so that the codebase reflects the actual architecture.
- As a maintainer, I want live-gated integration tests for direct Tavily API behavior, so that real endpoint compatibility can be validated safely.
- As an AFK implementation agent, I want a clear PRD decision log, so that implementation can proceed without further discovery interviews.
Implementation Decisions
- Hard cutover strategy: remove MCP architecture rather than feature-flagging it.
- New Tavily plugin identity: rename to
TavilyApi (remove MCP naming from user-facing plugin metadata).
- Tool coverage in v1: keep
tavily_search, tavily_extract, tavily_crawl, tavily_map; exclude tavily_research.
- Tool output contract: return Tavily raw JSON strings on success.
- Tool failure contract: return structured error JSON payloads instead of throwing.
- Required fields: success flag, endpoint/tool name, HTTP status when available, error message, retryable indicator, and request correlation metadata when available.
- Tavily auth/config:
- Project-level API key only (
TavilyApiKey).
- No
X-Project-ID support in v1.
- Endpoint remains configurable with safe default (
https://api.tavily.com).
- Parameter surface in v1 is intentionally focused:
- Search: essential query + bounded subset of controls.
- Extract/Crawl/Map: essential inputs + minimal useful toggles.
- Full parameter parity deferred.
- Reliability policy:
- Bounded retries with exponential backoff + jitter for transient failures (429, 5xx, transport/network timeouts).
- No retries for non-retryable 4xx validation/auth failures.
- Dependency graph simplification:
- Remove MCP startup discovery, runtime supervision, reconnect policies, aliasing, and MCP telemetry primitives.
- Replace with direct Tavily API service + plugin registration path.
- Configuration simplification:
- Remove MCP configuration model/sections from runtime config and docs.
- Introduce direct Tavily API config model aligned to new service.
- Backward behavior intent:
- Preserve tool names to minimize model behavior drift.
- Preserve weather and existing non-Tavily plugin behavior unchanged.
Testing Decisions
- Testing principle: validate observable behavior and contracts (returned tool payloads, retry/error semantics, registration surface), not internal private implementation details.
- Unit tests should cover:
- Tavily request body/header construction for each supported endpoint.
- Structured error JSON mapping for HTTP/network failure classes.
- Retry policy behavior (retryable vs non-retryable paths).
- Plugin registration and callable function names.
- Integration tests should cover:
- Live-gated direct Tavily search call with deterministic assertion (e.g., capital-of-France query contains
Paris).
- At least one non-search endpoint smoke validation (extract/crawl/map) behind live opt-in flag.
- Remove MCP-specific tests entirely and replace with direct API equivalents.
- Prior art in repo:
- Existing live API integration test patterns (weather and Tavily REST tests).
- Existing kernel plugin availability/invocation test style.
Out of Scope
- Tavily Research async orchestration (
POST /research + polling/streaming completion routing).
- Discord follow-up delivery architecture for long-running background research jobs.
- Persisted message/request state for delayed completion workflows.
- Markdown/post-processing transformation of Tavily JSON payloads.
- Full Tavily API parameter parity on day 1.
- Multi-project usage attribution via
X-Project-ID.
Further Notes
- Research endpoint remains intentionally deferred because proper UX requires an async state model (request tracking, callback/poll trigger route, response correlation to requester/channel/message).
- This PRD optimizes for immediate reliability and reduced complexity, with a future phase to add rich formatting and async research workflows.
- Migration should include README/runbook updates so operators know MCP is gone and Tavily now runs through direct API integration.
Problem Statement
The current Tavily integration relies on MCP transport/runtime wiring, which has become a reliability and maintenance burden for this bot. The integration path is harder to debug, introduces additional transport/protocol complexity, and creates operational ambiguity when failures happen (startup discovery, runtime reconnect behavior, transport compatibility).
The team wants a hard cutover to a simpler direct Tavily API integration using Semantic Kernel plugin functions, with raw JSON responses and predictable failure behavior.
Solution
Replace the MCP-based Tavily path with a direct HTTP Tavily API plugin registered in Semantic Kernel.
The new plugin will expose the same core tool names used today (
tavily_search,tavily_extract,tavily_crawl,tavily_map), but implemented as first-party bot plugin functions that call Tavily REST endpoints directly.The bot will remove all MCP-specific runtime/configuration/test surface area. Tavily tool failures will return structured error JSON (not throw) so the conversation can continue and the model can reason about retries/fallbacks.
The v1 cutover intentionally excludes async Tavily Research orchestration.
User Stories
tavily_researchexcluded from v1, so that we avoid incomplete async orchestration/state handling.Implementation Decisions
TavilyApi(remove MCP naming from user-facing plugin metadata).tavily_search,tavily_extract,tavily_crawl,tavily_map; excludetavily_research.TavilyApiKey).X-Project-IDsupport in v1.https://api.tavily.com).Testing Decisions
Paris).Out of Scope
POST /research+ polling/streaming completion routing).X-Project-ID.Further Notes