Introduction to MCP
MCP (Model Context Protocol) is a development protocol that standardizes how applications provide context for large models. MCP provides a standardized way to supply data and tools for LLMs, making it easier to build agents or complex workflows based on LLMs.
Architecture
MCP follows a client-server architecture where an MCP host application can link to multiple MCP servers.
-
MCP Host: The program that needs to obtain data via MCP, such as Claude Desktop, IDEs, or some AI tools. -
MCP Client: The client of the MCP protocol, which supports one-to-one communication with the MCP Server. -
MCP Server: A lightweight application that exposes certain capabilities through MCP. According to the MCP protocol, servers can provide three types of standard capabilities: Resources, Tools, and Prompts. Each server can provide one or more of these capabilities simultaneously. -
Resources: Resources, similar to file data reading, can be file resources or content returned from API responses. -
Tools: Third-party services or functional functions that control which functions can be called by the LLM. -
Prompts: Predefined templates for specific tasks. -
Local Data Resources: Local files, databases, services, etc. that the MCP Server can access securely. -
Remote Services: External systems that the MCP Server can connect to via the network (e.g., APIs).
Illustration of MCP services:
MCP Servers provide a list of functionalities (e.g., a list of tools) to the Host Application via the MCP Protocol. The Host Application formats this list into a format that the LLM can understand. The Host Application can use this functionality list to send requests that require processing by the large model (this is the prompt). The LLM returns a JSON string of tool_calls based on this prompt. When the Host Application receives this tool_calls, it will call the corresponding MCP server tool to return the corresponding result.
Using MCP with Claude Desktop
To use the MCP with Claude Desktop, you first need to install it, which we will skip here. We will configure a file system MCP Server.
Then select Edit Config under Developer,
Open<span>claude_desktop_config.json</span>
to complete the configuration of the file system MCP Server. (In the configuration, replace the username with your own computer’s username, and ensure that you have Node.js installed locally.)
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Desktop",
"/Users/username/Downloads"
]
}
}
}
After completing the configuration, restart the Claude client. You can then try it out. Click the hammer icon to see the tools provided by the MCP Server.
Input the following prompt to test it out:
Can you take all the images on my desktop and move them to a new folder called “Images”?
When the LLM responds and the file system MCP server executes, there will be several permission prompts; remember to allow them.
Then you will see the LLM and MCP Server start working.
Beginner’s Guide to Developing MCP Server (Python and Pip)
A simple MCP server developed using the Python tech stack.
Requirements
The MCP server requires the python-sdk, and Python version 3.10 is needed. Install as follows:
pip install mcp
PS: The official MCP uses the uv package manager, but I usually use pip, so this article primarily uses pip. Since some dependency versions of MCP are not the latest, it’s best to create a clean environment. The MCP inspector provides debugging client functionality needed to develop an MCP Server.
npx @modelcontextprotocol/inspector <command> <arg1> <arg2>
In which case the command should be python if we are using a Python-written server. The <arg1> <arg2>
are optional parameters. After starting:
Developing a Demo MCP Server
The MCP Server needs to expose certain capabilities through MCP. According to the MCP protocol, servers can provide three types of standard capabilities: Resources, Tools, and Prompts. Each server can provide one or more of these capabilities simultaneously.
-
Resources: Similar to file data reading, can be file resources or content returned from API responses. -
Tools: Third-party services or functional functions that control which functions can be called by the LLM. -
Prompts: Predefined templates for specific tasks.
Next, we will demonstrate the above three types of capabilities using the python-sdk.
Prompts
We start with prompts by using<span>handle_list_prompts</span>
to list available prompt templates, and<span>handle_get_prompt</span>
to retrieve a specific prompt template by name.
@server.list_prompts()
async def handle_list_prompts() -> list[types.Prompt]:
"""
Prompt template definition
"""
return [
types.Prompt(
name="example-prompt",
description="An example prompt template",
arguments=[
types.PromptArgument(
name="arg1",
description="Example argument",
required=True
)
]
)
]
@server.get_prompt()
async def handle_get_prompt(
name: str,
arguments: dict[str, str] | None
) -> types.GetPromptResult:
"""
Prompt template processing
"""
if name != "example-prompt":
raise ValueError(f"Unknown prompt: {name}")
return types.GetPromptResult(
description="Example prompt",
messages=[
types.PromptMessage(
role="user",
content=types.TextContent(
type="text",
text="Example prompt text"
)
)
]
)
Resources
The resource management functionality code<span>list_resources</span>
lists available resources and returns a list of resources. The<span>read_resource</span>
reads the contents of a specified URI. SAMPLE_RESOURCES is a demo created for testing.
@server.list_resources()
async def list_resources() -> list[types.Resource]:
"""
Resource definition
"""
test='test'
return [
types.Resource(
uri=AnyUrl(f"file:///{test}.txt"),
name=test,
description=f"A sample text resource named {test}",
mimeType="text/plain",
)
# for name in SAMPLE_RESOURCES.keys()
]
SAMPLE_RESOURCES={'test':'this demo is a mcp server!'}
@server.read_resource()
async def read_resource(uri: AnyUrl) -> str | bytes:
assert uri.path is not None
print(uri.path)
name = uri.path.replace(".txt", "").lstrip("/")
# print(name)
if name not in SAMPLE_RESOURCES:
raise ValueError(f"Unknown resource: {uri}")
return SAMPLE_RESOURCES[name]
Tools
Tool definitions and calls,<span>handle_list_tools</span>
defines available tools and uses JSON Schema to validate tool parameters. The<span>handle_call_tool</span>
processes tool calls by executing the corresponding operation based on the tool name and parameters.
@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
"""
Tool definition.
Each tool uses JSON Schema to validate its parameters.
"""
return [
types.Tool(
name="demo-tool",
description="Get data tool for a param",
inputSchema={
"type": "object",
"properties": {
"param": {
"type": "string",
"description": "url",
},
},
"required": ["param"],
},
)
]
@server.call_tool()
async def handle_call_tool(
name: str, arguments: dict | None
) -> list[Any]:
logging.info(name)
"""
Process tool calls
"""
if not arguments:
raise ValueError("Missing arguments")
if name == "demo-tool":
param = arguments.get("param")
if not param:
raise ValueError("Missing state parameter")
param = param.upper()
return [
types.TextContent(
type="text",
text=f"text:{param}"
)
]
else:
raise ValueError(f"Unknown tool: {name}")
Inspector
Below is a completed MCP Server that can be debugged using the MCP inspector. Enter the following command in the directory where the server code is located:
npx @modelcontextprotocol/inspector
After starting, you will see a screenshot. Access http://localhost:5273, select STDIO for transport type, input python for command, and server.py for arguments (the demo code above is saved in server.py). Click connect. Through the interface, you can enter various types to call the corresponding server services. In Resources, click List Resource to list all resources, and click on a specific resource to see its content.
This way, you can interact with the MCP Server you have developed.
How to Configure in Claude Desktop
According to the command configuration in the inspector, configure this MCP Server in Claude. Click on the settings in Claude Desktop, select the Developer tab, and then click Edit Config to navigate to claude_desktop_config.json.
I have currently installed two MCP Servers, configured as follows: one for file organization and one for playwright (the MCP Server for playwright needs to be installed via npx).
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/crisschan/Desktop",
"/Users/crisschan/Downloads"
]
},
"playwright": {
"command": "npx",
"args": ["-y",
"@executeautomation/playwright-mcp-server"]
}
}
}
Configure your own demo service in this format, save it, and then restart Claude Desktop.
{
"mcpServers": {
"demo": {
"command": "/opt/anaconda3/bin/python3",
"args": ["/Users/workspace/pyspace/try_mcp/server.py"]
}
}
}
In the configuration, the command must be the absolute path of the corresponding version of Python, and the location of server.py in args must also use the absolute path.