mcpField
P
pixoo-mcp-server

pixoo-mcp-server

本地服务
github.com/cyanheads媒体与设计104 天前更新

关于 pixoo-mcp-server

pixoo-mcp-server 通过本地网络将文本、场景、图像、HTML 和动画发送到 Divoom Pixoo LED 显示屏,也可读取和调整设备状态,适合构建像素画与小型仪表盘。

主要功能

  1. 01渲染主题化文本与动画
  2. 02组合分层场景和图形
  3. 03推送图像及动画文件
  4. 04将 HTML 页面渲染到屏幕
  5. 05读取并控制显示设备状态

适用场景

  1. 01在 Pixoo 屏幕显示实时风格化信息
  2. 02制作像素风仪表盘与动画
  3. 03调整亮度、频道和屏幕状态

MCP 相关

提供 8 个工具和 4 个资源,通过 STDIO 或 Streamable HTTP 供 MCP 客户端使用。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"cyanheads-pixoo": {
"command": "npx",
"args": [
"-y",
"@cyanheads/pixoo-mcp-server"
],
"env": {
"PIXOO_IP": "<PIXOO_IP>",
"PIXOO_SIZE": "<PIXOO_SIZE>",
"PIXOO_OUTPUT_DIR": "<PIXOO_OUTPUT_DIR>",
"PIXOO_PUSH_MIN_INTERVAL_MS": "<PIXOO_PUSH_MIN_INTERVAL_MS>",
"PIXOO_SERVE_HOST": "<PIXOO_SERVE_HOST>",
"PIXOO_SERVE_PORT": "<PIXOO_SERVE_PORT>",
"PIXOO_BROWSER_PATH": "<PIXOO_BROWSER_PATH>",
"PIXOO_HTML_ENABLED": "<PIXOO_HTML_ENABLED>",
"MCP_LOG_LEVEL": "<MCP_LOG_LEVEL>",
"MCP_TRANSPORT_TYPE": "<MCP_TRANSPORT_TYPE>",
"MCP_HTTP_HOST": "<MCP_HTTP_HOST>",
"MCP_HTTP_PORT": "<MCP_HTTP_PORT>",
"MCP_HTTP_ENDPOINT_PATH": "<MCP_HTTP_ENDPOINT_PATH>",
"MCP_AUTH_MODE": "<MCP_AUTH_MODE>"
}
}
}
}
启动命令npx -y @cyanheads/pixoo-mcp-server
需要配置的环境变量
PIXOO_IPDevice IP address on the local network (e.g. 192.168.1.50). Required for device tools; discovery and pure-render (push: false) work without it.
PIXOO_SIZEDisplay size in pixels: 16, 32, or 64. Must match the physical device.
PIXOO_OUTPUT_DIRDirectory for auto-saving preview PNG and GIF files. When unset, previews are returned in-response only.
PIXOO_PUSH_MIN_INTERVAL_MSMinimum interval between device pushes in milliseconds. Prevents device freeze from rapid-fire commands.
PIXOO_SERVE_HOSTHost advertised in the URL the device downloads an animation of more than 40 frames from, for NAT or a DNS name. When unset, the local address the OS routes to PIXOO_IP; the listener binds that address either way.
PIXOO_SERVE_PORTFixed port for the listener the device downloads an animation of more than 40 frames from, for firewall rules. When unset, a free port.
PIXOO_BROWSER_PATHBrowser executable for HTML rendering, such as the chrome-headless-shell that `npx @puppeteer/browsers install chrome-headless-shell@stable --path <dir>` installs. When set, the only browser tried: a path that is not an executable file fails rather than falling back. When unset, the newest chrome-headless-shell in Puppeteer's cache (~/.cache/puppeteer).
PIXOO_HTML_ENABLEDOffer pixoo_render_html. false (or 0, no, off) disables it, removing it from tools/list; unset or true keeps it. A value that is not one of those boolean spellings fails startup.
MCP_LOG_LEVELSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_TRANSPORT_TYPESelects the HTTP transport.
MCP_HTTP_HOSTThe hostname for the HTTP server.
MCP_HTTP_PORTThe port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHThe endpoint path for the MCP server.
MCP_AUTH_MODE密钥Authentication mode to use: 'none', 'jwt', or 'oauth'.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@cyanheads/pixoo-mcp-server1.4.1

工具

8

收录的工具列表 · 更新于 4 天前

参数类型必填说明
fontenum否字体变体,按指定值使用;文本过宽时会溢出,不会切换字体:standard(5×7)或 compact(3×5),两者均支持可打印 ASCII 字符及 ° ← ↑ → ↓ ▲ ▼ ♥ · …;或 numerals(用于时钟和读数的 11×18 数字),仅绘制 0–9、空格及 : . - + / % ° ?,因此文本包含其他字符时会被拒绝。省略此参数时,单行文本先尝试 standard,若溢出则回退到 compact;多行文本使用 standard。standard | compact | numerals
pushboolean否将渲染后的帧推送到设备(默认值:true)。
textany是要显示的文本。字符串或行数组。
alignenum否多行文本:将每行在最宽行的范围内对齐,然后使用 position.x 放置整个文本块。省略时,使用各自的 position.x 单独放置每一行。left | center | right
styleobject否文本样式:调色板、阴影、描边、缩放。
style.colorstring否不使用调色板时的纯色。
style.scaleinteger否整数像素缩放倍数(1 = 正常,2 = 粗块状字体)。
style.shadowboolean否文本后方的投影。
style.outlineboolean否提升可读性的 1px 对比色描边。
style.paletteany否用于垂直色阶的命名调色板或自定义渐变色标。
themeenum否命名场景主题 — 设置背景渐变和默认文本调色板。midnight | ember | claude | ice | neon | forest | mono
effectenum否动画效果。scroll 会让文本在最多 40 帧内横穿显示屏一次;auto 仅在文本宽度超出显示范围时滚动;float(轻柔浮动)和 pulse(亮度呼吸)会循环播放 20 帧。动画结果会作为动画推送,并以帧网格预览。none 或省略时会渲染一个静态帧。none | auto | scroll | float | pulse
positionobject否文本在显示屏上的位置。
position.xany否X 位置或对齐方式(默认:居中)。
position.yany否Y 位置或对齐方式(默认:居中)。
backgroundany否背景颜色或渐变。设置后会覆盖主题背景。
brightnessinteger否推送前设置设备亮度(0–100)。失败时仅发出警告,不视为错误。

详细介绍

@cyanheads/pixoo-mcp-server

通过 MCP 在本地网络上,将风格化像素艺术、文本、仪表板和动画渲染并推送到 Divoom Pixoo LED 显示屏。支持 STDIO 或 Streamable HTTP。

8 个工具 • 4 个资源

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


概述

可在本地网络上使用 Divoom Pixoo LED 矩阵显示屏,主要面向 Pixoo-64,也支持 16 和 32 型号。渲染并推送风格化文本、分层场景、仪表板、动画和 HTML 页面,也可读取和更改设备状态。

工具
工具描述
pixoo_display_text使用主题、渐变、阴影和自动适配功能渲染风格化文本,支持静态或动态效果并推送
pixoo_compose_scene合成由文本、图标、小组件、形状、位图、图像和精灵组成的分层场景,支持静态或动态效果
pixoo_push_image将本地或 https 图像缩放至 LED 网格并推送;也可将动态 GIF 或 WebP 作为动画推送
pixoo_render_html在无头浏览器中以面板尺寸渲染 HTML 页面(CSS、SVG、Canvas、WebGL),支持静态显示或基于虚拟时钟逐帧播放动画并推送
pixoo_overlay_text设置或清除由设备渲染的滚动文本叠加层
pixoo_control_device读取或更改亮度、屏幕状态、频道或时钟表盘
pixoo_discover_devices通过 Divoom 的云端发现功能查找 Pixoo 设备及其局域网 IP
pixoo_design_brief为设计主题提供指导,包含实时设备状态和预先填充的后续调用
资源
资源描述
pixoo://device/status实时设备快照:可访问性、频道、亮度、屏幕状态、显示尺寸
pixoo://reference/themes主题和调色板注册表
pixoo://reference/icons按类别划分的内置图标名称
pixoo://reference/design-guide面向 64px 显示屏的详细设计指南

仅支持工具的客户端可使用工具覆盖相同内容:pixoo_control_device 读取实时设备状态,pixoo_design_brief 返回设计指南、主题名称和图标名称。

功能参考

pixoo_display_text 工具
  • text 可以是字符串或多行数组;theme(midnight、ember、claude、ice、neon、forest、mono)用于设置背景和默认调色板。style 可采用 palette 色阶(ember、ice、neon、fire、lavender、claude、mono),也可采用自定义的 { from, to },并支持 shadow、outline 和 1–8 的 scale;position 可使用语义位置或像素位置,align 用于对齐多行文本
  • font:standard(5×7)和 compact(3×5)可绘制可打印 ASCII 字符以及 ° ← ↑ → ↓ ▲ ▼ ♥ · …;其他任何字符(€、’、单个字符串中的换行符)都会显示为 ?,并在响应的 notice 中注明其码点和行索引;numerals 是用于时钟和读数的 11×18 数字字体,可绘制 0–9、空格以及 : . - + / % ° ?,文本中包含其他任何字符都会导致验证失败,并列出这些字符
  • layout[] 会通过 action 报告每项适配决策(文本仅在紧凑字体下适配时为 shrunk-to-compact,返回帧滚动时为 scrolling,其他情况为 none),还会报告所用的 font,以及每行文本框是否适合面板(fits);单行文本过宽时会从 x 0 开始,并在不滚动时于右边缘截断。除非设置了 font,单行文本会从标准字体回退到紧凑字体——不会回退到 numerals——只有在 effect: "auto" 或 "scroll" 时,仍然过宽的文本才会滚动
  • effect:scroll 会在最多 40 帧中滚动一次,auto 仅在溢出时滚动,float 和 pulse 会循环播放 20 帧;frames 报告帧数,动画会作为一次设备动画推送
pixoo_compose_scene 工具
  • 最多可绘制 50 个 elements,按从后到前的顺序排列:text(使用与 pixoo_display_text 相同的三种字体)、icon、rect、circle、line、progress、sparkline、bitmap、pixels、image(绝对路径或 https URL,并使用与 pixoo_push_image 相同的 finish)、sprite(绝对路径)。background 可以是纯色、v / h / r 渐变,或 theme
  • 每个元素都接受 opacity(每个像素以自身 alpha × opacity 的值呈现,因此柔和边缘会均匀淡出)和 blend:normal、add(发光和光束)、screen 或 multiply。line 和描边圆形接受 strokeWidth 和 antialias;rect 边框接受 strokeWidth,并向内扩展。在不绘制描边的图形上使用任一字段都会导致验证失败,并指出字段名称
  • 返回 layout[]:每个元素放置后的边界框(对于宽描边或抗锯齿描边,包含其绘制的每个像素),以及元素是否适合显示在面板上。元素按给定顺序放置,不会重新适配,因此 action 始终为 none。绝对路径的 output 会将第一帧保存为 PNG,替代 PIXOO_OUTPUT_DIR 自动保存。类型化错误:asset_not_found、invalid_image(读取了图像或精灵,但无法解码)、invalid_color、unknown_icon、invalid_output_path
  • 可通过每个元素的 effect 预设(float、scroll-left、scroll-right、pulse、blink、twinkle、drift、fade-in、fade-out)或在 dx、dy、opacity(数字或数字字符串)、visible(true / false)和 color(对任何带有 color 的元素进行 RGB 插值)上设置原始 animate 关键帧,实现动画;每条轨道至少包含一个关键帧。frames 为 1–800,speed 为每帧 10–2000 ms(默认值为 150)。超过 40 帧时,场景会作为一个 GIF 播放,设备从此主机下载该 GIF;speed 会舍入到 10 ms。元素只能使用 effect 或 animate,不能同时使用。effect 的 amplitude 可设置 float、scroll-* 和 drift 的移动幅度,以及 pulse 和 twinkle 的不透明度变化深度(0–1)

pixoo_push_image 工具
  • source 为本地绝对路径或 https URL,下载大小上限为 10 MB;fit 为 contain(默认值)、cover 或 fill,kernel 为 nearest(默认值,适用于像素艺术)、lanczos3(适用于照片)或 mitchell
  • 无论文件名是什么,只要 source 可解码为 GIF 或 WebP 动图,就会以最多 maxFrames 帧(1–800,默认值为 40)的动画形式推送;如果源文件帧数超过上限,则会均匀采样。超过 40 帧时,动画会作为一个 GIF 播放,设备从此主机下载该 GIF。动画播放时长等于源文件总时长除以推送帧数(源文件未记录帧延迟时为 150 ms),也可通过 speed 设置(每帧 10–2000 ms);frames、sourceFrames 和 speed 会报告实际推送的内容
  • 推送前,finish 会将图像转换为调色板:必须且只能指定 colors(2–256,基于图像生成)或 palette(1–256 个十六进制或命名颜色),并指定 dither(none、bayer4、floyd-steinberg)。透明像素保持不亮,动画的 colors 调色板由所有帧共用
  • 无法读取的路径或 URL 会报错 asset_not_found;已读取但无法解码的源文件(文本文件、HTML 页面或下载不完整的文件)会报错 invalid_image;无法解析的 finish 调色板条目会报错 invalid_color;预览显示设备实际接收的帧,或动画的帧网格

pixoo_render_html 工具
  • html 是完整文档或正文片段,最多 500,000 个字符,会在每个 CSS 像素对应一个 LED 的方形视口中布局。页面就是面板:body 没有边距,滚动条会隐藏,未绘制背景的页面会以黑色(未点亮)渲染。页面自身的 CSS 会覆盖每个

  • frames 为 1–800(默认值为 1),speed 为每帧 10–2000 ms(默认值为 150)。每帧都会让虚拟时钟前进 speed:如果页面定义了 window.render(t, frame),则会在每次捕获前运行,其中 t = frame / frames,因此周期性动画可以无缝循环;requestAnimationFrame、setTimeout / setInterval(嵌套和重复计时器的最小间隔为 4 ms)、Date(从实际时间开始)和 performance.now()(页面加载时为 0)都遵循同一时钟,CSS 动画也会暂停并跳转到对应时间,因此每帧都是确定的。requestIdleCallback 和 iframe 使用实际时间。超过 40 帧时,页面会作为一个 GIF 播放,由设备从此主机下载,与 pixoo_compose_scene 一样

  • sampling:native(默认值)或 supersample,后者以 8× 分辨率渲染,再对每个 LED 进行面积平均,以平滑变换、文本、SVG 和 canvas。Chromium 会在缩放前将普通盒子的边缘对齐到整数 CSS 像素,因此 left: 0.5px 的盒子仍会落在一个 LED 上;使用 transform 移动它以实现亚像素移动。finish 使用与 pixoo_push_image 相同的调色板缩减,并在预览前应用

  • 不会从网络加载任何内容,且会阻止 worker。pageErrors 会返回页面中未捕获的错误、console.error 输出和被阻止的 URL(被阻止的导航格式为 Blocked navigation: <url>):最多 20 条,每条截断至 500 个字符。若 window.render 抛出错误或拒绝,则会以 page_error 失败,并注明帧;未找到浏览器时,调用会以 browser_unavailable 失败并提供安装步骤(参见先决条件);render_timeout 和 render_crashed 分别表示渲染超过 30 s,以及浏览器或页面崩溃。设置 PIXOO_HTML_ENABLED=false 可移除此工具

  • 每个页面都会在自身脚本运行前获得一个 pixoo 全局对象,用于绘制清晰的位图文本、调色板和图标,避免浏览器抗锯齿使它们在 LED 上变得模糊:

    • pixoo.context() 是一个固定覆盖在页面上的面板尺寸透明画布的 2D 上下文。
    • pixoo.text(ctx, text, x, y, { font, color, palette, scale, shadow, outline }) 使用 pixoo_display_text 的字体进行绘制。
    • pixoo.icon(ctx, name, x, y, { w, h, color, palette }) 绘制注册表中的图标。
    • pixoo.palettes 包含 7 种调色板,pixoo.size 是面板尺寸。

    使用这种方式绘制的文本和图标,在两种采样模式下都与 pixoo_compose_scene 的像素完全一致。未知的调色板、图标或颜色会抛出错误并注明名称:

    <script>
      const ctx = pixoo.context();
      pixoo.text(ctx, 'HELLO', 'center', 4, { palette: 'ember', scale: 2, shadow: true });
      pixoo.icon(ctx, 'check-circle', 50, 50, { color: 'green' });
    </script>
    
  • 主题为 html 的 pixoo_design_brief 涵盖循环、时钟、采样、pixoo 运行时以及 64 px 下的易读性。每个循环让一个点绕面板轨道运行一圈:

{
  "html": "<svg viewBox=\"0 0 64 64\" style=\"display:block;width:100vw;height:100vh\"><circle id=\"dot\" r=\"6\" fill=\"#ffb000\"/></svg><script>const dot = document.getElementById('dot'); window.render = (t) => { const a = 2 * Math.PI * t; dot.setAttribute('cx', 32 + 20 * Math.cos(a)); dot.setAttribute('cy', 32 + 20 * Math.sin(a)); };</script>",
  "frames": 20,
  "speed": 100,
  "sampling": "supersample"
}

pixoo_overlay_text 工具
  • 在 20 个槽位中的一个(id 为 0–19)上设置 mode: "set" 或 "clear"。set 需要 text,并接受设备 font ID(0–114)、PIXOO_SIZE 范围内的 x / y、color、speed(0–100)、direction、align 和 width
  • 返回 acknowledged、mode 和 id。覆盖层由设备渲染,因此没有预览,并且会在切换频道后持续显示,直到被清除

pixoo_control_device 工具
  • 不带参数时读取状态;指定 brightness(0–100)、screen(on / off)、channel(faces / cloud / visualizer / custom)或 clockFaceId 中的任意项时,会先应用设置,再读取状态
  • 返回 reachable、channel、brightness、screenOn 和 clockId(设备不可达时不返回),以及 applied;设置失败的项目不会包含在 applied 中,而会在提示信息中注明,调用本身不会失败
pixoo_discover_devices 工具
  • 查询 Divoom 的云端端点(app.divoom-gz.com),因此需要互联网访问;timeoutMs 为 1000–30000(默认值为 5000)
  • 返回每台设备的 name、id 和 ip;设置 PIXOO_IP 后,configuredIpFound 会指示是否匹配。端点无法访问时会以 discovery_failed 失败

pixoo_design_brief 工具
  • topic:text、scene、dashboard、animation、pixel-art、html 或 troubleshooting;即使设备无法访问也可使用
  • 返回 Markdown 格式的 craftGuidance、实时 deviceContext、htmlRenderer(available、当 PIXOO_HTML_ENABLED=false 时为 disabled,或为 no_browser,表示已找到但未启动浏览器)、nextToolSuggestions(格式为 { toolName, reason, args },参数会根据主题和设备状态预先填好),以及 availableThemes 和 iconCategories

pixoo://device/status 资源
  • 未缓存的实时读取:reachable、channel、brightness、screenOn、clockId、displaySize、configuredIp
  • 当设备无法访问或未设置 PIXOO_IP 时,返回 reachable: false,而非错误

pixoo://reference/themes 资源
  • 每种主题(背景、textPalette、accent、shadow)和调色板(from / to 色标),以及供 theme 和 palette 参数使用的 themeNames 和 paletteNames
  • 静态注册表,缓存 24h

pixoo://reference/icons 资源
  • 每个图标的 name、category 和 viewBox,以及按类别分组的 byCategory(天气、箭头、状态、媒体);name 可填入 pixoo_compose_scene 图标元素
  • 静态注册表,缓存 24h

pixoo://reference/design-guide 资源
  • text/markdown:可读性下限、调色板规范、布局区域、动画预算、效果预设、像素艺术规则、推送节奏和已知设备行为
  • 完整指南包含在一份文档中,pixoo_design_brief 会按主题返回指导;缓存 24h

功能

基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可替换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),并提供结构化日志记录和可选的 OpenTelemetry 跟踪。

Pixoo 专属功能:

  • 所有合成工作都在主机上通过 RGBA 画布处理流水线(@cyanheads/pixoo-toolkit)完成;设备接收处理完成的 RGB 帧
  • 推送会将设备切换到自定义频道,并一次执行一个推送;推送之间的间隔由 PIXOO_PUSH_MIN_INTERVAL_MS 控制(默认值为 1000),避免快速连续推送导致设备卡死
  • 最多 40 帧动画每帧各推送一次请求;推送更多帧会导致设备不稳定。超过 40 帧时,pixoo_compose_scene、pixoo_push_image 和 pixoo_render_html(最多 800 帧)会通过此主机上的一次性监听器提供一个 GIF,供设备下载并循环播放,因此设备必须能够访问此主机。pixoo_display_text 不超过 40 帧

Agent 友好的输出:

  • 每次渲染都会生成预览:pixoo_display_text、pixoo_compose_scene、pixoo_push_image 和 pixoo_render_html 会以放大 8 倍的 PNG 图像块形式返回帧,无论是否推送,因此即使未连接设备,也可以通过 push: false 检查设计。动画会以帧网格的形式预览(1 倍尺寸的图块能放入 512 px 画布时显示每一帧;超出时均匀采样),因为 GIF 在不同 MCP 客户端中的显示效果各异;如果设置了 PIXOO_OUTPUT_DIR,GIF 本身会保存到该目录 — 保存的是放大 8 倍的预览 GIF,或者超过 40 帧时保存设备下载的面板尺寸 GIF
  • 布局透明度:layout[] 会报告渲染器的每项决策(字体回退、滚动,以及每个框是否适合面板),方便 Agent 改进设计
  • 设备状态真实可靠:pushed 反映设备 ACK(超过 40 帧时,反映播放请求的 ACK 以及设备对 GIF 的请求;整个文件会交由操作系统发送,但设备不会确认是否收到);推送后读取的 deviceState 会附带提示,指出渲染不可见的原因(屏幕关闭、亮度 ≤ 10、未处于自定义频道),并说明如何修复
  • 推送失败时仍保留渲染结果:对于全部四个渲染工具,类型化错误(device_unreachable、device_http_error、device_rejected、gif_serve_failed、no_device_configured)都会携带 outputFiles,指向已保存的预览(PIXOO_OUTPUT_DIR 副本;如果未设置,则指向临时文件)

快速开始

在 MCP 客户端配置文件中添加以下内容,并将 PIXOO_IP 设为 Pixoo 的局域网地址。如果不知道地址,可使用 pixoo_discover_devices 查找。

{
  "mcpServers": {
    "pixoo-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/pixoo-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "PIXOO_IP": "192.168.1.50"
      }
    }
  }
}

也可以使用 npx(无需 Bun):

{
  "mcpServers": {
    "pixoo-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/pixoo-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "PIXOO_IP": "192.168.1.50"
      }
    }
  }
}

也可以使用 Docker:

{
  "mcpServers": {
    "pixoo-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "-e", "PIXOO_IP=192.168.1.50",
        "-e", "PIXOO_SERVE_HOST=192.168.1.20",
        "-e", "PIXOO_SERVE_PORT=8765",
        "-p", "8765:8765",
        "ghcr.io/cyanheads/pixoo-mcp-server:latest"
      ]
    }
  }
}

超过 40 帧的动画会由设备从此主机下载;而在 Docker 默认桥接网络中,路由到设备的地址是容器自身的地址,设备无法访问。请将 PIXOO_SERVE_HOST 设为 Docker 主机的局域网地址,并发布固定的 PIXOO_SERVE_PORT,如上所示;40 帧及以下的动画无需设置这两项。

要使用 Streamable HTTP,请设置传输方式并启动服务:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 PIXOO_IP=192.168.1.50 bun run start:http
# Server listens at http://localhost:3010/mcp
前置条件
  • Bun v1.4.0 或更高版本(或 Node.js v24+)。
  • 局域网内的 Divoom Pixoo 设备(Pixoo-64、Pixoo-32 或 Pixoo-16)。
  • HTML 渲染器的可选依赖:chrome-headless-shell。运行 npx @puppeteer/browsers install chrome-headless-shell@stable --path ~/.cache/puppeteer 可将其安装到服务默认查找的位置。如果通过 --path <dir> 安装到其他位置,请将 PIXOO_BROWSER_PATH 设为安装程序输出的可执行文件路径。仅在需要渲染时,服务才会以无头模式启动它,且不开放 DevTools 端口。
安装
  1. 克隆代码仓库:
git clone https://github.com/cyanheads/pixoo-mcp-server.git
  1. 进入目录:
cd pixoo-mcp-server
  1. 安装依赖:
bun install
  1. 配置环境:
cp .env.example .env
# edit .env and set PIXOO_IP

配置

变量描述默认值
PIXOO_IP本地网络中的设备 IP。推送、叠加层和设备控制必需此项;发现、设计简报以及 push: false 渲染无需此项。—
PIXOO_SIZE显示尺寸(像素):16、32 或 64。64
PIXOO_OUTPUT_DIR渲染工具保存预览 PNG 和 GIF 文件的目录。相对路径将相对于启动服务时所在的目录解析,因此报告的保存路径为绝对路径。未设置时,仅在响应中返回预览。—
PIXOO_PUSH_MIN_INTERVAL_MS向设备推送的最小间隔,单位为毫秒。1000
PIXOO_SERVE_HOST设备下载超过 40 帧的动画时,URL 中公布的主机地址,用于替代操作系统路由到 PIXOO_IP 的本地地址。无论如何,监听器都会绑定到该路由地址。在 NAT 后或容器中运行时请设置此项。—
PIXOO_SERVE_PORT此次下载的一次性监听器固定端口,供防火墙规则和容器端口发布使用。未设置时,每次播放使用一个空闲端口。—
PIXOO_BROWSER_PATH用于 HTML 渲染的浏览器可执行文件。设置后只会尝试此浏览器:如果路径不是可执行文件,则会失败,不会回退。相对路径将相对于启动目录解析。未设置时,使用 Puppeteer 缓存(~/.cache/puppeteer)中最新的 chrome-headless-shell。Docker 镜像不包含浏览器。—
PIXOO_HTML_ENABLED提供 pixoo_render_html。设为 false 时会从 tools/list 中移除;若值不是布尔值,则启动失败。true
MCP_TRANSPORT_TYPE传输方式:stdio 或 http。stdio
MCP_HTTP_PORTHTTP 服务端口。3010
MCP_SESSION_MODEHTTP 会话模式:stateless、stateful 或 auto。在此处设置的值会覆盖服务声明的 stateless。stateless
MCP_AUTH_MODE身份验证方式:none、jwt 或 oauth。none
MCP_LOG_LEVEL日志级别(debug、info、warning、error 等)。info
LOGS_DIR日志文件目录(仅限 Node.js)。<project-root>/logs
LOG_TOOL_FAILURE_PAYLOADS记录每次失败的工具调用参数和结果,按键名脱敏,并限制为 LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES(默认 16384)字节。自由格式值中的机密不会被脱敏。false
OTEL_ENABLED启用 OpenTelemetry。false

完整的可选覆盖项列表请参见 .env.example。

运行服务

本地开发
  • 构建并运行:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
    
  • 运行检查和测试:

    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    
    # Real-browser suite for the HTML renderer (opt-in; launches the named browser)
    PIXOO_TEST_BROWSER_PATH=/path/to/chrome-headless-shell bun run test:browser
    
Docker
docker build -t pixoo-mcp-server .
docker run --rm -e PIXOO_IP=192.168.1.50 -p 3010:3010 \
  -e PIXOO_SERVE_HOST=192.168.1.20 -e PIXOO_SERVE_PORT=8765 -p 8765:8765 \
  pixoo-mcp-server

PIXOO_SERVE_HOST(Docker 主机的局域网地址)和已发布的 PIXOO_SERVE_PORT 可让设备从容器内下载超过 40 帧的动画,配置方式与上面的 stdio 配置相同。

Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/pixoo-mcp-server。默认会安装 OpenTelemetry 对等依赖项;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖项。

项目结构

目录用途
src/index.tscreateApp() 入口:注册工具和资源,并初始化 Pixoo 服务。
src/config/使用 Zod 解析并验证服务器专属的环境变量。
src/mcp-server/tools/工具定义(*.tool.ts)、共享的渲染后推送路径,以及共享的 finish 输入架构。
src/mcp-server/resources/资源定义(*.resource.ts)。
src/services/pixoo/PixooService:封装 @cyanheads/pixoo-toolkit,提供推送节流、结果映射和设备状态读取。
src/services/browser/BrowserRenderer:在隔离的无头 chrome-headless-shell 中渲染 HTML,通过 DevTools Protocol 管道驱动,并将其捕获为面板帧。
src/renderer/不依赖设备的纯渲染流水线:元素渲染器、样式化文本引擎、主题、图标、效果编译器、调色板处理、预览编码、远程图像抓取,以及注入 HTML 页面的虚拟时钟。
tests/与 src/ 结构对应的单元测试和集成测试。

开发指南

开发指南和架构规则请参阅 CLAUDE.md/AGENTS.md。简要说明:

  • 处理器抛出异常,框架负责捕获——工具逻辑中不要使用 try/catch
  • 使用 ctx.log 记录请求级日志,使用 ctx.state 存储租户级数据
  • 渲染器(src/renderer/)是纯逻辑——不依赖设备,无需硬件即可测试
  • 所有设备调用都通过 PixooService;检查每个 PixooResult——绝不要假定推送成功

贡献

欢迎提交问题。提交前请运行检查和测试:

bun run devcheck
bun run test

许可证

Apache-2.0——详情请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。