Lutra MCP

Lutra MCP

Exposes Lutra's in-browser color-grading tools to AI clients, enabling them to render shots, inspect scopes, adjust grade parameters, and export LUTs.

Category
访问服务器

README

Lutra

In-browser color-grading LUT creator. Drop screenshots, camera RAW files or a video clip, grade them with real colorist tools, export .cube / .3dl / Unreal / Unity / ReShade / HALD LUTs. No installs, no accounts — everything runs locally on your GPU via WebGL2. Images never leave your machine.

Live at https://lutra.gamebench.dev

Why

Making a color LUT usually means installing gigabytes of video software. Lutra is a ~70 KB (gzipped) web app built around one architectural rule: every operation is a pure per-pixel color transform, so the entire grade bakes into a 3D LUT exactly. Spatial effects (bloom, halation, grain, vignette) exist only as a clearly-labelled preview layer and export as an engine recipe rather than pixels, because they can't live in a LUT — what you see in the grade is what the LUT does.

Features

Grading

  • Contact-sheet grading — load many shots across lighting conditions; every thumbnail follows the grade live, because a LUT is global and has to hold up everywhere.
  • Per-shot development — normalize each source by ±4 EV before judging the shared look. Developed originals, scopes, color picking, and Auto match all see the same input; the offset stays out of the exported LUT by design.
  • Colorist toolset — white balance (+ gray eyedropper), exposure, contrast with pivot, highlights/shadows/whites/blacks, lift/gamma/gain/offset wheels, master and per-channel R/G/B curves, 8-band HSL mixer (Oklab hues), continuous Sat-vs-Sat and Luma-vs-Sat curves, saturation/vibrance with lightness-keyed shadow/highlight control, split toning, output levels, and a master look-strength blend.
  • Creative LUT layer — drop in any .cube you already own and keep grading on top of it with a strength slider. It stacks in right after the tone curves, so everything below trims the look rather than feeding it — and both still bake into one exported LUT.
  • Film response, honestly — bloom, halation, grain and vignette preview as a layer the UI labels not in the LUT in as many words. They can't bake (bloom reads neighbouring pixels; grain and vignette depend on position in frame), so they're hidden from thumbnails, comparisons and scopes, and export as an engine recipe naming the Unreal/Unity/ReShade settings that reproduce them.
  • Compare — before/after (hold Space), A/B wipe, per-shot thumbnails. Undo/redo and keyboard shortcuts throughout.

Input

  • Camera RAW.ARW, .CR2, .CR3, .NEF, .DNG, .RAF, .ORF, .RW2 and the rest via LibRaw compiled to WebAssembly. The camera's own white balance and color matrix are applied, then the frame enters the pipeline as scene-linear light at exactly the point EXR and PQ AVIF do — so a photo and a game capture grade identically. Exposure is a fixed, documented headroom constant, not per-image auto-brightness, so a night shot and a snow field don't develop to different brightnesses. The 1.5 MB decoder is behind a dynamic import() and never weighs on anyone else's load.
  • HDR & high bit depth — OpenEXR (half/float, NONE/RLE/ZIP), Radiance .hdr, and 10/12-bit AVIF (PQ, HLG, high-bit SDR) at full precision via zero-dependency decoders + WebCodecs. HDR develops to display sRGB with the same ACES fit the PQ shaper export assumes, so preview and in-engine result agree. Browsers without WebCodecs ImageDecoder (Safari, Firefox) get pre-developed SDR companions derived from the encoded PQ data, so pixels match — and a clear warning when a user's HDR AVIF must be browser-tonemapped.
  • Live video grading — MP4/MOV/WebM clips sit in the same filmstrip as stills. Select one, play, scrub or step frames in the normal viewport, and keep turning every grading knob while it runs. Presented frames feed the shared WebGL grade directly from the browser/OS decoder; hardware decode is used when that codec/browser/device combination supports it. Original clip bytes and the playhead persist locally in browser storage and restore into the filmstrip after a restart; they are never uploaded. Copies are chunked and cancellable, quota is checked first, and each clip is labelled LOCAL or SESSION so storage failure is visible rather than destructive.

Matching & QA

  • Auto match — drop a reference image and a solver fits the broad-stroke knobs so the whole contact sheet's Oklab statistics match it. The result is ordinary knob positions: blend with a strength slider, refine by hand, undo in one step.
  • .cube import — the same solver fits the knob stack to any 3D .cube (typically within ΔE ≈ 0.1), turning an opaque LUT back into an editable grade.
  • LUT Lab — open any 3D .cube as float data, inspect its declared input domain, output excursions and folded/singular cells, resize it, blend it from 0–200%, compose it before or after a second LUT, then download, stack, or reverse-fit the result. Custom domains and values outside 0–1 survive the round trip instead of being silently clipped.
  • Color locks — pin colors that must survive the grade (UI colors, team reds, skin tones). Live ΔE badges warn when the grade moves them, and Auto match treats them as constraints.
  • Harmonize assets — mask a palette to keep and an asset to adjust; Harmonize solves only the HSL mixer so the asset matches under your look. Export texture fix instead solves a standalone B→A transform and downloads it as .cube + HALD for batch-applying to textures.
  • Scopes — RGB histogram, parade, waveform, vectorscope with skin-tone line, clipping zebras, exact in→out pixel probe, and color-vision-deficiency simulation for gameplay-readability checks.
  • Honest baked preview — toggle between the float pipeline and the actual quantized LUT (16³/32³/65³, trilinear or tetrahedral) to see banding before export instead of in-engine.

Output & persistence

  • Source-resolution stills — export the active shot as a PNG at its original dimensions, including per-shot development and either the float grade or the currently selected quantized-LUT preview. A separate complete-look export renders tuned bloom, halation, grain and vignette into the pixels.
  • Exports.cube (16/32/65), .3dl, Unreal 256×16 strip, Unity LDR 1024×32 strip, ReShade lut.png, HALD CLUT 512×512, and a PQ shaper .cube for engines grading in scene-referred HDR before the tonemapper. Multiple formats bundle into one zip. See docs/exports.md for per-engine setup and the PQ shaper's caveats.
  • Share links — the Share button copies a URL with the whole look gzipped into the fragment. No server, nothing uploaded.
  • Sessions survive reload — shots and mask scribbles persist to OPFS, the grade to localStorage. Close the tab, come back, keep grading.
  • Works on a phone — below 860px the image pins to the top while controls scroll under it, hit targets grow, and two fingers pinch-zoom the viewport.

Connect AI

One button in the toolbar. Lutra exposes its tools over the Model Context Protocol, so Claude, ChatGPT or any MCP client can drive the app you already have open. The point isn't text-to-LUT: the assistant can look. It renders a shot, reads the scopes, nudges one named axis in plain English, renders again, checks your locked colors — the loop a blind generator can't close. Global grade changes remain ordinary undo steps; shot development and film response stay separate so an undo cannot silently cross pipeline boundaries.

Two transports, picked for you. WebMCP, where the browser implements it (Edge ships it; Chrome runs an origin trial from 149), hands the tools to the in-browser agent with no pairing at all. Everywhere else you get a connector link relayed through a Durable Object that stores nothing:

Client What you get
Claude Code claude mcp add --transport http lutra <url>, to run in a terminal
Codex an [mcp_servers.lutra] block for ~/.codex/config.toml
Claude app the bare URL, for Settings → Connectors → Add custom connector

Tools: get_look · list_shots · render_shot (returns the actual image) · get_scopes (original or graded) · nudge · set_look · set_shot_development · get_film_response · set_film_response · suggest_looks · check_locks · undo · get_share_link. The grade schema includes the wheels and expert curves, plus a compact toe/mid-gamma/shoulder tone shape. Declared once in shared/mcpTools.ts, implemented in src/mcp/tools.ts; worker/mcp.ts is the protocol as a pure function.

Security. There is no API key and no OAuth — the code in the URL is the credential, so treat it like a password and use New link to revoke one you've pasted somewhere public. It works only while the Lutra tab is open. Lutra holds no API key and calls no model: the intelligence is billed to the subscription you already pay for, which is why this costs nothing to run and needs no account. A localhost link is unreachable from the Claude app, which connects from Anthropic's servers; Claude Code and Codex run locally, so they can use one.

Develop

npm install
npm run dev        # http://localhost:5173
npm run build      # type-check + production build → dist/
npm test           # vitest

One runtime dependency (libraw-wasm, dynamically imported and code-split so it only loads for RAW files); dev deps are Vite + TypeScript only.

Deploy

Production is served as static assets from a Cloudflare Worker — no server code, just dist/:

npm run deploy       # build + wrangler deploy
npm run deploy:dry   # validate without deploying

The custom domain is a route in wrangler.jsonc, so DNS is kept in sync by the deploy. The app is fully static with relative asset paths, so it also hosts on Netlify, GitHub Pages or any file server — grading, export and every feature above work with no backend at all. The only server-side piece is the MCP pairing relay (worker/), and WebMCP doesn't even need that.

Docs

  • docs/exports.md — using the exported LUTs in each engine, and what the PQ shaper does and doesn't guarantee.
  • docs/architecture.md — the single-grade()-function design, the CPU mirror, the solver, and roadmap ideas.
  • docs/professional-parity.md — competitor-backed capability gaps, browser feasibility decisions, and acceptance gates.
  • docs/cloud-architecture.md — the local-first server boundary and the fail-closed Cloudflare budget capped at $100/year.

License

Proprietary — all rights reserved. See LICENSE.

The app is free to use at https://lutra.gamebench.dev; the source is not licensed for reuse. This may change: releasing under an open-source licence later is easy, and un-releasing is impossible, so the source stays closed until that decision is made deliberately.

A built deployment still redistributes LibRaw (LGPL-2.1 or CDDL-1.0, via libraw-wasm), and the bundled samples are CC0 from RawDB. Those obligations follow the deployed app rather than the source, so they apply regardless of this repository's visibility — see NOTICE, including which RawDB licences are safe to bundle if you add a sample.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选