MCP Server Development, Demystified with a macOS Maps Search Tool
How to Learn MCP Development with a Small Project
I demonstrate how to develop an MCP server with a small feature.
In an AI tool, say "Search West Lake scenic area in the map" and this service will open the macOS built-in "Maps" and initiate the search.
That's the only feature. Let's see how it works.
The relationship between the model and MCP
The model is responsible for understanding your words and deciding which tool to call. Tools are registered in the MCP server. The model selects them based only on name, description, and parameters. MCP is the protocol between them: the AI tool starts the server, sends the selection; the server executes and returns the result to the model.
How MCP works
An MCP server does a few things internally. It communicates with the AI tool via standard input and standard output, called stdio. Only protocol messages go to stdout; logs go to stderr. The server first registers tools with name, description, and parameters. When a call arrives, it executes according to the parameters and sends the result back.
This repository is called local-maps-mcp. Three files are key.
package.jsonis the project spec.binandnpm startboth point to the entrysrc/index.js.src/index.jsuses the official SDK@modelcontextprotocol/serverto create the server, describes parameters with Zod, and registers the single toolsearch_map. The parameterqueryis a required string, with description: use when the user asks to search, find, or open a place in the map.src/maps.jsonly handles the map part: check parameters, build the link, and call the system'sopen. It doesn't touch protocol messages.
Process analysis
- Normally the AI tool starts
src/index.jsin the MCP server. - When a call arrives,
index.jsdoesn't do the map work; it just passesquerytoopenMapSearch()inmaps.js. maps.jsbuilds an Apple Maps link with the search term in theqparameter, e.g.,https://maps.apple.com/?q=西湖景区. Then it uses the system commandopento open Maps. No API key for a map platform is required.
/usr/bin/open -b com.apple.Maps <map link>
-b com.apple.Maps specifies that the system "Maps" opens this link. When open returns, the request has been handed to the system.
How to configure the MCP server
The AI tool needs a configuration that specifies the server name, Node.js to start it, and the entry src/index.js.
Since I use Cursor, I'll use Cursor as an example.
Cursor merges project-level and user-level configurations, with project-level taking precedence if same names.
Project-level goes in .cursor/mcp.json and is effective when opening this project.
User-level goes in ~/.cursor/mcp.json and applies to all projects on this machine. When writing to user-level, keep other existing servers in the file.
{
"mcpServers": {
"local-maps-mcp": {
"command": "node",
"args": ["${workspaceFolder}/src/index.js"]
}
}
}
In the Agent conversation, type:
Search West Lake scenic area in the map
The model will call search_map with parameter { "query": "西湖景区" }. The system Maps comes to the foreground and receives the search. The conversation shows:
Sent search request to system Maps: 西湖景区
How to publish the MCP server
If you want others to use it, publish it to npm. Log in and publish both specify the official registry. During login, npm may ask for a dynamic verification code, and possibly again during publish.
# In command line, go to project directory
npm login --registry https://registry.npmjs.org
npm publish --registry https://registry.npmjs.org
Seeing + [email protected] means success.
Others install the published package; the entry is no longer the source file in the repo. Configuration can be:
{
"mcpServers": {
"local-maps-mcp": {
"command": "npx",
"args": ["-y", "local-maps-mcp"]
}
}
}
Or install globally and set the start command to local-maps-mcp:
npm install -g local-maps-mcp --registry https://registry.npmjs.org
command -v local-maps-mcp
command -v prints the executable path, indicating the current terminal can find it.
Below is the complete code and the repository link:
Repository: https://github.com/liyufengrex/mcp_search_map