Custom Agent Integration

Add policy enforcement to any MCP client or custom AI agent.

Overview

Keypost works with any MCP-compatible client. If your agent speaks MCP over HTTP, just point it at your Keypost URL instead of the upstream server.

HTTP integration

Keypost exposes a standard MCP endpoint. Send JSON-RPC requests to:

POST https://abc123xyz.keypost.ai/mcp
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_issue",
    "arguments": {
      "title": "Bug report",
      "body": "Description here"
    }
  }
}

Supported MCP methods

Keypost proxies all standard MCP methods:

  • initialize - Initialize the connection
  • tools/list - List available tools
  • tools/call - Execute a tool
  • resources/list - List resources
  • resources/read - Read a resource
  • prompts/list - List prompts
  • prompts/get - Get a prompt

SSE streaming

Keypost supports Server-Sent Events (SSE) for streaming responses. If the upstream server returns an SSE stream, Keypost passes it through with per-event DLP scrubbing applied.

Authentication

Keypost URLs are unguessable (10-12 random characters). For additional security, you can add an API key requirement in your Keypost settings.

POST https://abc123xyz.keypost.ai/mcp
Authorization: Bearer your-api-key
Content-Type: application/json

...

Error responses

When a policy denies a request, Keypost returns a standard MCP error:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32001,
    "message": "Request denied by policy: throttle limit exceeded (100/hour)"
  }
}

Example: Python client

import requests

def call_tool(keypost_url, tool_name, arguments):
    response = requests.post(
        keypost_url,
        json={
            "jsonrpc": "2.0",
            "id": 1,
            "method": "tools/call",
            "params": {
                "name": tool_name,
                "arguments": arguments
            }
        }
    )
    return response.json()

result = call_tool(
    "https://abc123xyz.keypost.ai/mcp",
    "search_issues",
    {"query": "is:open label:bug"}
)
print(result)

Example: TypeScript client

async function callTool(keypostUrl: string, toolName: string, args: object) {
  const response = await fetch(keypostUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'tools/call',
      params: { name: toolName, arguments: args }
    })
  });
  return response.json();
}

const result = await callTool(
  'https://abc123xyz.keypost.ai/mcp',
  'search_issues',
  { query: 'is:open label:bug' }
);
console.log(result);