跳过正文

Huawei PixLab + Raspberry Pi + Poke MCP 打印部署教程

·2803 字 ·6 分钟
作者
余晖采样
记录技术实践、生活随想与思考片段。
目录

本文面向希望把局域网打印机接入 Poke 的用户,目标是:

  • 树莓派连接局域网中的华为 PixLab 打印机;
  • 通过 CUPS 管理打印队列;
  • 通过 MCP 暴露打印能力给 Poke;
  • 支持 Poke 上传文件到树莓派后打印;
  • 公网入口带 Bearer API Key 鉴权;
  • 上传文件超过 7 天自动删除。

本文以 Huawei PixLab V1 为例,其他支持 AirPrint / IPP / driverless 的打印机也可参考。

一、最终架构
#

Poke
  │  HTTPS + Authorization: Bearer <MCP_API_KEY>
Cloudflare Tunnel
Raspberry Pi 127.0.0.1:3000
mcp-compat-proxy.mjs
  ├─ 鉴权
  ├─ 兼容 Poke 的 MCP 会话
  ├─ 上传文件工具
  ├─ print_url 下载工具
  └─ 打印机别名/选项规范化
Raspberry Pi 127.0.0.1:3001
lan-mcp-cups
CUPS
Huawei PixLab driverless 队列

不要把 CUPS 的 631 端口直接暴露到公网。公网只暴露认证后的 MCP 入口。

二、本地配套文件
#

本文配套文件已随站点提供,可从以下路径下载,也可以在部署机器上手动创建同名文件:

/downloads/huawei-printer-mcp/mcp-compat-proxy.mjs
/downloads/huawei-printer-mcp/huawei-printer-mcp-upstream.service
/downloads/huawei-printer-mcp/huawei-printer-mcp-proxy.service
/downloads/huawei-printer-mcp/cleanup-uploads.sh
/downloads/huawei-printer-mcp/huawei-printer-upload-cleanup.service
/downloads/huawei-printer-mcp/huawei-printer-upload-cleanup.timer

把这些文件复制到树莓派时,默认安装目录为:

/home/pi/huawei-printer-mcp/

如果你的用户名不是 pi,需要把所有示例里的 /home/pi 和 systemd unit 中的 User=piGroup=pi 改成你的实际用户名。

三、前置条件
#

树莓派需要:

  • Debian / Raspberry Pi OS;
  • 与打印机在同一局域网;
  • 已安装并启用 SSH;
  • 可访问公网,用于 Cloudflare Tunnel 和 npm 安装;
  • 已有一个可用于 Cloudflare Tunnel 的域名。

安装基础包:

sudo apt update
sudo apt install -y \
  cups cups-client cups-bsd \
  cups-browsed cups-filters avahi-daemon \
  curl openssl

说明:

  • cups / cups-client:CUPS 打印系统;
  • cups-bsd:提供 lprlan-mcp-cupsprint_file 会用到;
  • cups-browsed / cups-filters:提供 driverless/自动发现队列;
  • avahi-daemon:用于发现 .local / Bonjour / AirPrint 设备。

启用 CUPS:

sudo systemctl enable --now cups
sudo systemctl enable --now cups-browsed
sudo systemctl enable --now avahi-daemon

如需浏览器管理 CUPS:

sudo cupsctl --remote-any --remote-admin --share-printers
sudo usermod -aG lpadmin "$USER"
sudo systemctl restart cups

访问:

https://<树莓派IP>:631

四、安装 Node.js 和 lan-mcp-cups
#

确认 Node.js:

node -v
npm -v

建议 Node.js 20 或更高版本。

安装 lan-mcp-cups

sudo npm install -g lan-mcp-cups
command -v lan-mcp-cups

应输出类似:

/usr/local/bin/lan-mcp-cups

五、配置 CUPS 打印队列
#

先查看自动发现的打印机:

lpstat -p -d
lpstat -v
lpoptions -p <打印机名> -l

华为 PixLab 常见自动队列类似:

HUAWEI_PixLab_V1_0374

优先使用这个 driverless 自动队列,而不是手动创建的泛化 Printer - IPP Everywhere 队列。后者在部分 PDF 或图片场景下可能出现白纸、打印机端取消任务等问题。

查看队列驱动:

grep -Ei 'NickName|ModelName' /etc/cups/ppd/HUAWEI_PixLab_V1_0374.ppd

理想输出应包含:

HUAWEI PixLab V1, driverless, cups-filters

设置默认打印机:

sudo lpadmin -d HUAWEI_PixLab_V1_0374
lpoptions -d HUAWEI_PixLab_V1_0374

设置常用默认选项:

sudo lpadmin \
  -p HUAWEI_PixLab_V1_0374 \
  -o ColorModel=Gray \
  -o PageSize=A4 \
  -o MediaType=Stationery \
  -o cupsPrintQuality=Normal \
  -o sides=one-sided \
  -o print-scaling=auto-fit

检查:

lpstat -p -d
lpoptions -p HUAWEI_PixLab_V1_0374

六、部署 MCP 文件
#

创建目录:

mkdir -p /home/pi/huawei-printer-mcp/uploads
chmod 700 /home/pi/huawei-printer-mcp/uploads

把配套文件复制到树莓派:

scp huawei-printer-mcp-poke-files/mcp-compat-proxy.mjs \
  pi@<树莓派IP>:/home/pi/huawei-printer-mcp/

scp huawei-printer-mcp-poke-files/huawei-printer-mcp-upstream.service \
  pi@<树莓派IP>:/home/pi/huawei-printer-mcp/

scp huawei-printer-mcp-poke-files/huawei-printer-mcp-proxy.service \
  pi@<树莓派IP>:/home/pi/huawei-printer-mcp/

scp huawei-printer-mcp-poke-files/cleanup-uploads.sh \
  pi@<树莓派IP>:/home/pi/huawei-printer-mcp/

scp huawei-printer-mcp-poke-files/huawei-printer-upload-cleanup.service \
  pi@<树莓派IP>:/home/pi/huawei-printer-mcp/

scp huawei-printer-mcp-poke-files/huawei-printer-upload-cleanup.timer \
  pi@<树莓派IP>:/home/pi/huawei-printer-mcp/

给脚本执行权限:

chmod 755 /home/pi/huawei-printer-mcp/cleanup-uploads.sh

七、生成 MCP API Key
#

这个 Key 只用于 Poke 访问你的打印 MCP,不是 Poke API Key,也不是 Cloudflare Token。

openssl rand -hex 32 > /home/pi/huawei-printer-mcp/mcp-api-key
chmod 600 /home/pi/huawei-printer-mcp/mcp-api-key

查看 Key:

cat /home/pi/huawei-printer-mcp/mcp-api-key

稍后在 Poke 的 API Key 字段中只填写这串字符本身,不要加 Bearer 前缀。

八、安装 systemd 服务
#

安装两个 MCP 服务:

sudo install -o root -g root -m 0644 \
  /home/pi/huawei-printer-mcp/huawei-printer-mcp-upstream.service \
  /etc/systemd/system/huawei-printer-mcp-upstream.service

sudo install -o root -g root -m 0644 \
  /home/pi/huawei-printer-mcp/huawei-printer-mcp-proxy.service \
  /etc/systemd/system/huawei-printer-mcp-proxy.service

sudo systemctl daemon-reload
sudo systemctl enable --now huawei-printer-mcp-upstream.service
sudo systemctl enable --now huawei-printer-mcp-proxy.service

服务含义:

huawei-printer-mcp-upstream.service
  lan-mcp-cups,监听 127.0.0.1:3001

huawei-printer-mcp-proxy.service
  认证会话桥,监听 127.0.0.1:3000

检查:

systemctl is-enabled huawei-printer-mcp-upstream.service
systemctl is-active huawei-printer-mcp-upstream.service

systemctl is-enabled huawei-printer-mcp-proxy.service
systemctl is-active huawei-printer-mcp-proxy.service

ss -lntp | grep 3000
ss -lntp | grep 3001

查看日志:

journalctl -u huawei-printer-mcp-upstream.service -n 50 --no-pager
journalctl -u huawei-printer-mcp-proxy.service -n 50 --no-pager

huawei-printer-mcp-proxy.service 中的重要环境变量:

MCP_PROXY_API_KEY_FILE=/home/pi/huawei-printer-mcp/mcp-api-key
MCP_UPLOAD_DIR=/home/pi/huawei-printer-mcp/uploads
MCP_MAX_UPLOAD_BYTES=78643200
MCP_PRINTER_ALIAS=Huawei_PixLab
MCP_TARGET_PRINTER=HUAWEI_PixLab_V1_0374

78643200 字节等于 75 MiB。

九、配置 7 天自动清理上传文件
#

安装清理 service 和 timer:

sudo install -o root -g root -m 0644 \
  /home/pi/huawei-printer-mcp/huawei-printer-upload-cleanup.service \
  /etc/systemd/system/huawei-printer-upload-cleanup.service

sudo install -o root -g root -m 0644 \
  /home/pi/huawei-printer-mcp/huawei-printer-upload-cleanup.timer \
  /etc/systemd/system/huawei-printer-upload-cleanup.timer

sudo systemctl daemon-reload
sudo systemctl enable --now huawei-printer-upload-cleanup.timer

清理规则:

目录:/home/pi/huawei-printer-mcp/uploads
保留:7 天
频率:每天执行一次

先 dry-run:

sudo -u pi -H env \
  DRY_RUN=1 \
  MCP_UPLOAD_DIR=/home/pi/huawei-printer-mcp/uploads \
  MCP_UPLOAD_RETENTION_DAYS=7 \
  /home/pi/huawei-printer-mcp/cleanup-uploads.sh

查看 timer:

systemctl list-timers --all huawei-printer-upload-cleanup.timer --no-pager

立即手动执行一次清理:

sudo systemctl start huawei-printer-upload-cleanup.service

十、配置 Cloudflare Tunnel
#

在 Cloudflare Zero Trust 创建 Tunnel:

Zero Trust
→ Networks
→ Tunnels
→ Create a tunnel

在树莓派安装 cloudflared 后,按 Cloudflare 页面给出的命令安装服务。

Public hostname 示例:

Hostname: printer-mcp.example.com
Service Type: HTTP
Service URL: http://127.0.0.1:3000

注意:

  • Cloudflare 指向 127.0.0.1:3000
  • 不要指向 3001
  • 不要指向 CUPS 的 631
  • Poke 里填写 URL 时加 /mcp

检查:

systemctl status cloudflared --no-pager
curl -i https://printer-mcp.example.com/mcp

未带 API Key 时应返回:

HTTP 401 Unauthorized

十一、在 Poke 中添加 MCP
#

Poke 自定义集成里填写:

Name:
Huawei Printer

MCP Server URL:
https://printer-mcp.example.com/mcp

API Key:
< /home/pi/huawei-printer-mcp/mcp-api-key 的完整内容 >

API Key 不要写:

Bearer xxxxx

只写:

xxxxx

十二、Poke 可用工具
#

部署后,Poke 应看到这些工具:

list_printers
print_file
add_printer
upload_file
upload_and_print_file
print_url

建议使用:

print_url

当 Poke 能拿到附件下载链接时,让树莓派下载后打印。

也可使用:

upload_and_print_file

当 Poke 能把文件内容作为 base64 或纯文本传给 MCP 时,上传后立即打印。

只上传不打印:

upload_file

十三、工具调用示例
#

1. 只上传文本
#

{
  "name": "upload_file",
  "arguments": {
    "file_name": "note.txt",
    "content_text": "hello printer\n"
  }
}

2. 上传 base64 文件并打印
#

{
  "name": "upload_and_print_file",
  "arguments": {
    "file_name": "document.pdf",
    "content_base64": "<base64>",
    "printer": "Huawei_PixLab",
    "copies": 1,
    "options": "ColorModel=Gray PageSize=A4 MediaType=Stationery cupsPrintQuality=Normal sides=one-sided print-scaling=auto-fit"
  }
}

Huawei_PixLab 会被代理自动映射到:

HUAWEI_PixLab_V1_0374

3. 下载 URL 并打印
#

{
  "name": "print_url",
  "arguments": {
    "url": "https://example.com/file.pdf",
    "file_name": "file.pdf",
    "printer": "Huawei_PixLab",
    "copies": 1,
    "options": "ColorModel=Gray PageSize=A4 sides=one-sided"
  }
}

安全限制:

  • 只支持 http / https
  • 默认拒绝下载 localhost 和内网地址;
  • 单文件最大 75 MiB;
  • 上传文件保留 7 天后自动删除。

十四、验证命令
#

无 API Key 必须被拒绝
#

curl -i https://printer-mcp.example.com/mcp

预期:

HTTP/2 401
www-authenticate: Bearer

带 API Key 初始化
#

MCP_KEY="$(cat /home/pi/huawei-printer-mcp/mcp-api-key)"

curl -i \
  -X POST https://printer-mcp.example.com/mcp \
  -H "Authorization: Bearer $MCP_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  --data-raw '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"initialize",
    "params":{
      "protocolVersion":"2025-03-26",
      "capabilities":{},
      "clientInfo":{"name":"manual-test","version":"1.0.0"}
    }
  }'

响应头应包含:

mcp-session-id: ...

十五、常见问题
#

1. spawn lpr ENOENT
#

原因:未安装 cups-bsd,系统没有 lpr

修复:

sudo apt install -y cups-bsd
command -v lpr

2. lpr: unable to access "127.0.0.1"
#

原因:给 lan-mcp-cups 设置了 MCP_CUPS_SERVER=127.0.0.1,它会给 lpr-h 127.0.0.1,导致 127.0.0.1 被当成文件名。

修复:本机 CUPS 场景不要设置:

MCP_CUPS_SERVER
MCP_CUPS_PORT

只保留:

MCP_CUPS_DEFAULT_PRINTER
MCP_CUPS_HTTP_HOST
MCP_CUPS_HTTP_PORT

3. Invalid Request: Server already initialized
#

原因:lan-mcp-cups 的 HTTP transport 对重复初始化不友好。Poke 或代理重试时会触发。

修复:使用本文的 mcp-compat-proxy.mjs 会话桥。它对 Poke 暴露多个客户端 session,对上游复用单个 session。

4. 打印出白纸或打印机端取消任务
#

优先检查队列驱动:

grep -Ei 'NickName|ModelName' /etc/cups/ppd/<队列名>.ppd

建议使用类似:

HUAWEI PixLab V1, driverless, cups-filters

避免使用泛化:

Printer - IPP Everywhere

同时确认打印选项使用队列支持的名称:

ColorModel=Gray
PageSize=A4
MediaType=Stationery
cupsPrintQuality=Normal
sides=one-sided
print-scaling=auto-fit

5. Poke 显示工具为空
#

检查:

journalctl -u huawei-printer-mcp-proxy.service -n 100 --no-pager
journalctl -u huawei-printer-mcp-upstream.service -n 100 --no-pager

确认公网带 API Key 能看到工具:

MCP_KEY="$(cat /home/pi/huawei-printer-mcp/mcp-api-key)"
curl -i https://printer-mcp.example.com/mcp \
  -H "Authorization: Bearer $MCP_KEY"

如果 Poke 缓存了旧工具列表,删除后重新添加集成,或在 Poke 中刷新连接。

十六、维护命令
#

重启 MCP:

sudo systemctl restart huawei-printer-mcp-upstream.service huawei-printer-mcp-proxy.service

看状态:

systemctl status huawei-printer-mcp-upstream.service --no-pager
systemctl status huawei-printer-mcp-proxy.service --no-pager

看上传文件:

ls -lh /home/pi/huawei-printer-mcp/uploads

调整上传大小,例如 100 MiB:

sudo systemctl edit huawei-printer-mcp-proxy.service

填入:

[Service]
Environment=MCP_MAX_UPLOAD_BYTES=104857600

然后:

sudo systemctl daemon-reload
sudo systemctl restart huawei-printer-mcp-proxy.service

调整保留天数,例如 14 天:

sudo systemctl edit huawei-printer-upload-cleanup.service

填入:

[Service]
Environment=MCP_UPLOAD_RETENTION_DAYS=14

然后:

sudo systemctl daemon-reload
sudo systemctl restart huawei-printer-upload-cleanup.timer

十七、安全建议
#

  • API Key 只给 Poke 使用;
  • 不要把 /home/pi/huawei-printer-mcp/mcp-api-key 发给其他人;
  • Cloudflare Tunnel 只转发到 127.0.0.1:3000
  • 不要把 CUPS 631 暴露到公网;
  • 定期查看上传目录大小:
du -sh /home/pi/huawei-printer-mcp/uploads
  • 对多人使用的 Poke 集成,建议限制默认份数,并在 Poke 规则里要求超过 10 页或超过 1 份时先确认。

评论将在滚动到此处时加载。