Expose a self-hosted server
Make an MCP server that runs in your network or cluster reachable by sremcp, safely.
Servers like Grafana, Kubernetes, Prometheus or PostgreSQL usually run next to the systems they read, inside your network. sremcp needs to reach them. There are two ways.
| Public https endpoint with a key | sremcp in your network | |
|---|---|---|
| Works with app.sremcp.com | ✓ | |
| Works with self-hosted sremcp | ✓ | ✓ |
| What you add | TLS, a hostname, an API key | Nothing on the MCP side |
Option 1: a public https endpoint with an API key
Require a key
Every request must carry a secret. Some servers check one themselves, for example Grafana's
MCP_GRAFANA_SERVER_TOKEN. For the rest, put Supergateway in front
with --apiKey.
For a stdio server, Supergateway runs it:
supergateway --stdio "uvx some-mcp-server" \
--outputTransport streamableHttp --port 8000 --apiKey "$MCP_API_KEY"For a server that already speaks HTTP but has no key of its own (Kubernetes, Prometheus), Supergateway proxies to it:
supergateway --streamableHttp "http://kubernetes-mcp-server:8080/mcp" \
--outputTransport streamableHttp --stateful --port 8000 --apiKey "$MCP_API_KEY"Requests without Authorization: Bearer <key> (or X-API-Key: <key>) get 401.
Serve it over https
Give it a hostname and a certificate with what you already use: a Kubernetes Ingress with cert-manager, a cloud load
balancer, or a Cloudflare Tunnel. Route only the MCP path, usually /mcp.
# Ingress for Supergateway in front of an MCP server (cert-manager issues the certificate).
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mcp-kubernetes
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts: [mcp-k8s.example.com]
secretName: mcp-k8s-tls
rules:
- host: mcp-k8s.example.com
http:
paths:
- path: /mcp
pathType: Prefix
backend:
service: { name: mcp-kubernetes-gateway, port: { number: 8000 } }Onboard it
Endpoint URL https://mcp-k8s.example.com/mcp, Transport Streamable HTTP, Authentication
Bearer token, and the key as the Secret.
Don't expose a server without a key
An MCP server answers anyone who can reach it, with its own credentials. Never publish one without a key, and give
the server itself read-only credentials (a Grafana Viewer, a Kubernetes view role, a read-only database role), so
even a leaked key can only read.
Option 2: run sremcp in your network
A self-hosted sremcp can reach private addresses and plain http:// when its API sets
MCP_ALLOW_PRIVATE_NETWORKS=true. Then onboard servers by their in-cluster address, for example
http://kubernetes-mcp-server.mcp.svc:8080/mcp.
- Keep a key on servers that offer one. Anything in the cluster can reach them too.
- Restrict which hosts sremcp may call with
MCP_ALLOWED_HOSTS, a comma-separated list of host suffixes, for examplemcp.svc.cluster.local,example.com. - Cloud metadata addresses stay blocked either way.