内容
#树莓派MCP服务器
<p align="center">
<img src="https://raw.githubusercontent.com/ctacke/RaspiMcp/main/assets/icon.png" width="128" height="128" alt="RaspiMcp icon" />
</p>
用于通过SSH控制树莓派设备的生产级.NET 10 MCP(模型上下文协议)服务器。 将Claude Code或任何与MCP兼容的AI助手直接连接到您的树莓派设备群。
## 什么是RaspiMcp?
RaspiMcp将SSH操作公开为MCP工具,允许AI助手:
- 在远程树莓派上执行shell命令
- 读取文件并检查目录内容
- 尾部日志文件和查询systemd服务
- 在运行时切换多个配置的树莓派目标
所有命令都经过安全验证器,阻止破坏性操作(`rm -rf`、`mkfs`、`shutdown`等),每次执行都记录审计日志。
## 功能
| 功能 | 描述 | 安全注意事项 |
|---|---|---|
| shell命令执行 | 在活动树莓派上运行任何shell命令,并返回stdout/stderr/退出代码 | 基于黑名单,**不是**只读沙盒 - 只有少数破坏性模式(`rm -rf`、`mkfs`、`dd`、`shutdown`、`reboot`、`poweroff`、`halt`、`init 0`、`systemctl poweroff/reboot/halt`)被阻止。其他操作(包括写入和删除)都是允许的。 |
| 文件系统检查 | 读取文件、列出目录、状态路径、检查存在性 | 基于`cat` / `ls -lah` / `stat` / `test`的只读帮助程序 |
| 日志和服务检查 | 尾部日志文件、检查systemd服务状态、查询日志条目 | 基于`tail` / `systemctl status` / `journalctl`的只读帮助程序 |
| 主机管理 | 列出配置的树莓派别名、查看活动主机、在运行时切换目标 | 切换主机需要明确的用户批准 |
| 插件可扩展性 | 从放入`plugins/`的DLL加载额外的工具集 | 插件完全受信任 - 插件代码与主机进程之间没有沙盒隔离 |
| GPIO引脚控制 | 通过SSH上的`pinctrl`设置/读取BCM GPIO引脚,并驱动一个3引脚数字RGB LED | 随附一个插件(参见[随RaspiMcp附带的插件](#随raspimcp附带的插件))- 不编译到主服务器程序集,但无需额外步骤即可使用。需要在树莓派上安装`pinctrl`/`raspi-gpio` |
| 审计日志 | 每个执行的命令都记录有时间戳、主机、退出代码和持续时间 | 通过标准`ILogger`记录结构化的`[AUDIT]`条目 - 根据需要路由到文件/Seq等 |
参见下面的[可用MCP工具](#可用mcp工具)以获取逐工具的详细分解。
## 先决条件
- 一个或多个树莓派设备的SSH访问权限
- 一个SSH密钥对(推荐)或密码凭证
- [.NET 10运行时/SDK](https://dotnet.microsoft.com/download/dotnet/10.0) - **仅限**通过`dotnet tool install`或从源代码构建时需要。自包含的发布二进制文件只需要树莓派的SSH访问权限。
## 安装
### 推荐:作为全局工具安装
```bash
dotnet tool install -g RaspiMcp.Server
```
发布到[nuget.org](https://www.nuget.org/packages/RaspiMcp.Server),因此不需要源代码配置或身份验证 - 这是.NET SDK的默认包源。这会在您的`PATH`上安装一个`raspi-mcp`命令。直接在您的Claude Code的`mcp.json`条目中配置树莓派的连接详细信息 - 参见下面的[Claude Code集成](#claude-code集成)。以后可以使用`dotnet tool update -g RaspiMcp.Server`升级。
### 替代方法:下载发布二进制文件
不需要安装.NET。 从[发布页面](../../releases)获取您操作系统的存档并解压。 有关详细信息,请参见[docs/deployment.md](docs/deployment.md)。
## 从源代码运行
为RaspiMcp本身做出贡献:
1. **克隆和构建**
```bash
git clone https://github.com/ctacke/RaspiMcp
cd RaspiMcp
dotnet build RaspiMcp.slnx
```
2. **运行服务器**
```bash
dotnet run --project src/RaspiMcp.Server
```
树莓派的连接详细信息来自您的`mcp.json`条目的`env`块(如下所示),与任何其他安装方法相同。
## Claude Code集成
使用`claude mcp add` CLI将RaspiMcp注册到Claude Code - 这是在用户范围内添加服务器的受支持方式(在所有项目中都可用);没有用户级配置文件需要手动编辑。 环境变量直接传递树莓派的连接详细信息:.NET的配置管道在`appsettings.json`上层叠环境变量,使用`__`(双下划线)表示嵌套,因此没有单独的配置文件需要管理。
如果安装为全局工具:
```bash
claude mcp add --scope user raspi-mcp --env Ssh__CurrentHost=orleans2 --env Ssh__Hosts__orleans2__Host=orleans2.local --env Ssh__Hosts__orleans2__Username=pi --env Ssh__Hosts__orleans2__Password=secret -- raspi-mcp
```
如果使用下载的发布二进制文件:
```bash
claude mcp add --scope user raspi-mcp --env Ssh__CurrentHost=orleans2 --env Ssh__Hosts__orleans2__Host=orleans2.local --env Ssh__Hosts__orleans2__Username=pi --env Ssh__Hosts__orleans2__Password=secret -- F:/tools/raspi-mcp/RaspiMcp.Server.exe
```
如果从源代码运行:
```bash
claude mcp add --scope user raspi-mcp --env Ssh__CurrentHost=orleans2 --env Ssh__Hosts__orleans2__Host=orleans2.local --env Ssh__Hosts__orleans2__Username=pi --env Ssh__Hosts__orleans2__Password=secret -- dotnet run --project F:/repos/ctacke/RaspiMcp/src/RaspiMcp.Server --no-build
```
**运行`claude mcp add`后,请重启您的`claude`会话**(退出并重新启动)- 在会话已经运行时添加的服务器不会在`/mcp`中出现,直到您这样做。
使用私钥代替密码,请设置`--env Ssh__Hosts__<alias>__PrivateKey=<path>`而不是`...__Password`。希望通过git与团队共享,而不是仅限于您的机器?使用`--scope project`代替`--scope user` - 这会将内容写入存储库根目录中的`.mcp.json`。更喜欢为`switch_host`预定义多个树莓派主机,而不是使用一堆`--env`标志?请参见[docs/deployment.md](docs/deployment.md#installing-a-release)中的`appsettings.json`替代方案。
## 从非.NET客户端使用RaspiMcp
RaspiMcp是一个标准的MCP服务器,通过stdio使用JSON-RPC进行通信 - 任何与MCP兼容的客户端都可以与其通信,无论客户端使用何种语言编写。 您不需要.NET SDK来**使用**服务器:下载[发布页面](../../releases)上的独立二进制文件(参见[docs/deployment.md](docs/deployment.md)),并将您的客户端指向可执行文件。 .NET SDK仅在您从源代码构建时需要。
### 示例:Python客户端
安装官方MCP Python SDK:
```bash
pip install mcp
```
然后将RaspiMcp二进制文件作为子进程启动并调用其工具:
```python
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
server_params = StdioServerParameters(
command="./RaspiMcp.Server", # 或Windows上的RaspiMcp.Server.exe
args=[],
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
print([t.name for t in tools.tools])
result = await session.call_tool("execute", {"command": "uptime"})
print(result.content)
asyncio.run(main())
```
这与其他语言的MCP客户端库(或手工制作的JSON-RPC-over-stdio客户端)的工作方式相同 - Claude Code只是一个可能的前端。
## 可用MCP工具
| 工具 | 描述 |
|------|-------------|
| `get_current_host` | 返回活动的SSH目标(别名、主机、用户名) |
| `list_hosts` | 列出所有配置的主机别名 |
| `switch_host` | 切换活动的SSH目标 - 需要用户批准 |
| `execute` | 在当前主机上运行shell命令 |
| `read_file` | 返回远程文件的内容 |
| `list_directory` | 使用`ls -lah`输出列出目录 |
| `stat` | 返回远程路径的`stat`输出 |
| `file_exists` | 返回远程路径的真/假值 |
| `tail_log` | 返回日志文件的最后N行 |
| `systemctl_status` | 返回systemd服务状态 |
| `journal` | 返回服务的journalctl条目 |
| `hello` | 示例插件问候工具(验证插件系统是否正常工作) |
## 部署
要将RaspiMcp构建并发布为可下载的二进制文件或NuGet工具,请参见[docs/deployment.md](docs/deployment.md)。 推送`vX.X`或`vX.X.X`标签(例如`v1.0`、`v0.9.1`)会触发自动的GitHub Actions发布。
## 插件开发
RaspiMcp是可扩展的。 有关编写和部署自定义插件的完整指南,请参见[docs/plugin-development.md](docs/plugin-development.md)。
简要来说:
1. 创建一个引用`RaspiMcp.Core`的.NET类库
2. 实现`IMcpPlugin`
3. 创建一个具有`[McpServerTool]`属性的方法的`[McpServerToolType]`类
4. 将编译后的DLL放入服务器二进制文件旁边的`plugins/`文件夹中
### 随RaspiMcp附带的插件
任何源代码位于存储库下的`plugins-src/`的插件都将自动随`RaspiMcp.Server`附带 - 安装或更新工具(`dotnet tool install`/`update -g RaspiMcp.Server`)或下载发布二进制文件即可免费获得,无需手动构建/复制步骤。 它仍然通过运行时相同的`plugins/`下拉机制加载(不直接编译到`RaspiMcp.Server`自己的程序集中),因此`PluginLoader`无需进行代码更改即可加载它 - 插件DLL只需在构建/打包时自动打包到服务器二进制文件旁边的`plugins/`文件夹中。
**`plugins-src/RaspiMcp.Gpio`** - 通过`pinctrl`(如果您的树莓派没有`pinctrl`,则回落到`raspi-gpio`,语法相同)控制SSH上的BCM GPIO引脚:
| 工具 | 描述 |
|------|-------------|
| `set_rgb_led` | 通过驱动三个BCM引脚高/低,将3引脚数字RGB LED设置为命名颜色(关闭,红色,绿色,蓝色,黄色,洋红色,青色,白色) |
| `set_gpio_pin` | 将单个BCM引脚配置为输入或输出;对于输入,启用内部上拉/下拉电阻 |
| `get_gpio_pin` | 读取BCM引脚的当前模式、拉伸配置和电平 |
有关详细信息,请参见[docs/plugin-development.md](docs/plugin-development.md#real-world-external-plugin-example),或将您自己的插件添加到此列表中。
## 安全注意事项
- **永远不要提交`appsettings.json`** - 它包含凭证。 默认情况下,它被git忽略。
- **如果您使用`--scope project`注册RaspiMcp(写入存储库根目录中的`.mcp.json`),请不要提交该文件** - 优先使用`--scope user`,以便通过`--env`传递的树莓派凭证不会出现在git历史记录中。
- 命令验证器阻止:`rm -rf`、`mkfs`、`dd`、`shutdown`、`reboot`、`poweroff`、`halt`、`init 0`和`systemctl poweroff/reboot/halt`。
- 所有执行的命令都通过结构化的`[AUDIT]`日志条目进行审计日志记录。
- SSH私钥路径在连接时从本地文件系统读取;密钥永远不会离开机器。
- 在可能的情况下,请使用SSH密钥身份验证而不是密码。
## 运行测试
```bash
dotnet test tests/RaspiMcp.Tests/RaspiMcp.Tests.csproj
```