Skip to main content
Glama

Cullyard

Tell your agent how to sort. Watch the folders move.

Cullyard is a local MCP server with a desk in the browser. Claude Code, Antigravity or any other MCP client reads every file in a folder, sorts it into lanes (Picks, Maybe, Rejects, or lanes you name), and trims or resizes copies when you ask. The desk at http://127.0.0.1:4870 shows each move as it happens, and you can drag cards back if you disagree. When a sort is done, the agent can write a SHA-256 of the sort log into a Solana devnet memo, so anyone holding the log can check later that it was not edited.

Desk after a sort, with the activity feed showing the devnet seal

What it handles

Kind

Examples

What the agent sees

image

jpg, png, webp, heic, avif, gif, tiff

width, height, format

raw

cr2, cr3, nef, arw, dng, raf

width, height when the decoder can read it

video

mp4, mov, mkv, webm, avi, mts

duration, codec, frame size

audio

mp3, flac, wav, m4a, ogg, opus

duration, title, artist

pdf

pdf

page count

document

docx, xlsx, csv, pptx, md, epub

kind and size

archive, design, code, other

zip, psd, blend, py, anything else

kind and size

Unknown extensions are still listed as other. The desk never refuses a file because of its extension.

Related MCP server: FilePilot AI

Install

You need Node.js 20 or newer. FFmpeg ships inside the package, so trimming works on a clean Windows machine.

Claude Code:

claude mcp add cullyard -- npx -y github:bryankwandou/cullyard "D:\Shoots\Bali"

Antigravity, Cursor, Claude Desktop or any client that reads an mcpServers block:

{
  "mcpServers": {
    "cullyard": {
      "command": "npx",
      "args": ["-y", "github:bryankwandou/cullyard", "D:\\Shoots\\Bali"]
    }
  }
}

Replace the folder with your own. The desk opens on 127.0.0.1:4870 (set CULLYARD_PORT to change it). Pass --no-desk if you only want the MCP tools.

To seal runs on devnet, set CULLYARD_KEYPAIR to the path of a devnet keypair JSON file. Without it, sorting and editing work the same and seal_run returns a clear error.

Tools

Tool

What it does

scan_workspace

Lists every file with kind, size, pixel size, duration, tags or page count

describe_file

Metadata for one file

list_lanes

Current lanes and which file sits where

create_lane

Adds a lane, such as "Hero shots" or "Client docs"

move_to_lane

Moves a file into a lane folder, with an optional reason shown on the desk; never overwrites

assess_photos

Measures focus, exposure and bursts for every photo, ranks them against each other

contact_sheet

One numbered grid of up to 16 photos, returned as an image the agent can look at

preview_image

One photo as an image (up to 1024 px), plus its measurements

resize_image

Writes a resized WebP, JPG, PNG or AVIF copy

trim_media

Cuts a time range from video or audio without re-encoding

log_digest

SHA-256 of the sort log, computed locally

seal_run

Writes that hash into a Solana devnet memo

verify_seal

Recomputes the hash and checks it against the chain

list_kinds

The file kinds Cullyard recognises

Rules the server enforces: paths outside the workspace are refused, moves never overwrite, edits always write a new file, and the original is never touched.

How the agent sees photos

Metadata alone cannot tell a sharp frame from a blurred one, so Cullyard gives the agent two kinds of evidence.

Pictures. contact_sheet and preview_image return real images over MCP, so a vision model such as Claude looks at the photos instead of guessing from file names. The sheet numbers each frame, and the legend maps numbers back to files.

Measurements. assess_photos measures each photo and compares it with the rest of the set:

  • Focus: variance of the Laplacian on a contrast-stretched greyscale copy, measured per tile on a 4×4 grid. The sharpest tile counts, so a sharp subject on a soft background still reads as sharp, and a dark frame is not mistaken for a soft one.

  • Exposure: mean brightness and the share of clipped shadows and highlights.

  • Bursts: a 64-bit difference hash plus a 3×3 colour print. Two frames are one burst only when both match, so the same framing at golden hour and at blue hour stays separate. The sharpest frame of each burst is kept; the others are flagged duplicate.

  • Flags: soft (under 40% of the set's median focus), dark, bright, duplicate. Rank puts clean frames first, sharpest first.

The results are saved in .cullyard/quality.json, and the desk shows them on each card, so you see the same evidence the agent used. The numbers are signals, not verdicts: a shallow-focus portrait or a night shot can be a keeper with "bad" numbers, which is why the agent also looks at the picture.

A real run

scripts/demo-agent.mjs drives the real server over stdio, the same way an agent does. It scans twelve sample files, creates a "Client docs" lane, measures the seven photos, looks at them on a contact sheet, sorts photos from what it measured (with a reason on every move), files the other four, resizes the top pick to 1200 px WebP, trims three seconds from a clip, seals the log on devnet and verifies the seal. The full output is in docs/agent-transcript.txt, and the recorded desk is in web/media/walkthrough.mp4.

npm install
node scripts/make-samples.mjs demo-workspace
CULLYARD_KEYPAIR=path/to/devnet-keypair.json node scripts/demo-agent.mjs demo-workspace

The seal from the recorded run is in web/proof.json and can be opened on Solana Explorer.

How the seal works

Every move appends one JSON line to .cullyard/log.jsonl inside the workspace. seal_run hashes the log with SHA-256 and sends one transaction to the Memo program (Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo) with the text:

cullyard:v1 log=<sha256> entries=<count>

verify_seal fetches that transaction, hashes the log lines written before the seal, and compares the two. File names and file contents never go on-chain; only the hash does.

Tests

npm test

Eighteen tests cover file kinds, scanning, lanes, path traversal, no-overwrite moves, resizing, video probing, the desk's upload and cross-origin guard, the seal digest, photo measurement (blur, a sharp subject on a soft background, dark frames, bursts, colour-separated framings), the contact sheet, and a full MCP stdio round trip that includes the image tools.

Layout

bin/        command-line entry (MCP over stdio, plus the desk)
src/        scan, lanes, edit, look (photo measurement), seal, MCP server, desk server
desk/       the browser desk (plain HTML, CSS, JS; English and Indonesian)
web/        landing page, screenshots, walkthrough video, proof.json
scripts/    sample generator and the demo agent
test/       node:test suites
docs/       report and agent transcript
pitch/      pitch deck
video/      marketing video

What it does not do yet

  • The photo thresholds were tuned on generated test images, not yet on a real shoot. Treat flags as hints and check the contact sheet.

  • Image tools need an MCP client that shows image results to the model. Claude Code does; other clients were not tested.

  • There is no timeline editor. Trim and resize are single steps.

  • Seals use devnet only.

License

MIT

Available Tools

14 tools
assess_photosA

Measure sharpness (per region, so a sharp subject on a blurred background still scores well), exposure and clipping for each photo, find near-duplicate bursts and mark the sharpest frame of each, and rank the set. Flags are relative to the set: soft, dark, bright, duplicate. Treat them as evidence, then look with contact_sheet or preview_image before rejecting a photo.

Inputs: lane, files.

contact_sheetA

Return up to 16 photos as one numbered grid image you can look at, with a legend mapping numbers to files. Use it to compare a set: composition, faces, closed eyes, missed focus.

Inputs: lane, files, offset.

create_laneC

Create a custom lane, for example "Hero shots" or "Final cut".

Inputs: name (required).

describe_fileB

Return kind and metadata for one file in the workspace.

Inputs: file (required).

list_kindsB

List the file kinds Cullyard recognises.

Inputs: no named parameters.

list_lanesA

Return the lanes and which file sits in which lane.

Inputs: no named parameters.

log_digestA

Show the current SHA-256 and entry count of the sorting log, without sending anything.

Inputs: no named parameters.

move_to_laneA

Move a file into a lane folder. Never overwrites. Give a short reason; the desk shows it to the person watching.

Inputs: file (required), lane (required), reason.

preview_imageA

Return one photo as an image you can look at (up to 1024 px), with its measured quality. Use it to check focus on the eyes, expression or detail before deciding.

Inputs: file (required), size.

resize_imageC

Write a resized copy of an image next to the original.

Inputs: file (required), width, format, height.

scan_workspaceB

List every file in the workspace with its kind, size and metadata.

Inputs: no named parameters.

seal_runB

Write the SHA-256 of the sorting log into a Solana devnet memo, as proof of what was sorted and when.

Inputs: no named parameters.

trim_mediaC

Cut a time range out of a video or audio file without re-encoding.

Inputs: file (required), endSec (required), startSec (required).

verify_sealB

Recompute the log hash at seal time and compare it with the memo on Solana devnet.

Inputs: signature (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 14 tools

    Disambiguation4/5

    Most tools target clearly distinct resources and actions: sealing (seal_run/verify_seal/log_digest), workspace inspection (scan_workspace/describe_file/list_kinds), lanes (list/create/move), and media editing (resize/trim) are well separated. The photo-inspection trio (assess_photos, contact_sheet, preview_image) has some conceptual overlap since all return quality information, though the descriptions distinguish set-level measurement, grid comparison, and single-image inspection.

    Naming Consistency4/5

    Nearly all names follow a consistent snake_case verb_noun pattern (seal_run, list_kinds, scan_workspace, move_to_lane, assess_photos, resize_image). A couple deviate to compound nouns (contact_sheet, log_digest), which is a minor inconsistency but still readable and predictable.

    Tool Count5/5

    14 tools is well within the sweet spot for this domain, covering sealing, inspection, lane management, photo assessment, and light media editing. Each tool has a clear and non-redundant role.

    Completeness4/5

    The surface covers the core lifecycle: scan/describe files, create/list lanes, move files, assess and preview photos, resize/trim media, and seal/verify logs. Minor gaps exist—no delete or remove-from-lane operation, no lane update/delete, and no batch move—but most workflows can be completed.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      B
      maintenance
      A powerful, security-hardened MCP server for intelligent file organization. Provides high-level atomic tools for organizing files into categories, detecting duplicates, extracting EXIF/ID3 metadata, scheduling automatic organization, and more — for use with Claude, Cursor, and Gemini CLI.
      26
      119 npm
      46
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Local-first MCP server for safely searching, reading, summarizing, tagging, deduplicating, and organizing local files with scoped access, read-only defaults, and dry-run plans.
      19
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      MCP server for organizing files on your Mac Desktop by automatically categorizing them into folders. Supports listing, previewing, and moving files into category folders (Images, Documents, Videos, etc.).
      -
    • A
      license
      A
      quality
      B
      maintenance
      Local MCP server for PDF and photo tasks: merge, split, rotate and number PDFs, convert images to PDF, and inspect or strip hidden photo metadata (EXIF/GPS). Runs entirely on your machine — no uploads, no accounts, no API keys.
      2
      9
      MIT