Skip to main content
Connect a Semantic Kernel agent to Civic using MCPStreamableHttpPlugin. The plugin registers all Civic tools as kernel functions and makes them available to your agent.

Prerequisites

  • Python 3.11+
  • A Civic account at nexus.civic.com with a configured toolkit
  • A Civic token and an Anthropic API key

Installation

Semantic Kernel requires Pydantic v2 (not v3/v4). Use a dedicated virtual environment if you have other packages installed:
pip install "semantic-kernel" "anthropic" "pydantic>=2.0.0,<3.0.0" python-dotenv

Environment Variables

CIVIC_URL=https://nexus.civic.com/hub/mcp?profile=your-toolkit
CIVIC_TOKEN=your-civic-token
ANTHROPIC_API_KEY=your-anthropic-key

Get Your Credentials

How to generate a Civic token and configure toolkit URL parameters

Connecting to Civic

Use MCPStreamableHttpPlugin as an async context manager to load all Civic tools into the kernel:
import os
import asyncio
from dotenv import load_dotenv
from semantic_kernel import Kernel
from semantic_kernel.connectors.mcp import MCPStreamableHttpPlugin
from semantic_kernel.connectors.ai.anthropic import AnthropicChatCompletion
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior

load_dotenv()

async def main():
    kernel = Kernel()

    svc = AnthropicChatCompletion(
        ai_model_id="claude-sonnet-4-6",
        api_key=os.environ["ANTHROPIC_API_KEY"],
    )
    kernel.add_service(svc)

    async with MCPStreamableHttpPlugin(
        name="civic",  # name is required
        url=os.environ["CIVIC_URL"],
        headers={"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"},
    ) as civic_plugin:
        kernel.add_plugin(civic_plugin)

        plugin = kernel.plugins.get("civic")
        print(f"{len(plugin.functions)} tools loaded")

        settings = svc.get_prompt_execution_settings_class()()
        settings.function_choice_behavior = FunctionChoiceBehavior.Auto()

        result = await kernel.invoke_prompt(
            "What events do I have today?",
            settings=settings,
        )
        print(result)

asyncio.run(main())
The name parameter is required for MCPStreamableHttpPlugin. Use kernel.invoke_prompt() directly — not kernel.get_service(AnthropicChatCompletion) followed by chat_completion.get_chat_message_contents(), which raises a KernelServiceNotFoundError.

Production Configuration

For production agents, lock to a specific toolkit using the profile URL parameter:
CIVIC_URL=https://nexus.civic.com/hub/mcp?profile=your-production-toolkit

Reference Implementation

semantic-kernel-reference-implementation-civic

Complete implementation with FastAPI chat UI, isolated venv setup, and deployment guide

Next Steps

Agent Deployment

Production deployment guide: profile locking, URL params, authentication

Guardrails

Constrain what tools your agent can call

Audit Trail

Query what your agent did via Civic Chat

Get Credentials

Token generation and URL parameter reference