CodedByKay.ArtShow.Mcp
Provides tools for interacting with an artwork catalog stored in a SQLite database, enabling CRUD operations on artworks and classifiers, filtering and searching, catalog statistics, publish-state checks, and classifier management.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
CodedByKay.ArtShow.Mcp
MCP server that does the whole CodedByKay.ArtShow.CLI workflow — add, edit,
view, and delete artwork; manage classifiers; publish artwork.json; check
catalog/R2 sync — from an MCP client (Claude Code, Claude Desktop, etc)
instead of the CLI's interactive TUI. Batch-capable throughout (add/update/
delete many artworks in one call) and can classify new artwork itself when
you don't hand it category/medium/tags/groups (see "Classification" below).
This is a second writer of artwork.db alongside CodedByKay.ArtShow.CLI
itself, and — new as of this rebuild — a second writer of R2 objects and of
the site's data/artwork.json too. See
ArtShow.Workspace/working-on/mcp-rebuild-plan.md for the full rationale and
ArtShow.Workspace/AGENTS.md for how this fits the rest of the workspace.
Both this server and the CLI talk to the same SQLite file in WAL mode, which
supports that safely (busy_timeout + a SAVEPOINT per batch item here).
Uses Node's built-in node:sqlite (no native DB dependency to build), plus
sharp for imaging and @aws-sdk/client-s3 for R2 — both installed from
prebuilt binaries, no native build step. Requires Node.js 22.5+.
Setup
npm install
npm run buildR2 credentials aren't configured separately — this server reads the exact
same sources the CLI does (see "Configuration" below), so if dotnet run in
CodedByKay.ArtShow.CLI already works, this does too.
Related MCP server: serve-mcp
Tools
Read / inspect
list_artworks— filter (ids, type, category, medium, tag, group, text search, date range, missing-R2-key) + sort + paginate.get_artwork— fetch one or more artworks by id.get_status— no network: catalog counts, classifier breakdown, the pending-publish flag, and the resolved config (paths, R2 bucket, and where credentials were found or that they're missing). Good first call.check_sync— cross-references the catalog against the R2 bucket: keys referenced but missing, bucket objects orphaned (unreferenced), total bytes.verifyUrls: truealso HEAD-checks every public URL.verify_catalog— DB-only consistency sweep the CLI has no equivalent of: missing R2 keys/video ids, invalid dates, empty titles, duplicate R2 keys, classifier values used by an artwork but not in theClassifierstable.
Write — artworks
add_artworks— the centerpiece. Add one or more artworks (images and/or YouTube videos, mixed freely) in a single call. Per image: EXIF- orients, encodes a full-res WebP (q90) + 600w WebP thumbnail (q75), allocates collision-free R2 keys, uploads both, inserts the row, marks the catalog dirty, HEAD-verifies both public URLs, then deletes the local source file (deleteSourceAfterUpload, default true — only deletes after both URLs verify live). Every item succeeds or fails independently.dryRun: truevalidates/encodes/resolves classifiers without uploading or writing anything. See "Classification" below foronMissingClassifiersandclassifierMode.update_artworks— batch partial update by id; nullable fields (description/createdDate/category/medium/r2Key/thumbR2Key/videoId) explicitly settable tonullto clear them. Doesn't touch R2 or re-encode images.delete_artworks— batch delete, including R2 objects (the CLI's real "Delete artwork" behavior) unlesskeepFiles: true. Requiresconfirm: true.replace_artwork_image— point an existing image row at a new local file: uploads new R2 objects, updates the row, verifies, then removes the old R2 objects. The one workflow the CLI has no direct answer for short of delete-and-re-add.relocate_artwork_media— batch-move an image row's R2 objects to their canonicaloriginals/<year>/<slug>.webp/thumbs/<year>/<slug>-600w.webppath (year fromCreatedDate, falling back toAddedDate) via a server-side R2 copy — no download, no re-encoding, bytes untouched. For whenCreatedDatewas corrected after upload and left the object under the wrong year folder. A row already at its canonical keys is left alone and reportedunchanged; a manual copy done ahead of time (new key already present, old key already gone) is tolerated and still updates the row. Every id succeeds or fails independently.
Classifiers
list_classifiers— the vocabulary (Category/Medium/Tag/Group), each with a usage count and example titles. Passmatch: string[]to fuzzy-match candidate values against it (surfaces "watercolour" → "watercolor" instead of letting a near-duplicate spelling become a second classifier).create_classifiers— batch add known values without attaching them to any artwork.rename_classifier— cascades into every artwork using it.merge: truefolds a rename into an already-existing classifier of the same name instead of erroring — the real fix for a near-duplicate.delete_classifier— reports usage count;force: trueto unlink from artworks and delete anyway.
Publish
publish— writesdata/artwork.jsonbyte-identically to what the CLI'sSystem.Text.Jsonwriter produces (see "Publish parity" below), clears the pending-publish flag, and returns a diff (ids added/removed, and which fields changed on modified ids). Metadata only — does not commit or push; review the diff, then commit + push the site repo yourself (Netlify auto-deploys on push).dryRun: truecomputes the diff without writing. Also writesdata/collections.json(collection blurb/cover/order, seeset_collection_details).set_publish_state/get_publish_state— read/manually set the pending-publish flag.
Maintenance
prune_orphaned_r2_objects— deletes bucket objects no catalog row references (originals, thumbs and display files all count as referenced). Dry-run by default;confirm: trueto execute.backfill_image_metadata— one-off catch-up for rows added before the 2026-10 data-contract change: records each image's pixel size and uploads the 2000pxdisplay/WebP where the original is larger. Dry-run by default;confirm: trueprocesses up tolimitrows per call. Idempotent.set_collection_details(under Classifiers) — a Group's blurb, cover artwork and display order, published todata/collections.json.
Also: an MCP resource artshow://classifiers (the same vocabulary
list_classifiers returns, without a tool call) and an MCP prompt
add-new-drawings that walks through classifying-and-adding every image in
a staging folder end to end.
Classification
This server can't see an image — classification is the calling agent's job. Three things make that consistent instead of ad hoc:
list_classifiersis the vocabulary, with usage counts and example titles, so an agent picks an established value over inventing a new one.onMissingClassifiersonadd_artworks(default"error"): an item with no category/medium/tags/groups at all is rejected, and the error carries the entire vocabulary — so an agent that hits it can look at the image and retry immediately instead of a second round trip."warn"inserts anyway with a flag on the result;"allow"is silent (the pre-rebuild behavior).classifierMode:"lenient"(default, matches the CLI's own auto-add-on-first-use behavior) accepts a new value and creates it, reporting it in the result asclassifiersCreated."strict"rejects a value not already in the vocabulary — if something close exists ("watercolour" vs "watercolor") the error suggests it by name; if nothing does, it says so and points atlist_classifiers.
Publish parity
CodedByKay.ArtShow.CLI writes data/artwork.json via
JsonSerializer.Serialize(items, new JsonSerializerOptions { WriteIndented = true }).
For this server's publish to be a safe drop-in replacement (rather than
having every alternate publish between the CLI and this server rewrite the
whole file), src/publishing/dotnet-json-encoder.ts reimplements that
writer's exact output byte-for-byte: CRLF line endings, 2-space indent, no
trailing newline, comma-before-newline placement, empty arrays/objects
collapsed to []/{}, and JavaScriptEncoder.Default's escaping (" as
\u0022 — not \" —, &, ', <, >, and everything above 0x7E
escaped as uppercase \uXXXX). The " rule was wrong until 2026-10 and was
found by diffing against the CLI's real output; ArtShow.CLI --publish makes
that comparison scriptable.
Verified with a byte-for-byte round-trip test against the live file — see
src/test/dotnet-json-encoder.test.ts.
Configuration
Reads the same sources CodedByKay.ArtShow.CLI does (mirroring
Program.cs's ConfigurationBuilder precedence — env vars win, then
dotnet user-secrets, then appsettings.json), so no separate credential
setup is needed if the CLI already works:
Source | What it provides |
|
|
|
|
Environment variables | Override anything above — see below |
Env var overrides (all optional):
Variable | Overrides |
| Path to |
| Full path to |
| Site repo root (default |
| Default |
| R2 bucket config |
| R2 credentials |
Call get_status to see exactly what was resolved and where each value
came from (including whether credentials were found and in which file).
Safety
Every destructive tool (
delete_artworks,prune_orphaned_r2_objects) requiresconfirm: true; both plusadd_artworks/replace_artwork_imagesupportdryRun.A local source file is never deleted before both its R2 public URLs HEAD 200.
If a catalog insert fails after an R2 upload already succeeded, the server best-effort deletes the just-uploaded objects rather than leaving them orphaned.
This server never runs EF Core migrations and never creates tables — a schema mismatch at startup fails loudly and tells you to run the CLI once instead of silently improvising.
Each batch item (in
add_artworks/update_artworks) runs in its own SQLiteSAVEPOINT, so one bad item can't corrupt the catalog or block the rest of the batch.
Registering with a client
{
"mcpServers": {
"artshow-catalog": {
"command": "node",
"args": ["C:\\Users\\kaywi\\dev\\CodedByKay.ArtShow.Mcp\\dist\\index.js"]
}
}
}Or with the Claude Code CLI:
claude mcp add artshow-catalog -- node C:\Users\kaywi\dev\CodedByKay.ArtShow.Mcp\dist\index.jsDevelopment
npm run dev # tsc --watch
npm test # build, then run src/test/*.test.ts under node --testSeveral tests read the live artwork.db and site artwork.json
read-only (never mutate) to check real-world parity — they skip gracefully
if those paths don't exist on the machine running them.
Data contract (2026-10)
artwork.json items carry width, height, displayUrl, datePrecision and
media[] after the legacy fields, and data/collections.json is written
alongside it. Both writers (this one and the CLI's) produce byte-identical
output for both files — src/publishing/derive.ts holds the derivations that
must match CodedByKay.ArtShow.CLI/Publishing/MediaDerivation.cs. New image
adds record size and upload a display/<year>/<slug>-2000w.webp when the
original's long edge is over 2000px (media/imaging.ts createDisplay).
src/schema-guard.ts now also requires the CLI's new columns, so run the CLI
once (or dotnet ef database update) before starting a build of this server
against an older DB.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
AI-native art catalogue. Catalogue works, parse provenance, and generate signed RAIs.
Read-only catalog of app-building materials: fonts, APIs, MCP servers, libraries, templates, data.
OAuth-protected, read-only-by-default MCP server for provenance-labeled QuillCaddie project memory.
Read-only access to the Artbook Society published catalog: books, artists, editors and events.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP server that lets AI assistants manage an art catalogue — find paintings, post to social media, upload to galleries, schedule posts, and update metadata.-
- AlicenseAqualityCmaintenanceA local MCP-controlled artifact shelf for agents to publish generated content with stable preview URLs. Provides a shared SQLite registry and HTTP gallery for human browsing.39 npm1MIT
- FlicenseNot gradedqualityBmaintenanceEnables clients to search and retrieve Artsdata entities in English or French, run SPARQL queries against the Artsdata endpoint, fetch the compiled Artsdata schema, and discover the download URL and version of the latest core-minus-provenance dump via the Databus. It exposes these capabilities as MCP-style tools and resources over HTTP, with configurable endpoints, timeouts, row limits, and CORS.-
- AlicenseNot gradedqualityBmaintenanceProvides a local creator asset library MCP server that scans folders to catalog media files, batch-renames them, applies tags, tracks asset lineage between source and finished works, and offers keyword- and BGE-vector-based semantic search. It also lets other content-production MCP servers auto-register their generated outputs into the library for later retrieval and reuse.MIT