# How to Run the QMD MCP Server in HTTP Mode for Shared Access

> Learn how to run the QMD MCP server in HTTP mode. This allows multiple clients to share a single LLM instance, keeping models loaded in VRAM for faster access.

- Repository: [Tobias Lütke/qmd](https://github.com/tobi/qmd)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Run `qmd mcp --http` to start a long-running HTTP server on port 8181 that keeps LLM models loaded in VRAM, allowing multiple clients to share a single QMD instance.**

The QMD repository (`tobi/qmd`) ships with a built-in Model Context Protocol (MCP) server that supports two transport modes. While the default **stdio** transport spawns a short-lived subprocess for each request, running the QMD MCP server in **HTTP mode** creates a persistent local server ideal for shared access across multiple agents, scripts, or web interfaces.

## Why Use HTTP Mode for the QMD MCP Server?

HTTP mode offers three distinct advantages over the stdio transport:

* **Model persistence** – Loading a GGUF model can take approximately one second. The HTTP server keeps the model resident in VRAM across requests, eliminating reload latency for subsequent searches.
* **Multi-process safety** – Multiple agents or scripts can issue JSON-RPC calls concurrently without each spawning a separate QMD process.
* **Standard networking** – You can route the server through a reverse proxy, expose it on different interfaces, or embed it in containerized environments.

## Starting the QMD MCP Server in HTTP Mode

The HTTP server implementation resides in [`src/mcp.ts`](https://github.com/tobi/qmd/blob/main/src/mcp.ts), specifically within the `startMcpHttpServer()` function (lines 53-66). This function registers all QMD tools and resources, then binds to `localhost:8181` by default.

### Foreground Mode

To start the server in the foreground for testing or development:

```bash
qmd mcp --http

```

The process remains attached to your terminal. Press **Ctrl-C** to stop the server and release the VRAM.

### Daemon Mode with PID Management

For production or long-running shared access, run the server as a background daemon:

```bash
qmd mcp --http --daemon

```

When launched with `--daemon`, the process writes its PID to `~/.cache/qmd/mcp.pid` (as implemented in [`src/mcp.ts`](https://github.com/tobi/qmd/blob/main/src/mcp.ts), lines 124-129). This file allows the CLI to target the specific process during shutdown.

### Custom Port Configuration

To bind to a non-default port, use the `--port` flag:

```bash
qmd mcp --http --port 8080

```

This modifies the `HttpServerHandle` configuration before the server begins listening.

## Verifying Your HTTP Server is Running

The HTTP server exposes a health check endpoint at `GET /health` (defined in [`src/mcp.ts`](https://github.com/tobi/qmd/blob/main/src/mcp.ts), lines 104-108). Verify liveness with:

```bash
curl http://localhost:8181/health

```

A running server returns:

```json
{"status":"ok","uptime":42}

```

The `uptime` value indicates how many seconds the server has been active since model loading completed.

## Making Requests to the HTTP MCP Server

The primary endpoint is `POST /mcp`, which accepts standard MCP JSON-RPC payloads. Unlike the stdio transport, HTTP mode maintains the model context between calls.

### Example: Keyword Search via cURL

```bash
curl -X POST http://localhost:8181/mcp \
     -H "Content-Type: application/json" \
     -d '{
       "jsonrpc":"2.0",
       "id":1,
       "method":"tools/call",
       "params":{
         "name":"search",
         "arguments":{"query":"authentication","limit":5}
       }
     }'

```

The response follows the MCP specification with `result.content` containing human-readable text and `result.structuredContent` containing machine-parseable result objects.

### Example: Deep Search via Node.js

```javascript
import fetch from "node-fetch";

async function deepSearch(query) {
  const resp = await fetch("http://localhost:8181/mcp", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "tools/call",
      params: {
        name: "deep_search",
        arguments: { query, limit: 5 }
      }
    })
  });

  const { result } = await resp.json();
  console.log(result.content[0].text);
  console.log(result.structuredContent.results);
}

deepSearch("how to deploy a Node app");

```

## Stopping the Daemon

To gracefully shut down a background daemon:

```bash
qmd mcp stop

```

This command reads the PID from `~/.cache/qmd/mcp.pid` (as written during daemon startup in [`src/mcp.ts`](https://github.com/tobi/qmd/blob/main/src/mcp.ts), lines 124-129), sends a termination signal to the process, and cleans up the PID file.

## Summary

* Run `qmd mcp --http` to start the QMD MCP server in HTTP mode for shared access, binding to `localhost:8181` by default.
* Use `--daemon` to run as a background process with PID management via `~/.cache/qmd/mcp.pid`.
* The server exposes `POST /mcp` for JSON-RPC tool calls and `GET /health` for liveness checks.
* HTTP mode keeps LLM models loaded in VRAM between requests, enabling low-latency shared access across multiple clients.
* Stop background servers gracefully with `qmd mcp stop`.

## Frequently Asked Questions

### What is the default port for the QMD MCP HTTP server?

The default port is **8181**. When you run `qmd mcp --http`, the `startMcpHttpServer()` function in [`src/mcp.ts`](https://github.com/tobi/qmd/blob/main/src/mcp.ts) binds to `localhost:8181` unless you specify a different port with the `--port` flag.

### How does the HTTP mode differ from stdio mode in QMD?

**stdio mode** (the default) spawns a short-lived subprocess for each request, loading the model into VRAM and unloading it immediately after. **HTTP mode** creates a long-running server that persists the model in VRAM across multiple requests, allowing shared access from many clients simultaneously without reload penalties.

### Where is the PID file stored when running as a daemon?

When launched with `--daemon`, the process writes its PID to `~/.cache/qmd/mcp.pid`. This path is hardcoded in [`src/mcp.ts`](https://github.com/tobi/qmd/blob/main/src/mcp.ts) (lines 124-129) and is read by the `qmd mcp stop` command to locate and terminate the background process.

### Can I run the QMD MCP server behind a reverse proxy?

Yes. Because the HTTP transport uses standard HTTP/1.1 with JSON-RPC payloads, you can route the server through nginx, Caddy, or any reverse proxy. Simply point the upstream to `localhost:8181` (or your custom port) and ensure the proxy supports the `POST /mcp` endpoint for tool calls and `GET /health` for health checks.