Skip to main content

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:

MethodDescription
initializeInitialize the MCP session
tools/listList all available tools (from tool functions and MCP connectors)
tools/callCall a tool by name with arguments
resources/listList all available resources from connected MCP servers
resources/readRead a resource by its URI. Returns text or binary content.
resources/templates/listList all available resource templates from connected MCP servers
prompts/listList all available prompts with their arguments
prompts/getGet 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 URI
  • name - The resource name
  • description - A description of the resource
  • mimeType - 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 parameters
  • name - The template name
  • description - A description of the template
  • mimeType - The MIME type of resources generated by this template

Prompts

When listing prompts, each prompt includes:

  • name - The prompt name
  • description - A description of the prompt
  • arguments - An array of arguments, each with name, description, and required

When getting a prompt, the response includes:

  • description - The prompt description
  • messages - An array of messages, each with role (e.g. user, assistant) and content (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

ParameterTypeDescription
include_functionsarray of stringsOnly expose functions matching these regex patterns
exclude_functionsarray of stringsHide functions matching these regex patterns
include_resourcesarray of stringsOnly expose resources matching these patterns
exclude_resourcesarray of stringsHide resources matching these patterns
include_resource_templatesarray of stringsOnly expose resource templates matching these patterns
exclude_resource_templatesarray of stringsHide resource templates matching these patterns
include_resource_template_urisarray of stringsOnly expose resource template URIs matching these patterns
exclude_resource_template_urisarray of stringsHide resource template URIs matching these patterns
include_promptsarray of stringsOnly expose prompts matching these patterns
exclude_promptsarray of stringsHide prompts matching these patterns
allow_rulesobjectAdvanced JsonPath-based allow rules (see MCP Connectors - Advanced rules)
disallow_rulesobjectAdvanced 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"
}