本节我们从无到有,创建一个自己的MCP Server,它可以执行本地的shell,并返回结果。我们将全程使用cursor,不用写任何代码。
先对cursor做下配置,把MCP相关的文档加载到index,这样生成代码的时候会更加准确。
在右上角点击设置,然后在features部分,找到Docs,点击Add new doc
:
分别添加下面两个地址:
https://modelcontextprotocol.io/introduction
https://github.com/modelcontextprotocol/python-sdk
添加时,为它命名,例如MCP
:
添加完成后,cursor很快索引了82个文档页面:
添加第二个文档,同样为它命名:
这次有6000多个page被索引:
添加完这两个文件之后,我们就可以进行代码生成了。
创建一个项目及文件:
mkdir mcp-demo
cd mcp-demo
touch server.py
然后在cursor里输入如下prompt:
这个prompt非常简单,cursor会自动帮我们生成MCP server的代码,代码如下(每次生成的代码都有不同结果,如果运行有问题可以参考以下的代码):
from typing import Any
from mcp.server.fastmcp import FastMCP
import subprocess
import shlex
import os
# Initialize FastMCP server
mcp = FastMCP("ShellExecutor")
# List of allowed commands (for security)
ALLOWED_COMMANDS = {
'ls': True,
'pwd': True,
'echo': True,
'cat': True,
'grep': True,
'find': True,
'date': True,
'whoami': True,
'uname': True,
'df': True,
'du': True,
'ps': True,
'top': True,
'free': True,
'uptime': True,
'netstat': True,
'ifconfig': True,
'ping': True,
'traceroute': True,
'dig': True,
'nslookup': True,
'curl': True,
'wget': True,
'git': True,
'docker': True,
'kubectl': True,
}
def is_command_allowed(command: str) -> bool:
"""Check if the command is in the allowed list."""
cmd = shlex.split(command)[0]
return cmd in ALLOWED_COMMANDS
@mcp.tool()
async def execute_command(command: str) -> dict[str, Any]:
"""
Execute a shell command and return the result.
Args:
command: The shell command to execute
Returns:
A dictionary containing:
- success: bool indicating if the command executed successfully
- output: str containing the command output
- error: str containing any error message
"""
if not is_command_allowed(command):
return {
"success": False,
"output": "",
"error": f"Command '{command.split()[0]}' is not allowed"
}
try:
# Execute the command with a timeout of 30 seconds
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30
)
return {
"success": True,
"output": result.stdout,
"error": result.stderr
}
except subprocess.TimeoutExpired:
return {
"success": False,
"output": "",
"error": "Command execution timed out after 30 seconds"
}
except Exception as e:
return {
"success": False,
"output": "",
"error": str(e)
}
if __name__ == "__main__":
# Run the MCP server
mcp.run(transport='stdio')
可以看到,上面生成的代码有简单的安全加固,它只允许执行一部分命令。
在cursor中配置MCP:
为这个server命名为command
,然后写好对应的python文件路径:
配置完成后,回到原来的页面,发现检查正常。并且看到它的描述是Execute a shell command and return the result
:
此时我们在cursor中可以跟自己的系统交互了,比如查看根目录下的文件:
比如执行kubectl指令,它返回了7个节点:
我们试图执行个不被允许的指令,例如创建文件:
发现没有通过检查,执行失败。