MCP server exposition
Otoroshi can expose tool functions and MCP connectors as MCP servers using three different transport protocols: HTTP, SSE, and WebSocket. This allows external MCP clients to connect to your Otoroshi-managed tools.
Supported MCP methods
All three transport plugins (HTTP, SSE, WebSocket) implement the full MCP protocol:
| Method | Description |
|---|---|
initialize | Initialize the MCP session |
tools/list | List all available tools (from tool functions and MCP connectors) |
tools/call | Call a tool by name with arguments |
resources/list | List all available resources from connected MCP servers |
resources/read | Read a resource by its URI. Returns text or binary content. |
resources/templates/list | List all available resource templates from connected MCP servers |
prompts/list | List all available prompts with their arguments |
prompts/get | Get a prompt by name with arguments. Returns the prompt description and messages (each with role and content). |
Resources
When listing resources, each resource includes:
uri- The resource URIname- The resource namedescription- A description of the resourcemimeType- The MIME type of the resource
When reading a resource, the content is returned as either text (with uri, mimeType, text) or binary blob (with uri, mimeType, blob).
Resource Templates
When listing resource templates, each template includes:
uriTemplate- The URI template with parametersname- The template namedescription- A description of the templatemimeType- The MIME type of resources generated by this template
Prompts
When listing prompts, each prompt includes:
name- The prompt namedescription- A description of the promptarguments- An array of arguments, each withname,description, andrequired
When getting a prompt, the response includes:
description- The prompt descriptionmessages- An array of messages, each withrole(e.g.user,assistant) andcontent(text or image)
Filtering at the plugin level
All MCP server exposition plugins (HTTP, SSE, WebSocket) support filtering which tools, resources, resource templates, and prompts are exposed to clients. These filters are applied on top of any filters already configured on the MCP connectors themselves.
Available filters
| Parameter | Type | Description |
|---|---|---|
include_functions | array of strings | Only expose functions matching these regex patterns |
exclude_functions | array of strings | Hide functions matching these regex patterns |
include_resources | array of strings | Only expose resources matching these patterns |
exclude_resources | array of strings | Hide resources matching these patterns |
include_resource_templates | array of strings | Only expose resource templates matching these patterns |
exclude_resource_templates | array of strings | Hide resource templates matching these patterns |
include_resource_template_uris | array of strings | Only expose resource template URIs matching these patterns |
exclude_resource_template_uris | array of strings | Hide resource template URIs matching these patterns |
include_prompts | array of strings | Only expose prompts matching these patterns |
exclude_prompts | array of strings | Hide prompts matching these patterns |
allow_rules | object | Advanced JsonPath-based allow rules (see MCP Connectors - Advanced rules) |
disallow_rules | object | Advanced JsonPath-based disallow rules |
Example plugin configuration with filters
{
"name": "filtered-mcp-server",
"version": "1.0.0",
"refs": ["tool-function_xxxxx"],
"mcp_refs": ["mcp-connector_xxxxx"],
"include_functions": ["get_.*", "list_.*"],
"exclude_functions": ["delete_.*"],
"include_prompts": ["summarize"],
"exclude_prompts": [],
"include_resources": [],
"exclude_resources": ["admin_.*"]
}
These plugin-level filters are merged with the filters defined on each MCP connector. This means you can have broad access on the connector itself and restrict it further at the exposition level, or vice versa.
MCP Http Plugin


Configuration
{
"_loc": {
"tenant": "default",
"teams": [
"default"
]
},
"id": "route_2629d12c2-130b-42d5-aba5-b584b95961c9",
"name": "MCP HTTP server exposition",
"description": "MCP HTTP server exposition",
"tags": [],
"metadata": {},
"enabled": true,
"debug_flow": false,
"export_reporting": false,
"capture": false,
"groups": [
"default"
],
"bound_listeners": [],
"frontend": {
"domains": [
"mcp-http-expo.oto.tools"
],
"strip_path": true,
"exact": false,
"headers": {},
"query": {},
"methods": []
},
"backend": {
"targets": [
{
"id": "target_1",
"hostname": "request.otoroshi.io",
"port": 443,
"tls": true,
"weight": 1,
"predicate": {
"type": "AlwaysMatch"
},
"protocol": "HTTP/1.1",
"ip_address": null,
"tls_config": {
"certs": [],
"trusted_certs": [],
"enabled": false,
"loose": false,
"trust_all": false
}
}
],
"root": "/",
"rewrite": false,
"load_balancing": {
"type": "RoundRobin"
},
"client": {
"retries": 1,
"max_errors": 20,
"retry_initial_delay": 50,
"backoff_factor": 2,
"call_timeout": 30000,
"call_and_stream_timeout": 120000,
"connection_timeout": 10000,
"idle_timeout": 60000,
"global_timeout": 30000,
"sample_interval": 2000,
"proxy": {},
"custom_timeouts": [],
"cache_connection_settings": {
"enabled": false,
"queue_size": 2048
}
},
"health_check": {
"enabled": false,
"url": "",
"timeout": 5000,
"healthyStatuses": [],
"unhealthyStatuses": []
}
},
"backend_ref": null,
"plugins": [
{
"enabled": true,
"debug": false,
"plugin": "cp:otoroshi.next.plugins.OverrideHost",
"include": [],
"exclude": [],
"config": {},
"bound_listeners": [],
"plugin_index": {
"transform_request": 0
},
"nodeId": "cp:otoroshi.next.plugins.OverrideHost"
},
{
"enabled": true,
"debug": false,
"plugin": "cp:otoroshi_plugins.com.cloud.apim.otoroshi.extensions.aigateway.plugins.McpRespEndpoint",
"include": [],
"exclude": [],
"config": {
"name": "first-mcp-http-server",
"version": "1.0.0",
"refs": [
"tool-function_0511ff44-0ce5-487d-aa1c-d1980ac9a4b8"
],
"mcp_refs": []
},
"bound_listeners": [],
"plugin_index": {},
"nodeId": "cp:otoroshi_plugins.com.cloud.apim.otoroshi.extensions.aigateway.plugins.McpRespEndpoint"
}
],
"kind": "proxy.otoroshi.io/Route"
}
MCP SSE Plugin


Configuration
{
"_loc": {
"tenant": "default",
"teams": [
"default"
]
},
"id": "route_73e79129a-1cc6-4473-970a-b80905e80c7b",
"name": "mcp-sse-exposition",
"description": "mcp-sse-exposition",
"tags": [],
"metadata": {},
"enabled": true,
"debug_flow": false,
"export_reporting": false,
"capture": false,
"groups": [
"default"
],
"bound_listeners": [],
"frontend": {
"domains": [
"mcp-sse-exposition.oto.tools"
],
"strip_path": true,
"exact": false,
"headers": {},
"query": {},
"methods": []
},
"backend": {
"targets": [
{
"id": "target_1",
"hostname": "request.otoroshi.io",
"port": 443,
"tls": true,
"weight": 1,
"predicate": {
"type": "AlwaysMatch"
},
"protocol": "HTTP/1.1",
"ip_address": null,
"tls_config": {
"certs": [],
"trusted_certs": [],
"enabled": false,
"loose": false,
"trust_all": false
}
}
],
"root": "/",
"rewrite": false,
"load_balancing": {
"type": "RoundRobin"
},
"client": {
"retries": 1,
"max_errors": 20,
"retry_initial_delay": 50,
"backoff_factor": 2,
"call_timeout": 30000,
"call_and_stream_timeout": 120000,
"connection_timeout": 10000,
"idle_timeout": 60000,
"global_timeout": 30000,
"sample_interval": 2000,
"proxy": {},
"custom_timeouts": [],
"cache_connection_settings": {
"enabled": false,
"queue_size": 2048
}
},
"health_check": {
"enabled": false,
"url": "",
"timeout": 5000,
"healthyStatuses": [],
"unhealthyStatuses": []
}
},
"backend_ref": null,
"plugins": [
{
"enabled": true,
"debug": false,
"plugin": "cp:otoroshi.next.plugins.OverrideHost",
"include": [],
"exclude": [],
"config": {},
"bound_listeners": [],
"nodeId": "cp:otoroshi.next.plugins.OverrideHost",
"plugin_index": {
"transform_request": 0
}
},
{
"plugin_index": {},
"nodeId": "cp:otoroshi_plugins.com.cloud.apim.otoroshi.extensions.aigateway.plugins.McpSseEndpoint-0",
"plugin": "cp:otoroshi_plugins.com.cloud.apim.otoroshi.extensions.aigateway.plugins.McpSseEndpoint",
"enabled": true,
"debug": false,
"include": [],
"exclude": [],
"bound_listeners": [],
"config": {
"name": "mcp-sse",
"version": "1.0.0",
"refs": [
"tool-function_0511ff44-0ce5-487d-aa1c-d1980ac9a4b8"
],
"mcp_refs": []
}
}
],
"kind": "proxy.otoroshi.io/Route"
}
MCP WebSocket Plugin


Configuration
{
"_loc": {
"tenant": "default",
"teams": [
"default"
]
},
"id": "route_62c427cac-43c9-4d86-bab4-56cb0b61040b",
"name": "mcp-websocket-exposition",
"description": "mcp-websocket-exposition",
"tags": [],
"metadata": {},
"enabled": true,
"debug_flow": false,
"export_reporting": false,
"capture": false,
"groups": [
"default"
],
"bound_listeners": [],
"frontend": {
"domains": [
"mcp-websocket-exposition.oto.tools"
],
"strip_path": true,
"exact": false,
"headers": {},
"query": {},
"methods": []
},
"backend": {
"targets": [
{
"id": "target_1",
"hostname": "request.otoroshi.io",
"port": 443,
"tls": true,
"weight": 1,
"predicate": {
"type": "AlwaysMatch"
},
"protocol": "HTTP/1.1",
"ip_address": null,
"tls_config": {
"certs": [],
"trusted_certs": [],
"enabled": false,
"loose": false,
"trust_all": false
}
}
],
"root": "/",
"rewrite": false,
"load_balancing": {
"type": "RoundRobin"
},
"client": {
"retries": 1,
"max_errors": 20,
"retry_initial_delay": 50,
"backoff_factor": 2,
"call_timeout": 30000,
"call_and_stream_timeout": 120000,
"connection_timeout": 10000,
"idle_timeout": 60000,
"global_timeout": 30000,
"sample_interval": 2000,
"proxy": {},
"custom_timeouts": [],
"cache_connection_settings": {
"enabled": false,
"queue_size": 2048
}
},
"health_check": {
"enabled": false,
"url": "",
"timeout": 5000,
"healthyStatuses": [],
"unhealthyStatuses": []
}
},
"backend_ref": null,
"plugins": [
{
"enabled": true,
"debug": false,
"plugin": "cp:otoroshi.next.plugins.OverrideHost",
"include": [],
"exclude": [],
"config": {},
"bound_listeners": [],
"nodeId": "cp:otoroshi.next.plugins.OverrideHost",
"plugin_index": {
"transform_request": 0
}
},
{
"plugin_index": {},
"nodeId": "cp:otoroshi_plugins.com.cloud.apim.otoroshi.extensions.aigateway.plugins.McpWebsocketEndpoint-0",
"plugin": "cp:otoroshi_plugins.com.cloud.apim.otoroshi.extensions.aigateway.plugins.McpWebsocketEndpoint",
"enabled": true,
"debug": false,
"include": [],
"exclude": [],
"bound_listeners": [],
"config": {
"name": "mcp-server",
"version": "1.0.0",
"refs": [
"tool-function_0511ff44-0ce5-487d-aa1c-d1980ac9a4b8"
],
"mcp_refs": []
}
}
],
"kind": "proxy.otoroshi.io/Route"
}