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 connectiontools/list- List available toolstools/call- Execute a toolresources/list- List resourcesresources/read- Read a resourceprompts/list- List promptsprompts/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);