MCP integration

Learn how to leverage Caddey's Model Context Protocol (MCP) to access and execute a range of tools.


This guide is designed for developers looking to create a custom AI agent—not tied to a specific platform—that can query and execute tools using Caddey's Model Context Protocol (MCP). Whether you're building a web-based chatbot, a customer support assistant, or an internal automation tool, these steps will help you seamlessly integrate Caddey's MCP capabilities into your custom solution.

MCP is a protocol that enables AI assistants to securely connect to external data sources and tools. Caddey implements MCP to provide a standardized way for AI agents to interact with your connected apps and tools.

Prerequisites

  • Caddey Account: Ensure you have an active Caddey account with at least one OAuth client created.
  • OAuth Access Token: Obtain an access token through OAuth 2.0 flow with your Caddey client.
  • Development Environment: Familiarity with JSON-RPC, Server-Sent Events (SSE), and HTTP clients (e.g., curl or your preferred library).

Step 1: Configure OAuth Authentication

  1. Log in to Caddey at https://app.caddey.ai.
  2. Navigate to the Clients tab.
  3. Select your OAuth client and note the Client ID.
  4. Implement OAuth 2.0 flow to obtain an access token. Here's a Python example using requests-oauthlib:
import os
from requests_oauthlib import OAuth2Session

def get_caddey_access_token(client_id, redirect_uri="http://localhost:8080/callback"):
    oauth = OAuth2Session(
        client_id=client_id,
        redirect_uri=redirect_uri,
        scope=['openid', 'profile', 'email']
    )

    authorization_url, state = oauth.authorization_url('https://auth.caddey.ai/realms/caddey/protocol/openid-connect/auth')
    print(f"Please go to {authorization_url} and authorize access.")
    authorization_response = input('Paste the full redirect URL here: ')

    token = oauth.fetch_token(
        'https://auth.caddey.ai/realms/caddey/protocol/openid-connect/token',
        authorization_response=authorization_response,
        client_secret=None
    )

    return token['access_token']

# Usage
CLIENT_ID = os.getenv("CADDEY_CLIENT_ID")
access_token = get_caddey_access_token(CLIENT_ID)
  1. Use the obtained access token in the Authorization: Bearer header on all MCP requests.

Step 2: Open the SSE Stream & Read Endpoint URL

Establish a persistent SSE connection to receive all JSON-RPC messages (responses and notifications):

curl -N -X GET \
  -H "Accept: text/event-stream" \
  -H "Authorization: Bearer $access_token" \
  https://api.caddey.ai/mcp

The server will respond with Content-Type: text/event-stream and push an initial SSE event named endpoint with the full POST URL (including the sessionId query parameter). For example:

event: endpoint
data: https://api.caddey.ai/mcp?sessionId=abc123def456

Extract the sessionId from this URL—you'll use it for all subsequent JSON-RPC requests.

Step 3: Complete the JSON-RPC Handshake

3a. Send initialize

curl -X POST "https://api.caddey.ai/mcp?sessionId=<SESSION_ID>" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
  -d '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {
        "protocolVersion": "2024-11-05",
        "capabilities": {
          "tools": {}
        },
        "clientInfo": {
          "name": "my-custom-assistant",
          "version": "1.0.0"
        }
      }
    }'

The server responds via SSE with an initialize result containing its capabilities.

3b. Send notifications/initialized

Acknowledge the handshake (no SSE response expected):

curl -X POST "https://api.caddey.ai/mcp?sessionId=<SESSION_ID>" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
  -d '{
      "jsonrpc": "2.0",
      "method": "notifications/initialized",
      "params": {}
    }'

Step 4: List Available Tools

Request the full list of tools:

curl -X POST "https://api.caddey.ai/mcp?sessionId=<SESSION_ID>" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
  -d '{
      "jsonrpc": "2.0",
      "id": 2,
      "method": "tools/list",
      "params": {}
    }'

Step 5: Execute Tools

Call any listed tool by name, passing its arguments:

curl -X POST "https://api.caddey.ai/mcp?sessionId=<SESSION_ID>" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
  -d '{
      "jsonrpc": "2.0",
      "id": 3,
      "method": "tools/call",
      "params": {
        "name": "send_email",
        "arguments": {
          "to": "[email protected]",
          "subject": "Hello from Caddey",
          "body": "This email was sent via MCP!"
        }
      }
    }'

Step 6: Handle Responses

All responses arrive via the SSE stream as JSON-RPC messages. Match responses to requests using the id field.

Advanced Usage

  • SSE reconnect:
    If your SSE connection drops, re-open it using the Last-Event-ID header to resume from the last event:
    curl -N -X GET \
      -H "Accept: text/event-stream" \
      -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
      -H "Last-Event-ID: <LAST_EVENT_ID>" \
      https://api.caddey.ai/mcp
    
    You do not need to re-run the JSON-RPC handshake unless the server's protocol version changes.

Additional Resources

Need assistance? Visit the Support Section.