ArmorIQ LogoArmorIQ SDK

MCP Format Requirements

Required format for building MCPs compatible with ArmorIQ SDK

MCP Format Requirements

This guide outlines the exact format requirements for building Model Context Protocol (MCP) servers that integrate with the ArmorIQ SDK.

Protocol Requirements

Transport Protocol

  • Protocol: JSON-RPC 2.0 over HTTP
  • Response Format: Server-Sent Events (SSE)
  • Endpoint: Must expose a POST endpoint (e.g., /mcp)
  • Content-Type: application/json for requests
  • Response Type: text/event-stream for responses

SSE Response Format

All JSON-RPC responses must be wrapped in SSE format:

event: message
data: {json-rpc-response}

Note: The double newline at the end is required.

Required Methods

1. initialize

Handshake between client and server.

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {
      "name": "armoriq-agent",
      "version": "1.0.0"
    }
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {}
    },
    "serverInfo": {
      "name": "your-mcp-server-name",
      "version": "1.0.0"
    }
  }
}

2. tools/list

Return list of available tools.

Request:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}

Response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "tool_name",
        "description": "Clear description of what this tool does",
        "inputSchema": {
          "type": "object",
          "properties": {
            "parameter1": {
              "type": "string",
              "description": "Description of parameter1"
            }
          },
          "required": ["parameter1"]
        }
      }
    ]
  }
}

3. tools/call

Execute a specific tool.

Request:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "tool_name",
    "arguments": {
      "parameter1": "value1"
    }
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"result\": \"your data here\"}"
      }
    ]
  }
}

Important:

  • The content field must be an array
  • Each item must have type: "text"
  • The actual data must be a JSON string in the text field
  • Do NOT return raw objects in text, stringify them first

Python Implementation Example

from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse
import json

app = FastAPI()

TOOLS = [
    {
        "name": "example_tool",
        "description": "Example tool description",
        "inputSchema": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Query parameter"
                }
            },
            "required": ["query"]
        }
    }
]

def sse_response(data):
    """Format response as SSE"""
    json_str = json.dumps(data)
    return f"event: message\ndata: {json_str}\n\n"

async def handle_jsonrpc(request_data):
    method = request_data.get("method")
    msg_id = request_data.get("id")
    
    if method == "initialize":
        return {
            "jsonrpc": "2.0",
            "id": msg_id,
            "result": {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {
                    "name": "example-mcp",
                    "version": "1.0.0"
                }
            }
        }
    
    elif method == "tools/list":
        return {
            "jsonrpc": "2.0",
            "id": msg_id,
            "result": {"tools": TOOLS}
        }
    
    elif method == "tools/call":
        tool_name = request_data["params"]["name"]
        arguments = request_data["params"]["arguments"]
        
        # Execute your tool logic here
        result_data = {"result": "processed data"}
        
        return {
            "jsonrpc": "2.0",
            "id": msg_id,
            "result": {
                "content": [
                    {
                        "type": "text",
                        "text": json.dumps(result_data)
                    }
                ]
            }
        }

@app.post("/mcp")
async def mcp_endpoint(request: Request):
    request_data = await request.json()
    response_data = await handle_jsonrpc(request_data)
    
    async def stream():
        yield sse_response(response_data)
    
    return StreamingResponse(
        stream(),
        media_type="text/event-stream"
    )

Deployment Requirements

Your MCP must be deployed and accessible via HTTPS:

  1. Endpoint: Public HTTPS URL (e.g., https://your-mcp.example.com)
  2. Authentication: Proper authentication mechanism enabled
  3. Environment: Production-ready with proper error handling

Testing Your MCP

Before registering with ArmorIQ:

  1. Test the /mcp endpoint responds to POST requests
  2. Verify SSE format in responses
  3. Ensure all three methods (initialize, tools/list, tools/call) work
  4. Check that tool responses are properly JSON-stringified

Common Issues

Response Not Streaming

Ensure you're returning StreamingResponse with media_type="text/event-stream".

Tools Not Found

Verify your tools/list response matches the exact format shown above.

Invalid JSON in Response

The text field in tools/call response must contain a JSON string, not a raw object.

On this page