All posts
August 5, 2026·5 min read

MCP in llama.cpp: Tools for a Local GGUF Model

How to connect MCP servers in llama-server through --mcp-servers-config, why --jinja is required, why the CORS proxy is risky to enable, and what stays on your computer in this setup.

A local model, on its own, can do one thing: answer text with text. To make it read files, query a database, or hit an external service, it needs tools — and a shared way to describe them. That's what Model Context Protocol does.

llama.cpp has MCP support, but with an asterisk: the documentation marks it experimental, and part of the mechanics live not in the server itself but in the built-in web interface. That affects both the setup and how much you should trust this combination with real work data.

What's happening here

MCP describes a contract between a host and a tool server. The host runs the servers, reads their list of tools, and shows the model what it's allowed to call. The model doesn't "connect" anything itself — it only asks, and the host executes. The protocol is explained in detail in what MCP is.

Paired with llama.cpp, the roles split up like this: llama-server computes the model and serves the interface, the built-in web client acts as the MCP host, and the tool servers are separate programs, local or remote.

How to connect one

Two launch flags, both marked experimental:

  • --mcp-servers-config PATH — path to a JSON file describing the servers;
  • --mcp-servers-json JSON — the same thing, as a string right in the command.

The description format is compatible with Cursor's notation. That's convenient: ready-made config snippets from server documentation usually carry over without changes, same as in LM Studio.

The launch command looks like this:

llama-server.exe -m C:\models\qwen3-8b-q4_k_m.gguf --jinja --mcp-servers-config C:\llama\mcp.json

--jinja is required here. Without it, OpenAI-style function calling doesn't turn on, and without function calling, the model can't reach a tool even if the server is connected and visible.

If tools don't show up in the interface, check --jinja first, then the model's own chat template. Some GGUF files are built without a template for tool calls — in that case tools won't work with any flags, and the only fix is a different build of the model.

About the CORS proxy, and why it's off

There's a pair of related flags: --webui-mcp-proxy and --no-webui-mcp-proxy. The second is the default.

The proxy exists because the MCP client runs in the browser, and a browser doesn't let a page reach arbitrary addresses. The proxy works around that by routing requests through the server itself. The documentation comes with a direct warning: don't enable this in an untrusted environment.

The logic behind that warning is simple. The proxy turns llama-server into a middleman that reaches addresses on behalf of whoever asked it to. On a home network at 127.0.0.1, that's acceptable. On a machine reachable from outside, it isn't.

A related protection works the same way: when an MCP server config is set, --cors-origins defaults to a local address only. That's worth leaving as is too.

How local does this setup actually stay

Worth being honest here, because MCP often gets sold as "the private alternative to the cloud."

What stays local is the model's computation: the request text and the answer don't leave, the .gguf file lives on your machine. The tools, though, live their own life. A filesystem server reads your disk and goes nowhere. A GitHub server talks to GitHub. A web-search server sends a request to a search engine. A local MCP client doesn't make a cloud service local — it just gives the model a way to reach it.

You get fully offline if you stick to servers that never touch the network: filesystem, a local database, local scripts. An example of that pattern is in the article on MCP and a database.

A separate problem: the model might not be up to it

Tool descriptions land in the context on every request. One server with thirty tools and detailed schemas can eat several thousand tokens before your very first message.

For a cloud model with a large window, that's invisible. A local model with 8,000 tokens of context hits the wall right away and starts behaving oddly: mixing up arguments, calling the wrong tool, losing the plot after the second step.

What helps:

  • connect servers one at a time, not all together;
  • raise the context with the -c flag, if you have the memory for it;
  • take a bigger model — for agentic scenarios, this solves more than any setting.

Server security is its own topic: an MCP server is a regular program running with your permissions, so don't install them from random repositories and don't give a filesystem server root access to a drive. More on this in the article on connecting an MCP server.

Where this setup hits a ceiling

The assembled combination looks convincing: local model, local tools, nothing leaving. But it has a ceiling, and it's not in the settings.

llama-server is still an inference server with a browser chat. The model can call a tool — and that's where its independence ends. It doesn't carry a task through several steps, doesn't check its own result, doesn't return to the plan if a step fails, and doesn't run on a schedule. On top of that, MCP support here is still marked experimental, meaning the flags and behavior can change between builds.

Doka is built as an agent, not a chat with tools bolted on: it carries a task through to a result, works with files and the terminal, handles your own skills, and connects MCP servers as part of a ready-made process rather than an experimental flag. The local model downloads from the interface — no need to assemble an engine or pick a build for your GPU.

As a place to get hands-on with MCP, llama.cpp is genuinely good: every layer is visible, nothing's hidden behind buttons. The trouble starts when the experimenting gets old and you just want the tools to be there every day. At that point it's simpler to take Doka and not track which flags changed in the latest build.