Skip to content
Back to Blog
1 min read

Copilot Extensibility: Building Custom Copilot Experiences

I wrote “Copilot Extensibility: Building Custom Copilot Experiences” to share practical, production-minded guidance on this topic.

Copilot Plugin Development

# copilot_plugin.py - Building a Copilot plugin

from fastapi import FastAPI, Request
from pydantic import BaseModel
from typing import List, Optional

app = FastAPI()

class CopilotRequest(BaseModel):
    query: str
    context: Optional[dict] = None
    conversation_id: str

class CopilotResponse(BaseModel):
    response: str
    citations: Optional[List[dict]] = None
    suggested_actions: Optional[List[str]] = None

@app.post("/api/plugin/query")
async def handle_query(request: CopilotRequest) -> CopilotResponse:
    """Handle queries from Copilot."""

    # Process the query using your business logic
    result = await process_business_query(request.query, request.context)

    return CopilotResponse(
        response=result["answer"],
        citations=result.get("sources", []),
        suggested_actions=result.get("next_steps", [])
    )

@app.get("/.well-known/ai-plugin.json")
async def get_manifest():
    """Return plugin manifest for Copilot discovery."""
    return {
        "schema_version": "v1",
        "name_for_human": "Sales Analytics",
        "name_for_model": "sales_analytics",
        "description_for_human": "Query sales data and get insights",
        "description_for_model": "Use this plugin to query sales data, analyze trends, and generate reports.",
        "auth": {
            "type": "oauth",
            "authorization_url": "/oauth/authorize",
            "token_url": "/oauth/token"
        },
        "api": {
            "type": "openapi",
            "url": "/openapi.json"
        },
        "capabilities": {
            "conversation_starters": [
                "What were our sales last quarter?",
                "Show me top performing products",
                "Compare sales by region"
            ]
        }
    }

async def process_business_query(query: str, context: dict) -> dict:
    """Process query against business data."""
    # Connect to your data sources
    # Run analysis
    # Return structured response
    pass

Plugin Best Practices

  1. Clear descriptions - Help the model understand when to use your plugin
  2. Structured responses - Include citations and suggested actions
  3. Error handling - Graceful failures with helpful messages
  4. Authentication - Secure access to business data

Custom Copilot plugins bring your business data into the AI conversation.\n\n## Takeaways\n\nAdd a concise, personal takeaway and recommended next steps here.\n

Michael John Peña

Michael John Peña

Senior Data Engineer based in Sydney. Writing about data, cloud, and technology.