Skip to main content

Discovery and Caching

Tools are discovered and cached once when users connect your integration.

Initial Connection

When a user adds your integration in Settings → Integrations:
  1. Poke connects to your server via Streamable HTTP or SSE
  2. If OAuth is required, Poke initiates the auth flow
  3. Once connected, Poke calls tools/list
  4. Tool schemas are cached for the connection lifetime
  5. The execution agent can now see your tools when planning tasks

During Usage

When a user asks a question:
  1. The execution agent sees cached tool schemas for all connected integrations
  2. It evaluates which tools are relevant based on user intent, tool descriptions, and server instructions
  3. If your integration is selected, a task agent spawns and calls tools/call
  4. Results flow back through the task agent to the execution agent to the user

Disconnection

When a user disconnects your integration:
  1. Cached tool schemas are cleared
  2. Poke stops calling your server
  3. Your tools are no longer available to the execution agent

Schema Updates

Tool changes won’t appear in existing connections. Users must disconnect and reconnect to pick up schema changes. Plan accordingly.

Handling Schema Changes

If you must change schemas: Maintain backward compatibility. Support both old and new parameter formats in your tool implementations. This lets existing connections continue working while new connections use updated schemas.
# Old schema: get_iss_location() -> returned structured data
# New schema: get_iss_location(format="text") -> optional parameter to maintain backward compatibility
@mcp.tool(description="Get ISS location")
def get_iss_location(format: str = "text") -> str | dict:
    """Format: 'text' (default) or 'json'."""
    # Fetch the raw ISS data from API
    data = fetch_iss_data()  # {"lat": 45.2, "lon": -122.8, "altitude": 408}

    # New behavior: format as human-readable text
    if format == "text":
        return f"ISS at {data['lat']}°N, {data['lon']}°W"

    # Old behavior: return raw structured data (maintains backward compatibility)
    return data
Return clear error messages. If you made a breaking change, return a clear error message that Poke can surface to users.
# Old Schema: format parameter was optional with default behavior
# New Schema: format parameter is now required (breaking change)
@mcp.tool(description="Get ISS location")
def get_iss_location(format: str) -> str | dict:
    """Format: 'text' or 'json' (required)."""
    # Validate the required format parameter
    if format not in ["text", "json"]:
        return {
            "error": "Invalid format. Use 'text' or 'json'.",
            "hint": "Reconnect integration to use new schema with required format parameter"
        }

    # Fetch ISS data from API
    data = fetch_iss_data()

    # Return formatted response based on requested format
    return format_as_text(data) if format == "text" else data

Cache Invalidation

Currently, the only way to invalidate the cache is user action: disconnect and reconnect. Future versions of Poke may support server-initiated cache invalidation or automatic schema refresh. For now, design schemas carefully and plan for backward compatibility.

Best Practices

Design schemas carefully before launch. Since updates require users to reconnect, get schemas right the first time. Version your server. Use semantic versioning in your server metadata to track changes:
mcp = FastMCP(
    name="my-integration",
    version="1.2.0",  # Increment when schemas change
    instructions="..."
)
Test schema changes locally. Use the MCP Inspector to verify new schemas work before deploying. Document breaking changes. If you must make breaking changes, announce them to users and provide migration guidance. Monitor connection versions. Track which server versions users are connected to. If most users are on old versions, consider backward compatibility even longer.

Next Steps