26 min read

Self-Host mcp-nixos and Connect It with Localtonet

Install and verify the mcp-nixos HTTP server, configure its local MCP endpoint, and provide remote access through a Localtonet HTTP tunnel.

Remote MCP client reaching a locally hosted mcp-nixos server through a Localtonet HTTP tunnel.
Localtonet carries public HTTP requests to the mcp-nixos service running on the local machine.
AI and MCP Β· mcp-nixos Β· Localtonet Β· 2026

Run a Nix knowledge MCP endpoint locally, verify it, and then make it reachable through a controlled HTTP tunnel

mcp-nixos is a self-hostable Model Context Protocol server that gives compatible AI clients access to current NixOS packages, system options, Home Manager, nix-darwin, flakes, Nix documentation, and related data. This guide starts with the application itself: choosing an installation method, launching its documented HTTP transport, checking the local endpoint, and handling common configuration changes. After the local server works, we connect it through a Localtonet HTTP tunnel without configuring inbound router port forwarding or requiring a public IP address. Because the available project evidence does not document application-level authentication or authorization, we also explain the security decisions that must be made before treating the endpoint as a long-running public service.

πŸ”’ Bind locally first and review access controls before exposure 🌐 Documented MCP endpoint at 127.0.0.1:8000/mcp ⚑ Install with pip or run through uvx, Nix, or Docker

What mcp-nixos provides

mcp-nixos is an MCP server focused on Nix-related information. Instead of asking an AI model to rely only on facts embedded in its training data, a compatible MCP client can call the server's tools to search or inspect current package, option, documentation, version, and cache information. The server is an API client for these information sources, so the normal query features do not require the host computer itself to run NixOS.

The project documents support for Windows, macOS, and Linux. It can expose its MCP interface through standard input and output, commonly called STDIO, or through HTTP. STDIO is useful when an AI application launches the MCP process directly on the same computer. HTTP is the relevant transport when the process should run independently, be reached by another local process, or later be made available from outside the host network.

πŸ“¦ NixOS package and option queries The unified nix tool can search packages, retrieve package or option details, inspect statistics, list channels, and perform other supported queries.
🏠 Related configuration ecosystems Documented sources include Home Manager, nix-darwin, Nixvim, NVF, FlakeHub, community flakes, and Noogle function information.
πŸ“š Documentation discovery Queries can surface material from the NixOS Wiki and nix.dev so an MCP client can retrieve relevant guidance through the same server.
⏱️ Package history The separate nix_versions tool provides package version history and associated nixpkgs commit hashes through NixHub data.
☁️ Binary cache checks The server can check binary cache status for packages, including information obtained from the NixOS binary cache service.
πŸ”Œ STDIO and HTTP transports STDIO is the default transport. Setting the documented environment variables changes the server into an independently running HTTP MCP endpoint.

The project consolidates its functionality into two MCP tools. This matters operationally because a successful connection does not necessarily present a long list of separate tool names. A client should discover the unified nix query tool and the nix_versions history tool.

Some capabilities have host-specific requirements. In particular, exploring local flake inputs reads pinned dependencies from the local Nix store and therefore requires Nix on the server host. That exception should not be confused with the server's normal remote-data queries, which can run without NixOS.

HTTP mode is not the default

Running mcp-nixos without setting its transport to HTTP starts the documented default STDIO mode. That process may appear to wait quietly because it expects an MCP client to communicate through standard input and output. Set MCP_NIXOS_TRANSPORT=http when the goal is to create a network endpoint.

Prerequisites and architecture

Architecture showing an MCP client, Localtonet infrastructure, and the local mcp-nixos HTTP server.
The Localtonet agent relays public HTTP traffic to mcp-nixos over the host’s loopback interface.

Decide where the mcp-nixos process and the Localtonet client will run before installing anything. The simplest arrangement is to run both on the same computer. In that design, mcp-nixos listens only on 127.0.0.1:8000, and our client connects to that loopback address locally. Keeping the application bound to loopback avoids exposing port 8000 directly to other devices on the LAN.

You need one supported way to execute the project. For the pip workflow, install Python and pip. For the recommended one-shot project workflow, install uv so its uvx command is available. Alternatively, use Nix or Docker. The official project material establishes these installation paths but does not state a minimum Python, uv, Nix, or Docker version in the evidence available for this guide. We therefore do not invent version requirements. If an installation tool reports an interpreter or engine compatibility error, use the requirement shown by the current package metadata or container release.

For the remote-access stage, install and run the Localtonet client on the device that can reach the local service. You also need a device-specific Localtonet authentication token and access to our dashboard. Treat the token as a secret. Do not paste it into application configuration, screenshots, shell history shared with others, or an MCP client profile.

Component Purpose Required for this workflow
mcp-nixos Provides the MCP tools and HTTP endpoint Yes
Python and pip, uvx, Nix, or Docker Installs or executes mcp-nixos Choose one supported path
Local MCP client Performs a protocol-level test and invokes tools Strongly recommended for complete verification
Localtonet client Establishes the outbound connection to our relay Required only for remote access
Nix installation Enables access to local flake inputs in the Nix store Not required for normal remote information queries

Plan the address boundaries

The documented HTTP configuration used in this guide has three related values:

  • 127.0.0.1 is the listening address and restricts direct connections to the host itself.
  • 8000 is the documented example port.
  • /mcp is the default HTTP MCP path.

Together, they produce http://127.0.0.1:8000/mcp. The Localtonet HTTP tunnel points to the local IP address and port, while the MCP client uses the MCP path on the assigned public HTTPS address.

Loopback only works from the same network namespace

If mcp-nixos is inside a container but the Localtonet client runs directly on the host, or if our client runs on another computer, 127.0.0.1 may refer to the wrong environment. Do not change the bind address blindly. First decide how those processes will communicate, then expose only the interface required by that architecture and protect it with appropriate host and network controls.

Install or run mcp-nixos

The project supports several execution methods. The pip route is convenient for a persistent Python environment, while uvx is useful when you want the tool runner to obtain and execute the package without maintaining a project-specific installation manually. Nix and Docker are also documented options.

Method Documented command Best fit
pip pip install mcp-nixos A persistent Python installation or virtual environment
uvx uvx mcp-nixos Running the package through the uv tool runner
Nix nix run github:utensils/mcp-nixos -- Hosts that already use Nix
Docker docker run --rm -i ghcr.io/utensils/mcp-nixos STDIO execution in a disposable container

The documented Docker command is an interactive STDIO example. The available evidence does not establish the complete port publishing and environment-variable command for running this image as an HTTP container. Rather than guessing its container networking behavior, this guide uses the direct pip or uvx path for HTTP mode.

Option A: install with pip in a virtual environment

A virtual environment keeps the package isolated from the operating system's global Python packages. On Linux or macOS, create and activate one with:

python -m venv .venv
source .venv/bin/activate
python -m pip install mcp-nixos

On Windows PowerShell, a common Python launcher and activation sequence is:

py -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install mcp-nixos

The available Python launcher can differ by installation. If py is unavailable but python works, use python -m venv .venv. If PowerShell blocks the activation script under the machine's execution policy, do not weaken organizational policy without approval. You can invoke the virtual environment's Python and installed executable directly or use an approved shell.

Keep the environment activated whenever you run the plain mcp-nixos command. If the shell says the command does not exist immediately after installation, confirm that installation completed in the same environment and that the virtual environment is active.

Option B: run through uvx

If uvx is already installed, the basic documented command is:

uvx mcp-nixos

By itself, that starts the default STDIO transport. In the next section we set the HTTP environment variables before invoking the same command. The benefit of this method is that the execution environment is handled by the uv tool runner rather than by a manually activated project virtual environment.

Option C: run through Nix

On a machine with Nix available, the project documents:

nix run github:utensils/mcp-nixos --

This is also a default STDIO invocation unless the HTTP environment variables are present in the process environment. Nix is not required merely because the service provides information about NixOS. It becomes relevant when you choose this installation path or need the local flake-input capability.

Configure the mcp-nixos HTTP server

mcp-nixos reads environment variables that select the transport, host, port, path, and optional stateless behavior. For the baseline deployment, explicitly configure all values needed to reproduce the documented local endpoint.

1

Select the HTTP transport

Set MCP_NIXOS_TRANSPORT to http. Without this value, the documented default is STDIO and there will be no HTTP listener for Localtonet to reach.

2

Bind the service to loopback

Set MCP_NIXOS_HOST to 127.0.0.1. This is appropriate when mcp-nixos and the Localtonet client run on the same host.

3

Choose the documented local port

Set MCP_NIXOS_PORT to 8000. If another process already uses that port, select an unused port and use the identical value in the Localtonet local target.

4

Start the mcp-nixos process

Run mcp-nixos from the activated pip environment, or run uvx mcp-nixos. Keep this process running while performing local and remote tests.

On Linux or macOS with the pip installation active:

export MCP_NIXOS_TRANSPORT=http
export MCP_NIXOS_HOST=127.0.0.1
export MCP_NIXOS_PORT=8000
mcp-nixos

To execute through uvx instead, keep the same exported variables and replace the final command:

uvx mcp-nixos

On Windows PowerShell:

$env:MCP_NIXOS_TRANSPORT = "http"
$env:MCP_NIXOS_HOST = "127.0.0.1"
$env:MCP_NIXOS_PORT = "8000"
mcp-nixos

These settings create the documented MCP endpoint:

http://127.0.0.1:8000/mcp

Use a custom MCP path

The default HTTP path is /mcp. The project documents MCP_NIXOS_PATH for changing it. For example:

export MCP_NIXOS_TRANSPORT=http
export MCP_NIXOS_HOST=127.0.0.1
export MCP_NIXOS_PORT=8000
export MCP_NIXOS_PATH=/api/mcp
mcp-nixos

The resulting local endpoint is http://127.0.0.1:8000/api/mcp. Remember that the Localtonet tunnel targets the host and port, but remote MCP clients must use the selected path. Changing the path is useful for routing and organization, but it should not be treated as authentication. A path can be discovered or shared and is not a substitute for access control.

Enable stateless HTTP mode

The project also documents a stateless HTTP mode that disables per-client session state:

export MCP_NIXOS_TRANSPORT=http
export MCP_NIXOS_HOST=127.0.0.1
export MCP_NIXOS_PORT=8000
export MCP_NIXOS_STATELESS_HTTP=1
mcp-nixos

Use this only when your client and deployment design expect stateless operation. The setting changes session behavior, not network reachability or authorization. Test your actual MCP client after enabling it rather than assuming all clients handle the mode identically.

Environment variables belong to the server process

Set the variables in the shell, service definition, or process manager that launches mcp-nixos. A value set in one terminal is not automatically inherited by a process launched from an unrelated terminal, desktop application, container, or operating system service.

Verify the local endpoint before tunneling

Local terminal check confirming that the mcp-nixos HTTP endpoint responds on loopback.
The local endpoint should respond successfully before the tunnel is enabled.

Do not create the public tunnel until local verification succeeds. Separating application problems from tunnel problems makes diagnosis much faster.

Confirm that the process remains running

After startup, the command should remain active as a server process rather than immediately returning to the shell. If it exits, read the emitted error before continuing. Common categories include a missing executable, an unsupported Python environment, a port conflict, or an invalid environment value.

Check basic HTTP reachability

From the same host, request the endpoint headers and response:

curl -i http://127.0.0.1:8000/mcp

MCP over HTTP is a protocol, not an ordinary informational web page. A generic GET request may therefore return a protocol-related status rather than useful MCP data. The important distinction at this stage is between receiving an HTTP response from the application and receiving a connection error such as connection refused or timeout. Do not interpret a browser page, or the absence of one, as complete MCP verification.

Perform protocol-level verification

Configure an MCP client that supports remote HTTP servers with the local URL http://127.0.0.1:8000/mcp. Client configuration formats differ, and the supplied project evidence does not establish one universal JSON schema for remote URLs. Some clients distinguish between STDIO and remote HTTP entries, while others expose an MCP server URL field in their interface. Use the client's HTTP MCP configuration rather than putting the URL into a field intended for an executable command.

A complete test should establish that the client can initialize an MCP session, discover the server's tools, and invoke a harmless query. The project exposes the unified nix tool and nix_versions. For example, use the client's interface to search for a known package such as Firefox. Exact tool-call entry screens and argument serialization are client-specific, so this guide does not invent a configuration format that may be wrong for your client.

Do not skip local verification

A Localtonet tunnel can be connected while its local target is unavailable. Creating a tunnel does not repair a stopped service, wrong port, incorrect path, or STDIO-mode process. Confirm the MCP server independently first.

Connect the working server through Localtonet

Four-stage flow from the local mcp-nixos server to a remote client through Localtonet.
After local verification, the Localtonet session exposes the same HTTP service through a public endpoint.

Once http://127.0.0.1:8000/mcp works locally, an HTTP tunnel can expose the service without inbound router port forwarding, firewall changes, VPN setup, or a public IP address. Our client establishes an outbound connection to a Localtonet relay server. The tunnel is available only while the selected client device is connected and the tunnel itself is running.

The current dashboard determines which relay servers, process types, domain choices, and plan-dependent options are available to your account. Obtain those values from the dashboard rather than copying a server code or region from an article.

1

Install and run the Localtonet client

Install our client for the operating system on the device that can reach mcp-nixos. For the loopback configuration in this guide, run the client on the same host as the MCP process.

2

Authenticate or select the client device

Use the device-specific authentication token associated with the client that will run the tunnel. Keep this token private and confirm that the intended device is connected.

3

Select an available relay server

Choose a currently available Localtonet relay server or region from the dashboard. Availability can vary, so this guide does not hardcode a server code.

4

Create the HTTP tunnel configuration

Create an HTTP tunnel and set its local target to IP address 127.0.0.1 and port 8000. Select an available HTTP Process Type appropriate to your deployment. Random Sub Domain, Custom Sub Domain, and Custom Domain all serve content at a public HTTPS address, but available choices can vary.

5

Start the tunnel

Use the Start button after saving the configuration. Creating the tunnel does not mean it is running. Confirm that both the selected client device and the tunnel show a connected state.

6

Use the assigned public endpoint

Take the assigned public HTTPS address and append the MCP path. With the default path, the client endpoint is the assigned address followed by /mcp. Stop or delete the tunnel when remote access is no longer required.

For example, if the dashboard assigns an address represented here as https://your-assigned-address, configure the remote MCP client with:

https://your-assigned-address/mcp

That hostname is deliberately a placeholder, not a real endpoint. Always copy the actual address from your tunnel. If you configured MCP_NIXOS_PATH=/api/mcp, use the public address followed by /api/mcp instead.

The local service remains HTTP on loopback, while an HTTP tunnel serves the content at a public HTTPS address. TLS termination at the tunnel edge protects the public HTTPS connection, but it does not create application-level user authentication inside mcp-nixos.

Our HTTP tunnel documentation is the appropriate place to confirm the current dashboard workflow and available options. Exact custom-domain DNS instructions are intentionally omitted because they must be checked against current documentation before use.

Verify the public route

Repeat the same two-stage verification used locally. First, make a basic request to distinguish a reachable HTTP service from a DNS, connection, or upstream error:

curl -i https://your-assigned-address/mcp

Then configure a remote-capable MCP client with the HTTPS URL and confirm initialization, tool discovery, and a test query. A response to curl alone proves only basic HTTP reachability. It does not prove that the complete MCP exchange succeeds.

Routine operation and configuration changes

Starting the complete service

Start mcp-nixos first and verify its local endpoint. Next, start the Localtonet client and then start the configured HTTP tunnel. This order makes failures easier to interpret because the local target is ready before traffic arrives.

For unattended operation, use a process manager appropriate to your operating system to launch mcp-nixos with the required environment variables. The project evidence supplied for this article does not prescribe a systemd unit, launchd property list, Windows service wrapper, or restart policy, so we do not provide an invented service definition. Whichever manager you choose should preserve the environment, run under a least-privileged account, record logs, and restart only according to your operational policy.

Stopping access safely

Stop the Localtonet tunnel when remote access is no longer needed. You can later start it again, or delete it if the configuration is no longer required. Remember that stopping mcp-nixos while leaving the tunnel running produces an unavailable upstream target, while stopping only the tunnel leaves the local endpoint available on loopback.

Changing the local port

If port 8000 conflicts with another process, select an unused port for MCP_NIXOS_PORT, restart the mcp-nixos process with that value, test the new local URL, and update the Localtonet tunnel's local target to the same port. A mismatch between the application port and tunnel target is a common cause of gateway or connection errors.

Changing the MCP path

Set MCP_NIXOS_PATH, relaunch the server with the intended environment, and update every local and remote MCP client URL. The Localtonet target remains the local IP and port. The path is part of each request URL rather than a separate raw-port target.

Updating mcp-nixos

An installation managed by pip, uvx, Nix, or Docker follows that tool's own update model. Before updating a long-running deployment, review the project release information, preserve the current working configuration, and retest locally before restoring remote access. The evidence supplied for this draft identifies version 3.0.2 as a release, but a newer release may exist when the article is reviewed or published.

Avoid presenting an untested update directly to remote clients. Stop the tunnel, update the package or execution source, start the local server, verify MCP initialization and tools, and then start the tunnel again.

Troubleshooting the complete workflow

The process starts but there is no HTTP listener

The most likely distinction is transport mode. Confirm that MCP_NIXOS_TRANSPORT=http exists in the environment inherited by the running process. If the process was launched from another terminal, service manager, IDE, or desktop application, variables set in your current terminal do not affect it.

The shell cannot find mcp-nixos

If you used pip, verify that installation completed successfully and that the intended virtual environment is active. Prefer python -m pip install mcp-nixos so pip is associated with the selected Python interpreter. If you intended to use uvx, run uvx mcp-nixos rather than expecting a persistent executable from a separate pip environment.

Port 8000 is already in use

Stop the conflicting application if appropriate, or select another unused local port. Set the new value in MCP_NIXOS_PORT, relaunch mcp-nixos, verify the changed local endpoint, and update the Localtonet local target. Do not expose an unrelated process merely because it already occupies port 8000.

Local curl fails with connection refused

Connection refused normally means no process is listening at the requested address and port. Check whether mcp-nixos exited, whether it is still in STDIO mode, and whether the configured host and port match the URL. Resolve this before inspecting the tunnel.

Local access works but the public address fails

Confirm that the Localtonet client is connected, that the correct device token was selected, and that the tunnel was explicitly started. Then compare the tunnel's local IP and port with the tested local endpoint. Creating a tunnel configuration without pressing Start does not make it active.

The public root URL responds but the MCP client fails

Verify the path. The documented default is /mcp, so using only the public root address can target the wrong route. If you set MCP_NIXOS_PATH=/api/mcp, every client must use that custom path. Also ensure the MCP application supports remote HTTP transport and that you selected its URL-based server configuration rather than an STDIO command configuration.

A browser shows an error or no useful page

An MCP endpoint is not designed as a conventional website. Browser behavior is not an authoritative protocol test. Use an MCP client that supports the server's HTTP transport and confirm initialization plus tool discovery.

The client connects but cannot use local flake inputs

Local flake-input exploration requires Nix and access to the relevant local Nix store. The fact that ordinary mcp-nixos queries run on Windows, macOS, and Linux without Nix does not remove this specific local-data requirement.

The endpoint works for one client but not another

Compare transport support, URL configuration, path, and session expectations. If stateless HTTP mode is enabled, temporarily test the documented normal HTTP mode to isolate whether session behavior is involved. Client-specific MCP configuration formats are outside the project details established by the supplied evidence, so use the failing client's current remote HTTP instructions rather than copying a command-based STDIO profile.

Security considerations before public exposure

The mcp-nixos material supplied for this guide documents HTTP transport, a custom path, and stateless mode. It does not establish built-in application-level authentication, authorization, or application-managed TLS. We therefore cannot claim that a directly exposed endpoint requires credentials or restricts callers by identity.

A Localtonet HTTP tunnel provides a public HTTPS address while the tunnel is running, and TLS is terminated at the tunnel edge. That protects the public connection in transit, but transport encryption and caller authorization solve different problems. HTTPS does not decide who may invoke MCP tools.

Treat the assigned address as reachable by untrusted callers

Do not rely on an obscure hostname or custom MCP path as the only protection. Before a persistent deployment, place an authentication-capable gateway in front of mcp-nixos or apply verified access controls available in your deployment. If you cannot establish suitable authorization, limit the tunnel to a short test window and stop it immediately afterward.

πŸ” Protect identities and tokens Keep the Localtonet device token, gateway credentials, and private endpoint details out of repositories, examples, logs shared publicly, and MCP prompts.
🧱 Use a narrow local bind Keep 127.0.0.1 when our client and mcp-nixos share a host. Broader binds should be deliberate and protected by host and network policy.
πŸ‘€ Add real authorization If remote access must persist, use an authentication-capable layer that is compatible with the MCP client instead of treating the URL path as a password.
⏹️ Minimize exposure time Start the tunnel only when needed and stop or delete it afterward. Tunnel availability depends on both the connected device and the running tunnel.
πŸ§ͺ Test changes locally Validate upgrades, path changes, ports, and stateless mode on loopback before restoring the public route.
πŸ“‹ Follow least privilege Run the service under an account with only the local permissions it needs, especially if enabling access to local Nix store data.

If you add a reverse proxy or authentication gateway, bind mcp-nixos behind it and configure the Localtonet tunnel to target the gateway's local address and port rather than bypassing that layer. Exact gateway configuration depends on the chosen software, MCP client's authentication support, and organizational policy, none of which are established by the mcp-nixos evidence supplied here.

Also consider the data returned by the service. Most documented sources are public package and documentation services, but local flake-input inspection can reveal information about the host's pinned dependencies. Decide whether remote users should be permitted to query local environment details before enabling that capability.

Frequently asked questions

Does mcp-nixos require NixOS?

No. The project documents support for Windows, macOS, and Linux because its normal functionality queries APIs rather than requiring the host to be NixOS. Exploring local flake inputs is an exception because that capability reads from a local Nix store and requires Nix.

What is the default local HTTP endpoint?

With MCP_NIXOS_TRANSPORT=http, MCP_NIXOS_HOST=127.0.0.1, and MCP_NIXOS_PORT=8000, the documented endpoint is http://127.0.0.1:8000/mcp. The default MCP path is /mcp.

Why does mcp-nixos appear to wait without opening a port?

STDIO is the documented default transport. In that mode, the process waits for an MCP client to communicate through standard input and output instead of listening on an HTTP port. Set MCP_NIXOS_TRANSPORT=http in the process environment for HTTP mode.

Can I change the /mcp path?

Yes. Set MCP_NIXOS_PATH, for example to /api/mcp, and use that path in local and remote MCP client URLs. A custom path is routing configuration, not an authentication mechanism.

What does stateless HTTP mode do?

Setting MCP_NIXOS_STATELESS_HTTP=1 disables per-client session state. It does not add authentication, TLS, or network restrictions. Test it with the intended MCP client because session expectations can differ.

Does Localtonet require router port forwarding?

No. Our client establishes an outbound connection to a Localtonet relay server, so this workflow does not require inbound router port forwarding, a public IP address, VPN setup, or inbound firewall changes.

Is the tunnel active as soon as I create it?

No. Creating a tunnel does not start it. Use the Start button and confirm that the selected client device is connected. The endpoint remains available only while the client is connected and the tunnel is running.

Does public HTTPS mean the MCP endpoint is authenticated?

No. HTTPS protects the public connection in transit, but it does not by itself identify or authorize callers. The supplied mcp-nixos evidence does not document built-in application authentication or authorization. Add a compatible authentication layer or limit the tunnel to controlled testing.

Can the Localtonet client run on a different computer?

It can run on a device that can reach the local service, but 127.0.0.1 refers to the client device itself. The simplest and narrowest configuration is to run both processes on the same host. A separate-host design requires a reachable local address and appropriate network protections.

Connect your verified mcp-nixos endpoint with Localtonet

Start mcp-nixos on loopback, complete a local MCP test, and then create an HTTP tunnel to the verified local address and port. Keep remote access temporary unless you have added authorization appropriate for your users and MCP clients.

Get Started Free β†’

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support