Skip to content

PRD: Hard cutover from Tavily MCP to direct Tavily API plugin #36

Description

@cgrpa

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

  1. As a bot operator, I want Tavily search to work without MCP transport dependencies, so that production behavior is easier to reason about.
  2. As a bot operator, I want startup to avoid remote MCP tool discovery, so that boot reliability improves.
  3. As a bot operator, I want to remove dormant/legacy integration paths, so that long-term maintenance cost drops.
  4. As a developer, I want Tavily tools to be normal Semantic Kernel functions, so that debugging is straightforward.
  5. As a developer, I want direct control over HTTP request/response handling, so that retries and error behavior are explicit.
  6. As a developer, I want tool outputs in raw Tavily JSON, so that no information is lost and formatting can evolve later.
  7. As a developer, I want structured JSON errors from tool calls, so that the LLM can recover gracefully without hard failures.
  8. As a developer, I want Tavily endpoint configuration with a safe default, so that local testing and future endpoint migration are easy.
  9. As a developer, I want transient retry behavior on 429/5xx/network faults, so that short-lived outages do not immediately fail user requests.
  10. 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.
  11. 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.
  12. As a maintainer, I want tavily_research excluded from v1, so that we avoid incomplete async orchestration/state handling.
  13. As a maintainer, I want MCP code and tests fully removed, so that the codebase reflects the actual architecture.
  14. As a maintainer, I want live-gated integration tests for direct Tavily API behavior, so that real endpoint compatibility can be validated safely.
  15. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions