Skip to main content

FastAPI Integration

This example demonstrates how to expose Corvic’s MCP protocol through a FastAPI web endpoint. This makes it easy to integrate Corvic-powered agents into external services like Slack, Discord, webhooks, or custom UIs.

Use Case

You want to expose a Corvic agent to external clients (e.g., Slack command, customer service UI, webhooks) via a simple HTTP endpoint. This FastAPI app acts as a bridge between those services and Corvic’s MCP-based query interface.

Key Points

  • The slack_handler (general-purpose POST endpoint) receives a user query via HTTP POST.
  • The process_query_and_respond method:
    • Initializes an sse_client connection to your deployed Corvic agent.
    • Sends a query_content to Corvic via the ClientSession.
    • Forwards the response to a webhook (e.g., response_url).
  • The response_url mechanism enables compatibility with asynchronous platforms like Slack or others expecting delayed responses.

Code Example

from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel
import mcp
import httpx
from typing import Optional

app = FastAPI()

# Configuration
MCP_ENDPOINT = "<<MCP_ENDPOINT>>"
CORVIC_API_TOKEN = "<<YOUR_CORVIC_API_TOKEN>>"

headers = {
    "Authorization": f"Bearer {CORVIC_API_TOKEN}",
    "Content-Type": "application/json"
}

class QueryRequest(BaseModel):
    query: str
    response_url: Optional[str] = None

class QueryResponse(BaseModel):
    answer: str
    status: str

async def process_query_and_respond(query: str, response_url: Optional[str] = None):
    """Process query with Corvic and optionally send to webhook."""
    try:
        # Query Corvic agent
        async with mcp.ClientSession(
            transport=mcp.SSEClientTransport(MCP_ENDPOINT, headers=headers)
        ) as session:
            await session.initialize()
            
            query_result = await session.call_tool(
                "query",
                arguments={"query_content": query}
            )
            
            answer = query_result.content[0].text if query_result.content else ""
        
        # If response_url is provided, send async response
        if response_url:
            async with httpx.AsyncClient() as client:
                await client.post(
                    response_url,
                    json={"text": answer},
                    timeout=30.0
                )
        
        return {
            "answer": answer,
            "status": "success"
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/query", response_model=QueryResponse)
async def slack_handler(request: QueryRequest):
    """
    General-purpose endpoint for querying Corvic agent.
    Can be used with Slack, Discord, or any HTTP client.
    """
    result = await process_query_and_respond(
        query=request.query,
        response_url=request.response_url
    )
    return QueryResponse(**result)

@app.post("/slack/command")
async def slack_command(request: Request):
    """
    Slack slash command handler.
    Expects Slack's form-encoded data.
    """
    form_data = await request.form()
    query = form_data.get("text", "")
    response_url = form_data.get("response_url")
    
    if not query:
        return {"text": "Please provide a query."}
    
    # Process asynchronously for Slack
    if response_url:
        # Return immediate acknowledgment
        # Process query in background
        import asyncio
        asyncio.create_task(
            process_query_and_respond(query, response_url)
        )
        return {"text": "Processing your query..."}
    else:
        # Synchronous response
        result = await process_query_and_respond(query)
        return {"text": result["answer"]}

@app.get("/health")
async def health_check():
    """Health check endpoint."""
    return {"status": "healthy"}

Usage Examples

Direct HTTP POST

curl -X POST "http://localhost:8000/query" \
  -H "Content-Type: application/json" \
  -d '{"query": "What is the NAICS code for wheat farming?"}'

With Webhook Response

curl -X POST "http://localhost:8000/query" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What is the NAICS code for wheat farming?",
    "response_url": "https://your-webhook-url.com/callback"
  }'

Resources