↓ 跳过正文

Huawei PixLab + Raspberry Pi + Poke MCP Printing Deployment Guide

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

This guide is for users who want to connect a local-network printer to Poke. The goal is to:

  • connect a Huawei PixLab printer on the local network to a Raspberry Pi;

  • manage the print queue through CUPS;

  • expose printing capabilities to Poke through MCP;

  • let Poke upload files to the Raspberry Pi and print them;

  • protect the public endpoint with a Bearer API key; and

  • automatically delete uploaded files after seven days.

This guide uses a Huawei PixLab V1 as an example. Other printers that support AirPrint, IPP, or driverless printing can follow the same approach.

1. Final Architecture
#

Poke
  │  HTTPS + Authorization: Bearer <MCP_API_KEY>
  ↓
Cloudflare Tunnel
  ↓
Raspberry Pi 127.0.0.1:3000
  ↓
mcp-compat-proxy.mjs
  ├─ Authentication
  ├─ Poke-compatible MCP sessions
  ├─ File upload tools
  ├─ print_url download tool
  └─ Printer alias and option normalization
  ↓
Raspberry Pi 127.0.0.1:3001
  ↓
lan-mcp-cups
  ↓
CUPS
  ↓
Huawei PixLab driverless queue

Do not expose CUPS port 631 directly to the public internet. Expose only the authenticated MCP endpoint.

2. Included Files
#

The accompanying files are included with this site. Download them from the following paths, or create files with the same names manually on the deployment machine:

/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

When copying these files to the Raspberry Pi, the default installation directory is:

/home/pi/huawei-printer-mcp/

If your username is not pi, replace every /home/pi in the examples and the User=pi and Group=pi values in the systemd units with your actual username.

3. Prerequisites
#

The Raspberry Pi needs:

  • Debian or Raspberry Pi OS;

  • to be on the same local network as the printer;

  • SSH installed and enabled;

  • internet access for Cloudflare Tunnel and npm installation; and

  • a domain that can be used with Cloudflare Tunnel.

Install the base packages:

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

Notes:

  • cups and cups-client: the CUPS printing system;

  • cups-bsd: provides lpr, which lan-mcp-cups uses for print_file;

  • cups-browsed and cups-filters: provide driverless and auto-discovered queues; and

  • avahi-daemon: discovers .local, Bonjour, and AirPrint devices.

Enable CUPS:

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

To manage CUPS in a browser:

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

Open:

https://<Raspberry-Pi-IP>:631

4. Install Node.js and lan-mcp-cups
#

Verify Node.js:

node -v
npm -v

Node.js 20 or later is recommended.

Install lan-mcp-cups:

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

The output should resemble:

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

5. Configure the CUPS Print Queue
#

First, inspect auto-discovered printers:

lpstat -p -d
lpstat -v
lpoptions -p <printer-name> -l

A typical auto-discovered Huawei PixLab queue looks like this:

HUAWEI_PixLab_V1_0374

Prefer this driverless auto-discovered queue over a manually created generic Printer - IPP Everywhere queue. The latter can produce blank pages or printer-side job cancellation for some PDF or image jobs.

Check the queue driver:

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

The ideal output includes:

HUAWEI PixLab V1, driverless, cups-filters

Set the default printer:

sudo lpadmin -d HUAWEI_PixLab_V1_0374
lpoptions -d HUAWEI_PixLab_V1_0374

Set common default options:

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

Verify the queue:

lpstat -p -d
lpoptions -p HUAWEI_PixLab_V1_0374

6. Deploy the MCP Files
#

Create the directory:

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

Copy the accompanying files to the Raspberry Pi:

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

scp huawei-printer-mcp-poke-files/huawei-printer-mcp-upstream.service \
  pi@<Raspberry-Pi-IP>:/home/pi/huawei-printer-mcp/

scp huawei-printer-mcp-poke-files/huawei-printer-mcp-proxy.service \
  pi@<Raspberry-Pi-IP>:/home/pi/huawei-printer-mcp/

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

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

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

Make the script executable:

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

7. Generate an MCP API Key
#

This key is only for Poke to access your printing MCP. It is neither a Poke API key nor a Cloudflare token.

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

View the key:

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

Later, enter only the character string itself in Poke’s API Key field. Do not prepend Bearer .

8. Install the systemd Services
#

Install the two MCP services:

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

The services are:

huawei-printer-mcp-upstream.service
  lan-mcp-cups, listening on 127.0.0.1:3001

huawei-printer-mcp-proxy.service
  Authenticated session bridge, listening on 127.0.0.1:3000

Check them:

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

View logs:

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

Important environment variables in 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 bytes equals 75 MiB.

9. Automatically Clean Uploaded Files After Seven Days
#

Install the cleanup service and 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

The cleanup policy is:

Directory: /home/pi/huawei-printer-mcp/uploads
Retention: 7 days
Frequency: once per day

Run a dry run first:

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

View the timer:

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

Run cleanup manually now:

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

10. Configure Cloudflare Tunnel
#

Create a tunnel in Cloudflare Zero Trust:

Zero Trust
→ Networks
→ Tunnels
→ Create a tunnel

After installing cloudflared on the Raspberry Pi, install the service using the command provided by the Cloudflare page.

Example public hostname:

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

Notes:

  • Cloudflare points to 127.0.0.1:3000;

  • do not point it to 3001;

  • do not point it to CUPS port 631; and

  • add /mcp when entering the URL in Poke.

Check:

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

Without an API key, it should return:

HTTP 401 Unauthorized

11. Add the MCP Server in Poke
#

Fill in Poke’s custom integration as follows:

Name:
Huawei Printer

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

API Key:
<the complete contents of /home/pi/huawei-printer-mcp/mcp-api-key>

Do not enter:

Bearer xxxxx

Enter only:

xxxxx

12. Tools Available in Poke
#

After deployment, Poke should show these tools:

list_printers
print_file
add_printer
upload_file
upload_and_print_file
print_url

Recommended:

print_url

When Poke can obtain an attachment download URL, let the Raspberry Pi download and print it.

You can also use:

upload_and_print_file

When Poke can send file contents to MCP as base64 or plain text, this uploads and prints the file immediately.

To upload without printing:

upload_file

13. Tool Call Examples
#

1. Upload Text Only
#

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

2. Upload a Base64 File and Print It
#

{
  "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"
  }
}

The proxy automatically maps Huawei_PixLab to:

HUAWEI_PixLab_V1_0374

3. Download a URL and Print It
#

{
  "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"
  }
}

Security limits:

  • only http and https are supported;

  • localhost and private-network addresses are rejected by default;

  • the maximum file size is 75 MiB; and

  • uploaded files are deleted automatically after seven days.

14. Verification Commands
#

Requests Without an API Key Must Be Rejected
#

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

Expected:

HTTP/2 401
www-authenticate: Bearer

Initialize With an 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"}
    }
  }'

The response headers should include:

mcp-session-id: ...

15. Common Issues
#

1. spawn lpr ENOENT
#

Cause: cups-bsd is not installed, so the system does not have lpr.

Fix:

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

2. lpr: unable to access "127.0.0.1"
#

Cause: MCP_CUPS_SERVER=127.0.0.1 was set for lan-mcp-cups. It adds -h 127.0.0.1 to lpr, causing 127.0.0.1 to be treated as a file name.

Fix: do not set these for a local CUPS installation:

MCP_CUPS_SERVER
MCP_CUPS_PORT

Keep only:

MCP_CUPS_DEFAULT_PRINTER
MCP_CUPS_HTTP_HOST
MCP_CUPS_HTTP_PORT

3. Invalid Request: Server already initialized
#

Cause: the HTTP transport in lan-mcp-cups does not handle repeated initialization well. This can be triggered when Poke or the proxy retries.

Fix: use the mcp-compat-proxy.mjs session bridge from this guide. It exposes multiple client sessions to Poke while reusing a single upstream session.

4. Blank Pages or Printer-Side Job Cancellation
#

First check the queue driver:

grep -Ei 'NickName|ModelName' /etc/cups/ppd/<queue-name>.ppd

Use a driver that resembles:

HUAWEI PixLab V1, driverless, cups-filters

Avoid the generic queue:

Printer - IPP Everywhere

Also ensure the print options use names supported by the queue:

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

5. Poke Shows No Tools
#

Check:

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

Confirm the public endpoint can show tools with an 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"

If Poke has cached an old tool list, remove and add the integration again, or refresh the connection in Poke.

16. Maintenance Commands
#

Restart MCP:

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

View status:

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

View uploaded files:

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

Adjust the upload size, for example to 100 MiB:

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

Enter:

[Service]
Environment=MCP_MAX_UPLOAD_BYTES=104857600

Then:

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

Adjust the retention period, for example to 14 days:

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

Enter:

[Service]
Environment=MCP_UPLOAD_RETENTION_DAYS=14

Then:

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

17. Security Recommendations
#

  • Give the API key only to Poke.

  • Do not share /home/pi/huawei-printer-mcp/mcp-api-key with anyone.

  • Have Cloudflare Tunnel forward only to 127.0.0.1:3000.

  • Do not expose CUPS port 631 to the public internet.

  • Regularly check the upload directory size:

du -sh /home/pi/huawei-printer-mcp/uploads
  • For a Poke integration shared by multiple people, limit the default copy count. In Poke rules, require confirmation for jobs longer than 10 pages or with more than one copy.

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