Remote MCP providers
mrl rlm can mount read-only tools from a remote MCP Streamable HTTP server. The trusted mrl host owns endpoint policy, OAuth or bearer secrets, MCP session state, cancellation, and response limits. Generated Python receives ordinary Droste capability bindings—not MCP URLs, credentials, session IDs, transport envelopes, or raw tool results.
This integration is for local and customer-controlled VPC execution. Hosted mrl rlm --remote and /rlm/execute reject remote MCP configuration. Run mrl inside the network that is allowed to reach the MCP server; do not copy private endpoints or credentials into a hosted request.
Configure a source
Create a mode-0600 JSON file such as docs-mcp.json:
{
"name": "docs",
"config": {
"endpoint": "https://mcp.example.com/v1",
"allowed_endpoints": ["https://mcp.example.com/v1"],
"tenant_id": "project-123",
"auth": {
"type": "bearer",
"token_ref": "docs-access"
},
"allowed_tools": ["search", "read_document"],
"bindings": {
"search": "search",
"read_document": "read_document"
},
"effects": {
"search": "read",
"read_document": "read"
},
"budget_classes": {
"search": "data.search",
"read_document": "data.read"
},
"policy_metadata": {
"search": {"read_only": true},
"read_document": {"read_only": true}
},
"source_description": "Approved product documentation."
},
"secrets": {
"docs-access": "DOCS_MCP_TOKEN"
},
"allowed_networks": []
}
The config object is the released Droste MCP HTTP contract. ModelRelay deliberately passes it through instead of maintaining a second provider schema.
secrets maps each logical reference used by config.auth to an environment-variable name. Secret values are not accepted in the file:
export DOCS_MCP_TOKEN='replace-with-the-token'
mrl rlm \
"Compare the current retention and deletion policies" \
--mcp-config ./docs-mcp.json
mrl reads the value into a tenant/source/reference-scoped host broker and removes DOCS_MCP_TOKEN from the Python subprocess environment. The runner configuration contains only docs-access. The MCP transport asks the authenticated loopback broker for that reference when it needs a bearer token.
Local RLM still runs as your OS user; it is not a general sandbox for unrelated files or services available to that account. The MCP boundary specifically prevents generated code from receiving MCP transport configuration, credentials, sessions, or raw protocol payloads. Run VPC deployments under a dedicated least-privilege service account.
Inside generated code, the approved binding names are available under the configured source:
matches = docs.search(query="retention policy")
policy = docs.read_document(id=matches[0]["id"])
Use --mcp-config more than once to mount multiple providers. If no SQL source already supplies the default, select one explicitly:
mrl rlm "Reconcile the policy with open customer requests" \
--mcp-config ./docs-mcp.json \
--mcp-config ./tickets-mcp.json \
--default-source docs
Source names must be unique Python identifiers. Each run acquires independent MCP sessions and closes them with the runner, so state cannot cross a run or tenant boundary.
OAuth client credentials
For MCP servers using OAuth protected-resource discovery, keep client credentials behind logical references as well:
{
"type": "oauth_client_credentials",
"client_id_ref": "docs-client-id",
"client_secret_ref": "docs-client-secret",
"resource_metadata_url": "https://mcp.example.com/.well-known/oauth-protected-resource/v1",
"authorization_server": "https://login.example.com",
"token_endpoints": ["https://login.example.com/oauth/token"],
"scopes": ["docs.read"]
}
Map both references in the envelope’s secrets object. Droste performs discovery only against the exact configured resource, issuer, and token-endpoint allowlists. Access and refresh tokens remain in the trusted transport session.
Policy and limits
The configuration must explicitly classify every allowed tool:
allowed_toolsis the exact discovery allowlist. Unexpected or missing tools fail acquisition.bindingsdefines the generated Python names.effectsmust classify every tool asread.mrlrejects effectful tools because this surface has no user-confirmation policy; never mislabel a mutating tool to bypass that gate.budget_classesparticipates in Droste capability budgeting and audit facts.policy_metadatacarries ModelRelay/Droste admission facts without trusting MCP annotations.
Optional hard bounds include startup_timeout_ms, request_timeout_ms, close_timeout_ms, max_frame_bytes, max_descriptor_bytes, max_result_bytes, max_tool_pages, max_tools, max_in_flight, reconnect_attempts, and backoff_ms. Defaults are conservative; raise them only for a measured requirement.
allowed_networks is ModelRelay host policy, not Droste provider configuration. Leave it empty for public endpoints. A VPC deployment may list only the canonical private CIDRs that contain the approved MCP endpoint, for example "allowed_networks": ["10.40.8.0/24"]. Resolved addresses outside those exact networks still fail closed.
The transport requires canonical HTTPS endpoints, pins resolved addresses for each connection, denies private and metadata networks by default, rejects redirects, bounds JSON/SSE frames, reconciles cancellation and deadlines, and normalizes results before the capability broker sees them. mrl rlm --json reports data_source_requests for host attribution; normalized capability metrics remain content-free.
Deployment support
| Mode | Support | Secret owner | Network boundary |
|---|---|---|---|
Local mrl rlm |
Supported | Local mrl host broker |
Current machine |
Customer VPC mrl rlm |
Supported | VPC mrl host broker |
Customer VPC policy |
Hosted mrl rlm --remote / /rlm/execute |
Not supported; fails closed | N/A | No MCP endpoint is accepted |
Hosted support requires a connector-neutral trusted provider sidecar that feeds Droste’s provider bridge. It must not move MCP transport or auth into the untrusted Pyodide interpreter. Until that substrate exists, use local/VPC mode or wrapper_v1 for an existing hosted wrapper.