MCP Explained: The Protocol That Lets Your Local AI Actually Do Things
If you’ve been running local AI models in your homelab — whether that’s Ollama, llama.cpp, vLLM, or something else — you’ve probably hit the same wall everyone hits. Your model is smart. It can reason, summarize, generate, and chat. But it can’t do anything. It can’t read a file on your NAS. It can’t query your Home Assistant instance. It can’t search your notes in Obsidian or look up a movie in your Plex library.
You can paste text into a chat window all day, but at some point you want the model to reach out and touch your actual systems.
That’s where MCP comes in.
What Is MCP?
MCP stands for Model Context Protocol. It’s an open standard — originally introduced by Anthropic in late 2024 — that defines a consistent way for AI models to interact with external tools, data sources, and services.
Think of it like a universal plug. Instead of every AI application building custom integrations for every possible tool, MCP defines a shared language. A tool exposes its capabilities through an MCP server. An AI client connects to that server and discovers what it can do. The model can then call those tools as needed during a conversation.
The key insight is that MCP standardizes the interface, not the integrations. Write your MCP server once, and any MCP-compatible client can use it.
Why MCP Matters for Self-Hosters
If you’re running cloud-based AI services, you might not care much about MCP. The big providers already have their own ecosystems of plugins, function calling, and integrations. But for self-hosters, MCP is a bigger deal.
Here’s why:
- It’s vendor-neutral. MCP isn’t tied to a single model provider. Any client that implements the protocol can talk to any server that implements it.
- It runs locally. You can run an MCP server on the same machine as your local model, giving it access to your files, databases, and services without sending data to the cloud.
- It’s composable. You can connect multiple MCP servers at once — one for your filesystem, one for a database, one for a web search tool — and the model picks the right tool for the job.
- It’s open. The spec is public, the SDKs are open source, and there’s already a growing ecosystem of community-built servers.
For homelabbers, this means your local LLM can stop being a glorified autocomplete and start being something closer to an actual agent that interacts with your infrastructure.
How MCP Works: The Core Concepts
MCP follows a client-server architecture. Let’s break down the pieces.
The MCP Server
An MCP server is a program that exposes resources, prompts, and tools to AI clients. It speaks the MCP protocol over a transport layer — typically either stdio (standard input/output, for local servers) or SSE/HTTP (Server-Sent Events over HTTP, for remote servers).
A server might expose:
- Resources: Data the model can read. Think files, database rows, API responses. Resources are identified by URIs (e.g.,
file:///mnt/nas/documents/budget.md). - Tools: Functions the model can call. These have defined input schemas (using JSON Schema) so the model knows what arguments to provide. A tool might be “search my notes” or “create a calendar event.”
- Prompts: Pre-defined prompt templates the client can offer to users. These are less common in practice but useful for structured workflows.
The MCP Client
The client is the AI application — your chat interface, your agent framework, whatever. It connects to one or more MCP servers, discovers what they offer, and makes those capabilities available to the model.
When the model decides it needs to use a tool, the client handles the actual call: it sends the request to the appropriate MCP server, gets the response, and feeds it back into the conversation context.
The Transport Layer
MCP currently supports two main transports:
- stdio: The server runs as a subprocess of the client. Communication happens over stdin/stdout. This is the simplest setup and ideal for local, single-machine deployments.
- Streamable HTTP (formerly SSE): The server runs as an HTTP service. The client connects over the network. This is better for shared servers or containerized deployments.
For most homelab setups, stdio is the easiest place to start. You configure your client to launch the server as a subprocess, and everything just runs locally.
A Practical Example: Giving Your Local Model Filesystem Access
Let’s walk through a real setup. We’ll use Ollama as our local model backend and a filesystem MCP server to let the model read and write files on our machine.
Prerequisites
You’ll need:
- Ollama installed and running (with at least one model pulled, like
llama3.1orqwen2.5) - Node.js or Python installed (we’ll use the Python SDK for this example)
- A basic MCP-compatible client (we’ll use
mcp-clifor simplicity, but many clients now support MCP — including Open WebUI, AnythingLLM, and others)
Step 1: Install the Filesystem MCP Server
Anthropic maintains a reference filesystem server. You can install it via pip:
| |
Or if you prefer using uvx (which runs it without a permanent install):
| |
This server exposes tools for reading files, writing files, listing directories, and searching within files.
Step 2: Configure Your Client
Let’s say you’re using a client that reads an MCP configuration file. The format looks something like this (saved as mcp_config.json):
| |
The ALLOWED_DIRECTORIES environment variable is important — it restricts which paths the server can access. You don’t want your AI model poking around in /etc or your .ssh folder.
Step 3: Start Chatting
Launch your MCP-compatible client with the config file. Once connected, the client discovers the filesystem server’s tools. Now you can ask your model things like:
“Read the file budget.md in my documents folder and summarize my spending categories.”
The model will:
- Recognize it needs to read a file
- Call the
read_filetool with the appropriate path - Receive the file contents back from the MCP server
- Summarize the content for you
You can also ask it to write:
“Create a new file called todo.md in my notes folder with a list of homelab projects I should work on this weekend.”
The model calls the write_file tool, and the file appears on disk.
Step 4: Add More Servers
The real power comes from combining servers. Let’s add a SQLite MCP server so the model can query a database:
| |
Now your model can read files and query your database. You could ask:
“Look at my server inventory database and write a summary of which machines need updates to a file called update_report.md.”
The model queries the database through the SQLite MCP server, processes the results, and writes the report through the filesystem MCP server. Two different servers, one seamless interaction.
Building Your Own MCP Server
One of the best things about MCP is how easy it is to build a custom server for your own infrastructure. If you have a service that exposes an API — Home Assistant, Proxmox, your custom dashboard, whatever — you can wrap it in an MCP server in an afternoon.
Here’s a minimal example using the Python SDK:
| |
Save this as homelab_server.py, add it to your client config, and your model now knows about your homelab. You could extend this to call the Proxmox API, check Docker container statuses, query your UPS, or anything else you can script in Python.
The Python SDK handles all the protocol details — the JSON-RPC messaging, the tool discovery, the schema validation. You just define your tools and their handlers.
Security Considerations
Before you go wild connecting your AI to everything in your homelab, let’s talk about security.
MCP servers can execute actions on your behalf. A filesystem server can write files. A database server can run queries (and potentially writes). A Home Assistant server can toggle your lights or unlock your door. Treat MCP servers like any other privileged integration.
Here are some ground rules:
- Scope permissions tightly. Only expose the directories, tables, or API endpoints the model actually needs. The filesystem server’s
ALLOWED_DIRECTORIESis a good example — use it. - Prefer read-only access where possible. If you just want your model to analyze data, don’t give it write tools. Build a server that only exposes read operations.
- Run servers as unprivileged users. Don’t run your MCP server as root. Create a dedicated user with limited permissions.
- Audit tool calls. Some clients log tool calls. Check those logs periodically to see what your model is actually doing.
- Be careful with remote MCP servers. If you expose an MCP server over HTTP, put it behind authentication and ideally on a private network or VPN.
MCP is powerful, but that power cuts both ways. A model that can call arbitrary tools is a model that can make mistakes at scale.
Current State of the Ecosystem
MCP is still young, but the ecosystem is growing fast. As of this writing:
- Anthropic’s Claude Desktop was the first major client to support MCP, and they maintain a set of reference servers (filesystem, SQLite, GitHub, Google Drive, Slack, and others).
- Open WebUI has added MCP support, making it a great option for self-hosters who want a web-based chat interface with tool access.
- Community servers exist for everything from Proxmox to Notion to Kubernetes. The MCP server registry is a good starting point.
- SDKs are available in Python, TypeScript, and other languages.
The spec is still evolving. The transport layer has already seen one major change (the shift from SSE to Streamable HTTP), so expect some churn. But the core concepts — resources, tools, prompts, the client-server model — are stable.
MCP vs. Function Calling: What’s the Difference?
If you’ve been doing AI work for a while, you might be wondering how MCP differs from function calling, which models have supported for a while now.
Function calling is a model capability — the model can output structured data that represents a function call. MCP is a protocol for discovering and executing those functions. They’re complementary, not competing.
In practice, here’s how they fit together:
- The MCP client discovers available tools from connected servers
- The client presents those tools to the model using the model’s function calling format
- The model decides to call a function (using its function calling capability)
- The client routes that call to the appropriate MCP server (using the MCP protocol)
- The server executes the tool and returns the result
- The client feeds the result back to the model
MCP standardizes steps 1, 4, and 5. Function calling handles step 3. They work together.
Summary
MCP is a protocol that lets AI models interact with external tools and data sources in a standardized way. For self-hosters running local AI, it’s the missing piece that turns a chatbot into something that can actually work with your infrastructure.
The core ideas are simple:
- Servers expose tools, resources, and prompts
- Clients connect to servers and make their capabilities available to models
- The model calls tools as needed, and the client handles the actual execution
Getting started is straightforward — install a reference server, configure your client, and start experimenting. Building your own server for your homelab services is a weekend project at most.
Just be mindful of security. Give your model the keys it needs, not the keys to the kingdom.
What’s Next?
If you want to dive deeper:
- Check the official spec at modelcontextprotocol.io
- Browse the server registry to see what community servers already exist
- Try the filesystem server with your local model setup this weekend
- Build a custom server for one of your homelab services and share it with the community
Have you set up MCP in your homelab yet? What servers are you running? Drop a comment below or join the conversation in our Discord — we’d love to hear what you’re building. And if you found this article helpful, subscribe to the YouTube channel for more self-hosting and local AI content.