MCP V1
A local-first desktop application built to understand how AI models can interact with external tools through the Model Context Protocol.
MCP V1 was a technical proof of concept I built to understand the architecture behind AI applications that can use external tools, similar to the tooling model used by applications such as Claude Desktop.
MCP V1 was my first practical exploration of the Model Context Protocol and the foundation for the MCP architecture I used in later projects.
The goal was deliberately narrow.
I was not trying to build an AI assistant or a production-ready automation platform. I wanted to understand what happens between an LLM deciding that it needs a capability and that capability actually being executed.
That meant exploring:
- How tools are exposed
- How tools are discovered
- How tool schemas are provided to an LLM
- How tool requests are routed
- How external operations are executed
- How results are returned to the model
The result was a small desktop application combining Tauri, a Python orchestration layer, Ollama, and independent MCP servers.
The idea
A basic LLM application can be represented as:
User
│
▼
Application
│
▼
LLM
│
▼
ResponseThe interesting part begins when the model can interact with capabilities outside of itself.
Instead of implementing every capability directly inside the application, MCP provides a standardized interface through which external tools can be exposed to the model.
The main idea I wanted to explore was this separation:
LLM
│
│ decides what capability is needed
▼
MCP Client
│
│ structured tool call
▼
MCP Server
│
│ performs the operation
▼
External SystemThe model handles the reasoning.
The MCP server handles the actual operation.
That distinction became the core concept behind the project.
Architecture
The application uses a sidecar-style architecture where the desktop interface, AI orchestration, model, and tools remain separate components.
The Tauri application provides the user interface, while the persistent Python process acts as the AI orchestration layer.
Python communicates with Ollama for local inference and manages communication with the MCP servers through the MCP stdio transport.
This separation also meant that the MCP servers could be developed and tested independently from the desktop application.
Why I built a Python orchestration layer
One of the architectural decisions I wanted to understand was where the AI and MCP logic should live.
Rather than placing model interaction directly inside the React/Tauri application, I used Python as a separate orchestration layer.
The bridge is responsible for:
- Receiving requests from the desktop application
- Communicating with Ollama
- Discovering available MCP tools
- Providing tool information to the model
- Routing model-generated tool requests
- Starting and communicating with MCP server processes
- Returning tool results to the model and application
This created a clean boundary between the UI and the AI/tooling system.
It also made the architecture easier to reason about:
Desktop UI
│
▼
Python Orchestrator
│
├── LLM
│
└── MCP ServersThe UI does not need to understand how an MCP server works, and the MCP servers do not need to know anything about the desktop interface.
MCP servers
The project contains two independent MCP servers.
File Operations
The filesystem server exposes basic file operations:
- List files
- Read files
- Write files
Filesystem access is restricted to a configured target directory rather than allowing unrestricted access to the machine.
The server validates requested paths before performing operations.
This was an important design consideration because the model can decide when to request a filesystem operation, but the tool itself should still enforce the boundaries of what it is allowed to access.
Browser
The browser MCP server provides headless browser functionality for retrieving web content.
This gives the model access to information outside the local model's knowledge without embedding browser-specific logic into the main application.
The browser functionality is exposed as an independent MCP capability rather than being tightly coupled to the filesystem server.
Tool discovery
One of the main things I wanted to understand was how an AI application can work with tools without hardcoding every tool into the model interaction logic.
MCP servers expose their available tools along with structured schemas describing how those tools can be called.
The Python bridge can discover this information and make it available to the model.
Conceptually:
The important part is that the model does not need to understand the implementation of the filesystem or browser.
It only needs a structured description of the capabilities available to it.
The MCP layer then handles the translation from that structured request into an actual tool execution.
Local inference with Ollama
The application uses Ollama as the local LLM backend.
Using a local model allowed me to experiment with the complete tool-calling workflow without making the application dependent on a cloud-hosted model API.
The model handles language-level reasoning, while the MCP servers handle the actual operations.
The separation looks like this:
The LLM does not directly execute filesystem or browser operations.
It produces a structured request which is then handled by the MCP layer.
Example workflow
For example, a user could request:
Create a file named plan.txt in the data folder
and write a summary into it.The resulting interaction can be represented as:
The important distinction is that the LLM decides which capability is relevant, while the MCP server remains responsible for executing the operation.
This separation was the primary behavior I wanted to understand through implementation.
Filesystem safety
Giving an AI model access to the local filesystem introduces an obvious security concern.
The filesystem MCP server therefore uses path-scoped access.
Instead of allowing arbitrary paths such as:
C:\Users\...the server operates inside a configured target directory.
Conceptually:
Configured Directory
│
├── notes.txt
├── projects/
├── data/
└── ...This is an application-level restriction rather than an OS-level sandbox.
That distinction is important.
The project was designed to explore MCP and AI-driven tooling, not to provide production-grade process or filesystem isolation.
What I learned
The biggest lesson from MCP V1 was that tool-enabled AI systems are not primarily about making an LLM "do things".
They are about creating a reliable boundary between reasoning and execution.
The project gave me practical experience with:
- How MCP servers expose tools to AI clients
- How tool schemas are discovered
- How structured tool requests move between an LLM and MCP servers
- How
stdiocan be used as a local MCP transport - How multiple independent MCP servers can be orchestrated
- How to separate model reasoning from tool execution
- How to integrate a local LLM through Ollama
- How a Python process can act as an orchestration layer
- How to build a desktop application around a persistent Python sidecar
- Why tool-level boundaries matter when an AI model can trigger external operations
The project also exposed an important practical reality:
Connecting an LLM to tools is relatively straightforward. Making that system reliable, predictable, and safe is considerably harder.
Local models can struggle with tool selection, argument formatting, and large tool results.
Large files can also consume significant portions of the model's context, making seemingly simple operations less reliable.
Those limitations were useful because they showed me where the actual engineering challenges begin.
Limitations
MCP V1 was intentionally experimental and was not designed as a production-ready AI platform.
No per-action permission system
Tools can execute without requiring explicit user confirmation for every individual action.
A more mature implementation would introduce permission policies or confirmation steps for sensitive operations.
Application-level filesystem protection
The filesystem restriction is implemented through path validation rather than OS-level sandboxing.
This provides a useful application-level boundary but should not be treated as a hardened security boundary.
Broad browser access
The browser server has broad access to the web and does not provide granular permission controls for every navigation or retrieval operation.
Sequential tool execution
Tool calls are handled sequentially rather than concurrently.
This simplified the implementation but limits throughput and makes more complex workflows slower.
Context limitations
Tool results and file contents can be passed directly into the model context.
Large files or large browser responses can therefore consume significant context and become difficult for smaller local models to handle reliably.
Packaging
The Python sidecar and its runtime require additional packaging configuration.
As a result, distributing the complete desktop application is more involved than packaging a standalone Tauri application.
Why this project is complete
MCP V1 was built around a specific learning objective: understand the architecture and mechanics behind AI-driven tool use through MCP.
Once I understood:
- How MCP servers expose capabilities
- How clients discover those capabilities
- How tool schemas are provided to an LLM
- How the model selects and requests tools
- How those requests are routed to MCP servers
- How results are returned to the model
- Where the practical limitations of the architecture appear
the project had achieved what I wanted from it.
I intentionally stopped development rather than turning the proof of concept into a larger product.
The project therefore remains intentionally small.
Its value is less in the number of features it contains and more in the architecture and implementation experience it provided.
What came next
MCP V1 became a foundation for how I think about AI systems that interact with external capabilities.
The architectural pattern I took away from the project was:
The important idea is that the model does not need to contain every capability itself.
Instead, capabilities can exist independently and be exposed through a standardized interface.
That separation influenced how I approached later projects involving AI, local models, and tool-based systems.
Status
Complete — experimental proof of concept
MCP V1 is no longer under active development.
It remains as a reference implementation of my first practical exploration into local LLM orchestration, MCP servers, and AI-driven tool execution.
