Tips for Building an MCP Server for Your App
What I've learned building an MCP server for my Mac apps: tool descriptions, keeping it in step with the app, server instructions, prompts, a routine tool for apps that don't show prompts, and a way for users to send feedback.

In the last post I mentioned that I’d added an MCP server for my Mac apps, so that Claude or ChatGPT can read and update the data in them while the apps are open. Since then it has grown to 6 apps, adding Due Again, Budget Planner and DiagramSnap, and while building it I’ve learned a few things about keeping the MCP server in step with the apps, helping the assistant pick the right tool, and giving users a way to get started. This article walks through those as tips, with what I did for each, which might help if you’re building an MCP server for your own app.
Write each tool description as the whole story
An MCP server gives the assistant a list of tools, each with a name and a description, and I found the assistant often looks at the tool that sounds closest and treats its description as the full list of what it can do. When I asked it to change a note’s category in Lists & Notes, it only looked at the tool for updating a note, which couldn’t change the category at the time, and then used the app window instead of the separate tool for moving a note. So what I did was to change the descriptions of those two tools so each one mentions the other, and make the update tool able to change anything about a note, including its category. I’ve done the same in some of the other apps, for example in Due Again the tool for moving just one occurrence to another date points to the tool for changing the whole schedule.
A description should also say when to use each option, not only what the options are. Budget Planner has two kinds of expense, Fixed, which is counted on its payment dates, and Estimate, which is spread evenly over the months. The assistant had added some of my annual subscriptions as Estimates, possibly because it defaulted to that. That meant the budget showed the cost as an averaged amount every month, like a run rate, when it was a fixed amount paid annually that should only appear in the month it’s bought and renewed. I reworded the description to say an Estimate is only for spending with no set day, like groceries or fuel, and added the switch between Fixed and Estimate to the tool for updating an expense, as there was no tool to switch them back.
Keep the MCP server in step with the app
Have the tools call the app’s own API, and check the app’s version before using anything newer. The MCP server sits outside the app, so it can fall behind when the app changes, or the app on a user’s Mac might be older than the server expects. I have the tools call each app’s own API rather than reading its data files. That way the app keeps its own rules, and in Budget Planner the totals are worked out by the app with the same code its window uses, not worked out again in the MCP server.
Each app’s tools are only offered when that app is installed on the Mac. A tool that needs a newer version of an app checks the version first, for example updating account balances in Budget Planner says which version it needs, and reading still works. I also have tests that fail if the instructions or prompts name a tool that doesn’t exist, for example after I rename or remove one.
Tell users which version they’re running
Give the assistant a way to answer “am I on the latest version?”. There’s a tool that reports the MCP server’s own version and each app’s version. Since my server doesn’t connect to anything other than the apps on the Mac, it can’t check for a newer version itself. Instead it gives the assistant the npm page, so the assistant can compare the versions if it can open web pages, or give you the link to check. After an update, quit and reopen the AI app, then start a new chat. I found when testing an update that an older chat listed only the routines from the previous version even though the new version was running.
Use the server instructions as a map
An MCP server can also send instructions, once, when the AI app first connects to it. The AI app can then add them to the assistant’s context, and Claude Code does, so they’re part of every message the assistant reads in that conversation. That’s why I keep them short, with one line per app saying which tool does which job, and a few rules for all the apps. The rules are that nothing deletes, a closed app is reported and the assistant asks before opening it, and names match whether or not the capitals match.
A user may want to make bulk updates, such as updating their budget from bank statements by uploading a screenshot, a PDF or a CSV export into the chat. That could be a lot of changes from one statement, so I added a rule that before several changes from one source, like a statement, a document or a pasted list, the assistant shows the proposed changes and waits for you to agree.
Add prompts so users know where to start
Put the steps for common jobs into prompts. Steps for a common job are too long to keep in every message the assistant reads. So I put them into prompts, which the user picks from a menu instead of the assistant reading them by itself. Claude Desktop lists them under the + button, then the server’s name, which for mine is Add from tiongcreative, and each one is only listed when the apps it needs are installed. There are 11 now, including what needs my attention this week, who owes me money and turning a note into a diagram. One is called “What can you do with my apps?”, and it gives a short tour of the connected apps, what you can ask for in each, and the routines you can run.
Prompts are also where I put the order of the steps and when the assistant should stop and ask. Checking a statement against my budget starts by listing the current expenses so nothing is added twice, then shows a table of proposed changes and waits for an OK. For a new price, the change starts from the date of the first charge at that price, and earlier months keep the old amount. Cancelled subscriptions get an end date and are not deleted. Not every AI app shows prompts though, which is the next tip.
Offer the same steps as a tool
Offer the prompts’ steps as a tool as well, for AI apps that don’t show prompts. I tried the prompts in ChatGPT desktop, which runs MCP servers through the Codex CLI that comes with it, and they weren’t there. After investigating, I found that Codex doesn’t show MCP prompts yet, and there’s an open request on GitHub asking for it. To get round that I added a routine tool, which returns the same steps as the prompt, from the same text. I also added a line in the instructions telling the assistant to call it for those jobs. Asking “what can you do with the apps” in a new chat in Claude Desktop listed the routines and how to send feedback, and the prompts are still in its menu as well.
Give users a way to send feedback
Give users a way to send feedback from the chat. An MCP server is a program running on the user’s computer, and it could send usage data back to the developer as optional telemetry, but for privacy I chose not to go down that path. My MCP server only talks to the apps on your Mac and doesn’t send anything to me, so I don’t see which tools are used. Downloads show on the npm page, though the biggest days are on release days, and I can’t tell from them who is actually using it.
My first attempt at feedback was a link in the tool that reports the server’s version, with a note telling the assistant to draft a message for the user to send. When I said “I wish there were more prompts” in ChatGPT, the assistant suggested some ideas but didn’t offer to pass it on, and it was only when I asked about feedback that it drafted the note. After that I moved it into its own feedback tool, with a description that names the moments it’s for, like “I wish” or “that didn’t work”. It drafts a note with the server and app versions filled in. It also returns an email link that opens the note ready to send, and a link to my contact page, and the assistant doesn’t send anything itself.
I hope this helps if you give it a go.