Building a Remote MCP Server for Expense Tracking: One Developer's Real-World Lessons
Every time you need to log an expense, you jump between an app, a spreadsheet, and a browser tab. It's tedious, and something that should take seconds ends up taking minutes. What if you could just tell an AI assistant to record it, naturally, like you're talking to a colleague—and have it actually be stored somewhere you control?
On July 16, 2026, developer Ali Raza shared exactly how he solved this problem by building a remote MCP server and connecting it to Claude Desktop. His journey reveals both how elegant this solution can be and where the real friction hides.
Why This Matters Right Now
In 2026, AI assistants are becoming your primary interface to tools. But most guides assume you're building toy examples that run locally or interact only with public APIs. The moment you want to bring your own data and your own services into the conversation—without handing control to a third party—you hit a different set of problems. This is the story of solving those problems end-to-end.
What Is MCP, and Why Does It Matter?
MCP stands for Model Context Protocol. Think of it as a conversation between Claude and your code. When you write something in Claude Desktop, it can call functions that live on a server you own. MCP defines how that conversation works—what format the request takes, what response looks like, how errors get handled. It's a protocol, not magic, but it opens a door.
Without MCP, connecting Claude to your personal expense tracker would mean building an API, then a Claude plugin, then hoping the plugin ecosystem works the way you expect. With MCP, you expose some functions ("add an expense," "show me what I spent last month") and Claude knows how to call them. Your data stays yours. Your server stays under your control.
The Setup: What Raza Built
The solution has three main parts: a tool-definition layer, a database, and a connection to Claude Desktop.
Tool Definition with FastMCP
FastMCP is a Python library that makes it easy to define which functions Claude can call. Raza used it to expose four core tools:
add_expense— record a new transactionget_summary— retrieve expense statistics or trendslist_transactions— show recent or filtered expenses- Category management — organize expenses by type
When you ask Claude "log $15 for coffee," FastMCP translates that into a function call and sends it to the server.
Database Access with aiosqlite
A naive approach would use standard SQLite, which blocks while the database answers queries. In an async server (one that juggles many requests at once without waiting), blocking is poison—it stalls everything. Raza switched to aiosqlite, which lets the database requests run without freezing other work.
The database itself lives in a temporary directory managed by Python's tempfile module. This might sound fragile, but it's actually adaptive: Raza's deployment environment (Horizon) doesn't guarantee a fixed writable path, so dynamic storage prevents deployment friction.
Connecting to Claude Desktop
Once the server is running, you register it in Claude Desktop's configuration as a custom connector. From then on, when you open Claude Desktop and ask it to work with expenses, it reaches out to your remote server.
Deploying the Server
Raza deployed the complete MCP server to Horizon, a cloud platform. The server runs remotely, not on your laptop. Claude Desktop, running locally, calls it over the internet. This separation is clean: your laptop doesn't need to stay powered on, and your server can be accessed from any device where Claude Desktop runs.
Two Lessons the Tutorials Don't Teach
Building this end-to-end surfaced problems that quick-start guides gloss over.
Lesson 1: Windows MSIX Sandboxing
Claude Desktop on Windows ships as an MSIX package—Microsoft's modern app format. The operating system virtualizes the file system. When you think Claude Desktop is writing to the usual Windows config folder, it's actually writing to a sandboxed location that the OS presents as if it were normal.
Raza discovered this the hard way: the configuration file didn't exist where the standard documentation said it should. Solving this required understanding how MSIX virtualization works, not just following a recipe.
Lesson 2: OAuth Beyond the Basics
Local-only MCP servers never need to authenticate with external services. But the moment your server talks to a real API—say, to fetch data from a bank, or log expenses to a service—you need OAuth. And OAuth is more than just "click a login button."
You need to:
- Start the OAuth redirect flow (send the user to the authorization server)
- Receive the authorization code when the user grants permission
- Exchange that code for an access token
- Store the token securely
- Refresh the token when it expires
Most beginner tutorials skip all of this. Raza had to read the OAuth specification directly to get it right.
The Outcome: Effortless Expense Logging
After working through these problems, Raza ended up with a working system. A natural-language instruction in Claude Desktop—"log 15 dollars for a coffee, category meals"—is routed through MCP to the remote server, stored in the database, no separate app or web form required.
More importantly, the real-world bugs are fixed. When Raza deploys to Horizon and opens Claude Desktop on Windows, it just works. No path surprises. No token expirations breaking the flow.
What's Next
Raza is extending this into agentic workflows using LangGraph, a framework for building multi-step AI agents. The goal is to add stateful logic: the AI doesn't just execute one tool call at a time, it builds a plan, executes it over multiple steps, checkpoints progress, and can pause to ask for human approval before taking critical actions.
The repository is public on GitHub at github.com/AliRaza3485/test-remote-mcp-server, so if you're building with MCP or LangGraph, you can see the patterns firsthand.
Conclusion
Building a remote MCP server is straightforward in outline—define your tools, wire them to a database, register the server with Claude Desktop—but the details matter. Windows packaging, async database access, and OAuth lifecycle management aren't exotic edge cases; they're part of any real deployment. Raza's journey shows that the gap between a toy example and a working system is smaller than it seems, but you do have to walk it with eyes open.
Merits
- Data ownership: Your expense data lives in your own database, not in a vendor's cloud.
- Natural interaction: No separate UI or app; you ask Claude Desktop in plain English.
- Extensibility: Once the foundation is in place, adding new tools (budget alerts, recurring expenses, etc.) is straightforward.
- Learning resource: The public repository shows real-world patterns for OAuth, async databases, and deployment quirks.
- Integration: Works seamlessly with Claude Desktop on Windows, Mac, and other platforms where it runs.
Demerits
- Operational responsibility: You own the server. Outages, security patches, and database backups are your responsibility.
- Deployment complexity: Horizon or another platform adds a layer; if you prefer local-only, you'd need a different approach.
- OAuth learning curve: If your server needs external authentication, you'll need to understand the full OAuth flow, not just copy a tutorial snippet.
- Limited to Claude: The MCP server talks to Claude Desktop. If you want the same tools in other AI clients, you'd need separate integrations.
- Tempfile fragility: Using Python's tempfile for database storage works for now but requires careful consideration if you later switch hosting environments.
Caution
This article is educational and summarizes real developments reported on DEV Community by Ali Raza on July 16, 2026. Any implementation you attempt should start with reading Raza's public repository and the official MCP documentation. Verify all claims against the original source before relying on this article for production work. The OAuth patterns and deployment details described here are specific to Raza's implementation; your environment may require different choices. Always test configuration paths, token refresh logic, and database access patterns in a non-production setting before moving to production. Treat access tokens and any secrets with appropriate security practices—never commit them to version control or log them in plain text.
Frequently asked questions
What is the Model Context Protocol (MCP)? — MCP is a standard protocol that lets AI assistants like Claude call functions exposed by a server you control, enabling seamless integration of your own tools and data without building a separate plugin.
Can I run the MCP server locally instead of on Horizon? — Yes, you can host the server locally or on any platform with internet access. Horizon is what Raza chose, but FastMCP and aiosqlite work anywhere Python runs.
Do I need to know Python to build an MCP server? — The example uses Python and FastMCP, but MCP is language-agnostic. You could build an MCP server in Node.js, Go, Rust, or any other language; you'd just use a different library.
How do I keep my expense data secure if it's on a remote server? — Use HTTPS to encrypt data in transit, run the server in a private network or behind authentication, and ensure the server itself is kept up-to-date. Consider storing sensitive credentials (like OAuth tokens) in a secure vault, not in plain files.
What if the remote server goes down? Does Claude Desktop stop working? — Yes, Claude Desktop won't be able to call tools hosted on an unavailable server. This is why production MCP servers usually have monitoring, backups, and a plan for quick recovery.
Can I use MCP servers to connect multiple AI assistants to the same tools? — MCP is protocol-based, so in theory yes. However, Claude Desktop is currently the primary client with full MCP support. Integration with other AI platforms would require those platforms to also support MCP.
How often do I need to refresh OAuth tokens? — It depends on the service. Most services issue tokens valid for one hour to several days. Raza's implementation handles this automatically; the server stores tokens and refreshes them before they expire.
Is aiosqlite faster than regular SQLite? — Not necessarily faster in raw speed, but safer in async contexts. It prevents the entire server from stalling while the database answers a query, which matters when you're juggling many requests at once.
Tags
#mcp #aiassistant #expensetracking #clouddeployment #pythondev #fastapi #oauth2 #remoteserver


Responses
Sign in to leave a response.