[{"content":"","date":"July 16, 2026","externalUrl":null,"permalink":"/en/tags/cups/","section":"Tags","summary":"","title":"CUPS","type":"tags"},{"content":"","date":"July 16, 2026","externalUrl":null,"permalink":"/en/tags/huawei-pixlab/","section":"Tags","summary":"","title":"Huawei PixLab","type":"tags"},{"content":"This guide is for users who want to connect a local-network printer to Poke. The goal is to:\nconnect 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.\n1. Final Architecture # Poke │ HTTPS + Authorization: Bearer \u0026lt;MCP_API_KEY\u0026gt; ↓ 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.\n2. 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:\n/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:\n/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.\n3. Prerequisites # The Raspberry Pi needs:\nDebian 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:\nsudo apt update sudo apt install -y \\ cups cups-client cups-bsd \\ cups-browsed cups-filters avahi-daemon \\ curl openssl Notes:\ncups 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:\nsudo systemctl enable --now cups sudo systemctl enable --now cups-browsed sudo systemctl enable --now avahi-daemon To manage CUPS in a browser:\nsudo cupsctl --remote-any --remote-admin --share-printers sudo usermod -aG lpadmin \u0026#34;$USER\u0026#34; sudo systemctl restart cups Open:\nhttps://\u0026lt;Raspberry-Pi-IP\u0026gt;:631 4. Install Node.js and lan-mcp-cups # Verify Node.js:\nnode -v npm -v Node.js 20 or later is recommended.\nInstall lan-mcp-cups:\nsudo npm install -g lan-mcp-cups command -v lan-mcp-cups The output should resemble:\n/usr/local/bin/lan-mcp-cups 5. Configure the CUPS Print Queue # First, inspect auto-discovered printers:\nlpstat -p -d lpstat -v lpoptions -p \u0026lt;printer-name\u0026gt; -l A typical auto-discovered Huawei PixLab queue looks like this:\nHUAWEI_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.\nCheck the queue driver:\ngrep -Ei \u0026#39;NickName|ModelName\u0026#39; /etc/cups/ppd/HUAWEI_PixLab_V1_0374.ppd The ideal output includes:\nHUAWEI PixLab V1, driverless, cups-filters Set the default printer:\nsudo lpadmin -d HUAWEI_PixLab_V1_0374 lpoptions -d HUAWEI_PixLab_V1_0374 Set common default options:\nsudo 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:\nlpstat -p -d lpoptions -p HUAWEI_PixLab_V1_0374 6. Deploy the MCP Files # Create the directory:\nmkdir -p /home/pi/huawei-printer-mcp/uploads chmod 700 /home/pi/huawei-printer-mcp/uploads Copy the accompanying files to the Raspberry Pi:\nscp huawei-printer-mcp-poke-files/mcp-compat-proxy.mjs \\ pi@\u0026lt;Raspberry-Pi-IP\u0026gt;:/home/pi/huawei-printer-mcp/ scp huawei-printer-mcp-poke-files/huawei-printer-mcp-upstream.service \\ pi@\u0026lt;Raspberry-Pi-IP\u0026gt;:/home/pi/huawei-printer-mcp/ scp huawei-printer-mcp-poke-files/huawei-printer-mcp-proxy.service \\ pi@\u0026lt;Raspberry-Pi-IP\u0026gt;:/home/pi/huawei-printer-mcp/ scp huawei-printer-mcp-poke-files/cleanup-uploads.sh \\ pi@\u0026lt;Raspberry-Pi-IP\u0026gt;:/home/pi/huawei-printer-mcp/ scp huawei-printer-mcp-poke-files/huawei-printer-upload-cleanup.service \\ pi@\u0026lt;Raspberry-Pi-IP\u0026gt;:/home/pi/huawei-printer-mcp/ scp huawei-printer-mcp-poke-files/huawei-printer-upload-cleanup.timer \\ pi@\u0026lt;Raspberry-Pi-IP\u0026gt;:/home/pi/huawei-printer-mcp/ Make the script executable:\nchmod 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.\nopenssl rand -hex 32 \u0026gt; /home/pi/huawei-printer-mcp/mcp-api-key chmod 600 /home/pi/huawei-printer-mcp/mcp-api-key View the key:\ncat /home/pi/huawei-printer-mcp/mcp-api-key Later, enter only the character string itself in Poke\u0026rsquo;s API Key field. Do not prepend Bearer .\n8. Install the systemd Services # Install the two MCP services:\nsudo 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:\nhuawei-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:\nsystemctl 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:\njournalctl -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:\nMCP_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.\n9. Automatically Clean Uploaded Files After Seven Days # Install the cleanup service and timer:\nsudo 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:\nDirectory: /home/pi/huawei-printer-mcp/uploads Retention: 7 days Frequency: once per day Run a dry run first:\nsudo -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:\nsystemctl list-timers --all huawei-printer-upload-cleanup.timer --no-pager Run cleanup manually now:\nsudo systemctl start huawei-printer-upload-cleanup.service 10. Configure Cloudflare Tunnel # Create a tunnel in Cloudflare Zero Trust:\nZero Trust → Networks → Tunnels → Create a tunnel After installing cloudflared on the Raspberry Pi, install the service using the command provided by the Cloudflare page.\nExample public hostname:\nHostname: printer-mcp.example.com Service Type: HTTP Service URL: http://127.0.0.1:3000 Notes:\nCloudflare 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:\nsystemctl status cloudflared --no-pager curl -i https://printer-mcp.example.com/mcp Without an API key, it should return:\nHTTP 401 Unauthorized 11. Add the MCP Server in Poke # Fill in Poke\u0026rsquo;s custom integration as follows:\nName: Huawei Printer MCP Server URL: https://printer-mcp.example.com/mcp API Key: \u0026lt;the complete contents of /home/pi/huawei-printer-mcp/mcp-api-key\u0026gt; Do not enter:\nBearer xxxxx Enter only:\nxxxxx 12. Tools Available in Poke # After deployment, Poke should show these tools:\nlist_printers print_file add_printer upload_file upload_and_print_file print_url Recommended:\nprint_url When Poke can obtain an attachment download URL, let the Raspberry Pi download and print it.\nYou can also use:\nupload_and_print_file When Poke can send file contents to MCP as base64 or plain text, this uploads and prints the file immediately.\nTo upload without printing:\nupload_file 13. Tool Call Examples # 1. Upload Text Only # { \u0026#34;name\u0026#34;: \u0026#34;upload_file\u0026#34;, \u0026#34;arguments\u0026#34;: { \u0026#34;file_name\u0026#34;: \u0026#34;note.txt\u0026#34;, \u0026#34;content_text\u0026#34;: \u0026#34;hello printer\\n\u0026#34; } } 2. Upload a Base64 File and Print It # { \u0026#34;name\u0026#34;: \u0026#34;upload_and_print_file\u0026#34;, \u0026#34;arguments\u0026#34;: { \u0026#34;file_name\u0026#34;: \u0026#34;document.pdf\u0026#34;, \u0026#34;content_base64\u0026#34;: \u0026#34;\u0026lt;base64\u0026gt;\u0026#34;, \u0026#34;printer\u0026#34;: \u0026#34;Huawei_PixLab\u0026#34;, \u0026#34;copies\u0026#34;: 1, \u0026#34;options\u0026#34;: \u0026#34;ColorModel=Gray PageSize=A4 MediaType=Stationery cupsPrintQuality=Normal sides=one-sided print-scaling=auto-fit\u0026#34; } } The proxy automatically maps Huawei_PixLab to:\nHUAWEI_PixLab_V1_0374 3. Download a URL and Print It # { \u0026#34;name\u0026#34;: \u0026#34;print_url\u0026#34;, \u0026#34;arguments\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;https://example.com/file.pdf\u0026#34;, \u0026#34;file_name\u0026#34;: \u0026#34;file.pdf\u0026#34;, \u0026#34;printer\u0026#34;: \u0026#34;Huawei_PixLab\u0026#34;, \u0026#34;copies\u0026#34;: 1, \u0026#34;options\u0026#34;: \u0026#34;ColorModel=Gray PageSize=A4 sides=one-sided\u0026#34; } } Security limits:\nonly 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:\nHTTP/2 401 www-authenticate: Bearer Initialize With an API Key # MCP_KEY=\u0026#34;$(cat /home/pi/huawei-printer-mcp/mcp-api-key)\u0026#34; curl -i \\ -X POST https://printer-mcp.example.com/mcp \\ -H \u0026#34;Authorization: Bearer $MCP_KEY\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -H \u0026#34;Accept: application/json, text/event-stream\u0026#34; \\ --data-raw \u0026#39;{ \u0026#34;jsonrpc\u0026#34;:\u0026#34;2.0\u0026#34;, \u0026#34;id\u0026#34;:1, \u0026#34;method\u0026#34;:\u0026#34;initialize\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;protocolVersion\u0026#34;:\u0026#34;2025-03-26\u0026#34;, \u0026#34;capabilities\u0026#34;:{}, \u0026#34;clientInfo\u0026#34;:{\u0026#34;name\u0026#34;:\u0026#34;manual-test\u0026#34;,\u0026#34;version\u0026#34;:\u0026#34;1.0.0\u0026#34;} } }\u0026#39; The response headers should include:\nmcp-session-id: ... 15. Common Issues # 1. spawn lpr ENOENT # Cause: cups-bsd is not installed, so the system does not have lpr.\nFix:\nsudo apt install -y cups-bsd command -v lpr 2. lpr: unable to access \u0026quot;127.0.0.1\u0026quot; # 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.\nFix: do not set these for a local CUPS installation:\nMCP_CUPS_SERVER MCP_CUPS_PORT Keep only:\nMCP_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.\nFix: use the mcp-compat-proxy.mjs session bridge from this guide. It exposes multiple client sessions to Poke while reusing a single upstream session.\n4. Blank Pages or Printer-Side Job Cancellation # First check the queue driver:\ngrep -Ei \u0026#39;NickName|ModelName\u0026#39; /etc/cups/ppd/\u0026lt;queue-name\u0026gt;.ppd Use a driver that resembles:\nHUAWEI PixLab V1, driverless, cups-filters Avoid the generic queue:\nPrinter - IPP Everywhere Also ensure the print options use names supported by the queue:\nColorModel=Gray PageSize=A4 MediaType=Stationery cupsPrintQuality=Normal sides=one-sided print-scaling=auto-fit 5. Poke Shows No Tools # Check:\njournalctl -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:\nMCP_KEY=\u0026#34;$(cat /home/pi/huawei-printer-mcp/mcp-api-key)\u0026#34; curl -i https://printer-mcp.example.com/mcp \\ -H \u0026#34;Authorization: Bearer $MCP_KEY\u0026#34; If Poke has cached an old tool list, remove and add the integration again, or refresh the connection in Poke.\n16. Maintenance Commands # Restart MCP:\nsudo systemctl restart huawei-printer-mcp-upstream.service huawei-printer-mcp-proxy.service View status:\nsystemctl status huawei-printer-mcp-upstream.service --no-pager systemctl status huawei-printer-mcp-proxy.service --no-pager View uploaded files:\nls -lh /home/pi/huawei-printer-mcp/uploads Adjust the upload size, for example to 100 MiB:\nsudo systemctl edit huawei-printer-mcp-proxy.service Enter:\n[Service] Environment=MCP_MAX_UPLOAD_BYTES=104857600 Then:\nsudo systemctl daemon-reload sudo systemctl restart huawei-printer-mcp-proxy.service Adjust the retention period, for example to 14 days:\nsudo systemctl edit huawei-printer-upload-cleanup.service Enter:\n[Service] Environment=MCP_UPLOAD_RETENTION_DAYS=14 Then:\nsudo 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. ","date":"July 16, 2026","externalUrl":null,"permalink":"/en/posts/huawei-pixlab-poke-mcp/","section":"Posts","summary":"","title":"Huawei PixLab + Raspberry Pi + Poke MCP Printing Deployment Guide","type":"posts"},{"content":"","date":"July 16, 2026","externalUrl":null,"permalink":"/en/tags/mcp/","section":"Tags","summary":"","title":"MCP","type":"tags"},{"content":"","date":"July 16, 2026","externalUrl":null,"permalink":"/en/tags/poke/","section":"Tags","summary":"","title":"Poke","type":"tags"},{"content":"","date":"July 16, 2026","externalUrl":null,"permalink":"/en/tags/printing/","section":"Tags","summary":"","title":"Printing","type":"tags"},{"content":"","date":"July 16, 2026","externalUrl":null,"permalink":"/en/tags/raspberry-pi/","section":"Tags","summary":"","title":"Raspberry Pi","type":"tags"},{"content":"","date":"July 16, 2026","externalUrl":null,"permalink":"/en/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":" Hello # This is a personal blog for notes on technology, AI, and life.\n","date":"January 2, 2026","externalUrl":null,"permalink":"/en/about/","section":"Afterglow Sampling","summary":"","title":"About","type":"page"},{"content":" ","date":"January 2, 2026","externalUrl":null,"permalink":"/en/subscribe/","section":"Afterglow Sampling","summary":"","title":"Subscribe","type":"page"},{"content":"","externalUrl":null,"permalink":"/en/","section":"Afterglow Sampling","summary":"","title":"Afterglow Sampling","type":"page"},{"content":"","externalUrl":null,"permalink":"/en/archives/","section":"Afterglow Sampling","summary":"","title":"Archives","type":"page"},{"content":"","externalUrl":null,"permalink":"/en/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/en/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/en/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":" Search posts in this language ","externalUrl":null,"permalink":"/en/search/","section":"Afterglow Sampling","summary":"Site search","title":"Search","type":"page"},{"content":"","externalUrl":null,"permalink":"/en/series/","section":"Series","summary":"","title":"Series","type":"series"}]