Skip to main content

MCP hosting (mcp-host)

Hosts the stdio MCP servers declared per tenant and per project in the Manager (navin-mcp-host): each server is started on demand, isolated in its own process (isolation process) or in its own rootless Podman container on the network of its tenant project (isolation container) with its memory and concurrency limits, and served over streamable HTTP at /t/{tenant}/p/{project}/s/{name}/mcp with its own bearer token. The list of hosted servers is written by the Manager (servers.json) and reloaded without restart.

Generated from catalog/services/mcp-host.yaml: do not edit by hand.

Summary​

Version1.0.0
Useinstall and configure
Layerfunctional (AI catalog)
CategoryGateways and load balancing
Installation methodspython
External connectionno
Sandbox onlyno

Licence​

SPDX identifierApache-2.0
Licence policycore licence (MIT or Apache-2.0)
Licence exception-
Platform componentnavin-mcp-host

Packages and artifacts​

A package the project of the service publishes (its image, its binary archive, its Python or OS package) carries the licence of the service; a third-party package carries the licence written on its row, read from the official upstream metadata.

KindPackageVersionLicenceDetails
container imagedocker.io/library/node22.23.4-bookworm-slimApache-2.0image key node, digest sha256:4b150b48b4116e2a22f2c39cc27025fbf4f153e2078fd3b14d159fdb5c7279da
container imagedocker.io/astral/uv0.9.30-python3.12-bookworm-slimApache-2.0image key python, digest sha256:e5b65587bce7de595f299855d7385fe7fca39b8a74baa261ba1b7147afa78e58
Python packagenavin-mcp-host1.0.0Apache-2.0interpreters, in order of preference python3.12, python3.11, python3.10

Images are pinned by tag in the descriptor, and by digest when the descriptor declares one (the offline bundle then refuses a pulled image that does not carry it); the digest is recorded in the mirror of the Manager when the offline bundle is imported, and every pull or load is checked against it.

Supported systems and architectures​

MethodOperating systemsArchitectures
pythonRHEL family (dnf), Debian family (apt), Arch Linux (pacman)x86_64, aarch64 (not restricted by the descriptor)

Certified host systems: RHEL 8/9/10, Rocky Linux 8/9/10, AlmaLinux 8/9/10, Oracle Linux 8/9, CentOS Stream 9/10, Ubuntu 22.04/24.04, Debian 12, Arch Linux (rolling). The host preflight accepts these systems (other releases of a known family give a warning, end of life releases are refused) and the x86_64 and aarch64 architectures.

Prerequisites​

Host​

  • at least 1024 MB of memory (blocking, memory).
  • the program npx installed on the host, only when isolation is process (warning, npx_present).
  • the program uvx installed on the host, only when isolation is process (warning, uvx_present).
  • the program podman installed on the host, only when isolation is container (blocking, podman_present).
  • subordinate uid and gid ranges of the user navin-mcp-host in /etc/subuid and /etc/subgid (created by user.ensure on a root agent with usermod), only when isolation is container (blocking, subordinate_ids).

Network and ports​

ComponentPort namePortOpened in the host firewall
mcp-hostmcp8790/tcpyes

Services and connections needed​

This service has no dependency.

Installation methods and modes​

MethodDefaultWhat the method uses
pythonyesa Python virtual environment holding the Python packages of the descriptor

Components​

ComponentKindInstallation methodsPorts
MCP host (mcp-host)masterpython8790/tcp

Single instance (single) (default)​

One instance hosts every MCP server of the cluster.

What the mode deploys:

ComponentPlacement
mcp-hostmin 1, max 1

Distributed (replicated)​

Two instances or more; each MCP server is placed on one instance, chosen by int(sha256(id)[:8], 16) modulo the number of instances sorted by id.

What the mode deploys:

ComponentPlacement
mcp-hostmin 2, recommended 2

Install this service​

The install wizard of the Navin Manager plans, validates and runs the installation; you need the services:install permission on the cluster.

  1. Open the wizard. In Clusters, choose the row action Install services of the target cluster. The wizard opens on its first step, Service.

  2. Choose the service. On the Service step, select MCP hosting. The card shows the licence Apache-2.0.

  3. Choose the hosts and the mode. On the Hosts step, tick the hosts, then choose the Mode: single (default), replicated. Each mode deploys the components listed in Installation methods and modes.

  4. Bindings. This service has no dependency: the Bindings step has nothing to bind.

  5. Configure. On the Configure step, review the parameters (see Configuration parameters). Passwords left empty with a generated default are generated and sealed by the Manager.

  6. Review and install. On the Install step the Manager validates the plan and shows the installation order; when it says "The plan is valid. Ready to install.", choose Install. A highly available mode is installed only when its HA checks pass.

  7. Verify. The operation ends when the health checks of every instance pass (see Health checks); the service then shows as running in Services.

High availability​

Clusternone (none)
High availabilityredundancy (redundancy)
Failovernone (none)
Replicationnone (none)
Quorumnone (none)
Discoverystatic (static)
Entry pointany node (any-node)
Official documentationhttps://modelcontextprotocol.io/specification/2025-03-26/basic/transports
Peer TLS parametertls_enabled
Peer authenticationNo traffic between the instances: each one reads its own servers.json written by the Manager.

Topology per mode​

ModesHighest catalog levelDistributionQuorum componentFault domainsDescription
singlestandalone (standalone)single (single)--One instance hosts every server; it is a single point of failure.
replicatedstandalone (standalone)active-active (active-active)-2The servers are spread over the instances, each server on exactly one instance; the load is shared, a failed instance stops its own servers only.

Notes​

  • Distribution, not high availability: a server is not moved when its instance fails; the Manager places it again on the next application of the hosting.

Configuration parameters​

Network​

ParameterTypeDefaultAllowed valuesRequiredSecretRestartDescription
MCP port (port)port8790-nonoyesPort of the streamable HTTP endpoint of the hosted servers, of /healthz and of /metrics.
TLS (tls_enabled)boolfalse-nonoyesServe the endpoint over TLS with a certificate issued by the manager CA.
Maximum request size (max_body_kb)int1024min 16, max 65536nononoKilobytes accepted in one MCP request; larger bodies are refused with 413.

Limits of the hosted servers​

ParameterTypeDefaultAllowed valuesRequiredSecretRestartDescription
Memory per server (default_memory_mb)int512min 64, max 65536nononoDefault memory limit (MB) of one hosted server process; a server may set its own limit.
Concurrent requests per server (default_max_concurrency)int8min 1, max 256nononoDefault number of requests a hosted server handles at the same time; the others wait.
Request timeout (request_timeout_s)int60min 1, max 3600nononoSeconds before a call to a hosted server is abandoned.
Idle timeout (idle_timeout_s)int600min 10, max 86400nononoSeconds without a request after which the process of a hosted server is stopped (started again on the next request).
Maximum servers per instance (max_servers)int200min 1, max 10000nononoHosted servers accepted by one instance; the extra entries of servers.json are ignored and reported.

Runtime​

ParameterTypeDefaultAllowed valuesRequiredSecretRestartDescription
PATH of the servers (runtime_path)string/usr/local/bin:/usr/bin:/bin-nononoPATH given to the hosted server processes (where npx, uvx or the server commands are found); with the isolation container, PATH of the podman commands (the servers keep the PATH of their image).
Allowed origins (allowed_origins)json[]-nononoOrigin headers accepted from browsers (JSON list); empty refuses every browser origin.
Log level (log_level)enuminfodebug, info, warning, errornononoVerbosity of the runtime log.

Isolation of the servers​

ParameterTypeDefaultAllowed valuesRequiredSecretRestartDescription
Isolation (isolation)enumprocessprocess, containernonoyesprocess: each server is a child process of the host (separation by configuration, validated servers of the company catalogue only). container: each server runs in a rootless Podman container, one network per tenant project, read-only root file system, no capability, memory and pids quotas; needed for untrusted servers.
Processes per container (container_pids_limit)int256min 16, max 65536nononoMaximum number of processes and threads of one server container (podman --pids-limit).
Temporary space per container (container_tmpfs_mb)int64min 1, max 4096nononoSize (MB) of the in-memory /tmp of one server container, the only writable folder with /work.

Endpoints​

EndpointSchemeComponentPortPathTLS parameterBinding parametersBinding secretsProvisioning command
mcphttpmcp-host8790 (port)-tls_enabled---

Commands​

CommandComponentTargetDescription
Status (status)mcp-hostevery hostAsks every instance whether it answers on /healthz.
Recent logs (logs)mcp-hostchosen hostLast lines of the runtime journal.

Health checks​

Liveness (per instance)​

ComponentCheckDetails
mcp-hostHTTP {{ 'https' if config.tls_enabled else 'http' }}://{{ host.ip or '127.0.0.1' }}:{{ config.port }}/healthzExpected 200; 30 retries; interval 2 s; timeout 5 s

Readiness (service check)​

CheckDetails
HTTP {{ 'https' if config.tls_enabled else 'http' }}://{{ host.ip or '127.0.0.1' }}:{{ config.port }}/healthzExpected 200; 10 retries; interval 2 s; timeout 5 s

Preflight checks​

CheckTypeMeaningSeverityComponents
memorymemory_mb {"min": 1024}at least 1024 MB of memoryblockingevery component
mcp_port_freeport_free {"param": "port"}port 8790 free on the hostblockingevery component
npx_presentbinary {"name": "npx"}the program npx installed on the host, only when isolation is processwarningevery component
uvx_presentbinary {"name": "uvx"}the program uvx installed on the host, only when isolation is processwarningevery component
podman_presentbinary {"name": "podman"}the program podman installed on the host, only when isolation is containerblockingevery component
subordinate_idssubordinate_ids {"user": "navin-mcp-host"}subordinate uid and gid ranges of the user navin-mcp-host in /etc/subuid and /etc/subgid (created by user.ensure on a root agent with usermod), only when isolation is containerblockingevery component

Uninstall​

Paths removed when the data is purged: {{ paths.data }}, {{ paths.log }}.

  • Metrics: {{ 'https' if config.tls_enabled else 'http' }}://{{ host.fqdn }}:{{ config.port }}/metrics

Upstream documentation​