关于 pixoo-mcp-server
pixoo-mcp-server 通过本地网络将文本、场景、图像、HTML 和动画发送到 Divoom Pixoo LED 显示屏,也可读取和调整设备状态,适合构建像素画与小型仪表盘。
主要功能
- 01渲染主题化文本与动画
- 02组合分层场景和图形
- 03推送图像及动画文件
- 04将 HTML 页面渲染到屏幕
- 05读取并控制显示设备状态
适用场景
- 01在 Pixoo 屏幕显示实时风格化信息
- 02制作像素风仪表盘与动画
- 03调整亮度、频道和屏幕状态
MCP 相关
提供 8 个工具和 4 个资源,通过 STDIO 或 Streamable HTTP 供 MCP 客户端使用。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @cyanheads/pixoo-mcp-serverPIXOO_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+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
8收录的工具列表 · 更新于 4 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| font | enum | 否 | 字体变体,按指定值使用;文本过宽时会溢出,不会切换字体:standard(5×7)或 compact(3×5),两者均支持可打印 ASCII 字符及 ° ← ↑ → ↓ ▲ ▼ ♥ · …;或 numerals(用于时钟和读数的 11×18 数字),仅绘制 0–9、空格及 : . - + / % ° ?,因此文本包含其他字符时会被拒绝。省略此参数时,单行文本先尝试 standard,若溢出则回退到 compact;多行文本使用 standard。standard | compact | numerals |
| push | boolean | 否 | 将渲染后的帧推送到设备(默认值:true)。 |
| text | any | 是 | 要显示的文本。字符串或行数组。 |
| align | enum | 否 | 多行文本:将每行在最宽行的范围内对齐,然后使用 position.x 放置整个文本块。省略时,使用各自的 position.x 单独放置每一行。left | center | right |
| style | object | 否 | 文本样式:调色板、阴影、描边、缩放。 |
| style.color | string | 否 | 不使用调色板时的纯色。 |
| style.scale | integer | 否 | 整数像素缩放倍数(1 = 正常,2 = 粗块状字体)。 |
| style.shadow | boolean | 否 | 文本后方的投影。 |
| style.outline | boolean | 否 | 提升可读性的 1px 对比色描边。 |
| style.palette | any | 否 | 用于垂直色阶的命名调色板或自定义渐变色标。 |
| theme | enum | 否 | 命名场景主题 — 设置背景渐变和默认文本调色板。midnight | ember | claude | ice | neon | forest | mono |
| effect | enum | 否 | 动画效果。scroll 会让文本在最多 40 帧内横穿显示屏一次;auto 仅在文本宽度超出显示范围时滚动;float(轻柔浮动)和 pulse(亮度呼吸)会循环播放 20 帧。动画结果会作为动画推送,并以帧网格预览。none 或省略时会渲染一个静态帧。none | auto | scroll | float | pulse |
| position | object | 否 | 文本在显示屏上的位置。 |
| position.x | any | 否 | X 位置或对齐方式(默认:居中)。 |
| position.y | any | 否 | Y 位置或对齐方式(默认:居中)。 |
| background | any | 否 | 背景颜色或渐变。设置后会覆盖主题背景。 |
| brightness | integer | 否 | 推送前设置设备亮度(0–100)。失败时仅发出警告,不视为错误。 |
详细介绍
@cyanheads/pixoo-mcp-server
通过 MCP 在本地网络上,将风格化像素艺术、文本、仪表板和动画渲染并推送到 Divoom Pixoo LED 显示屏。支持 STDIO 或 Streamable HTTP。
概述
可在本地网络上使用 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,并接受设备fontID(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 端口。
安装
- 克隆代码仓库:
git clone https://github.com/cyanheads/pixoo-mcp-server.git
- 进入目录:
cd pixoo-mcp-server
- 安装依赖:
bun install
- 配置环境:
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_PORT | HTTP 服务端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式: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.ts | createApp() 入口:注册工具和资源,并初始化 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。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。