Seven read-only tools over the catalog database: list_titles, search_scripts,
get_script, get_edition, list_files, find_file and collection_stats. Writing
stays in the CLI, where the effect of a command is visible.
Transport is Streamable HTTP on the JDK's com.sun.net.httpserver, so Gson is
the only new dependency. No sessions are kept: every tool is stateless, so
Mcp-Session-Id is omitted and GET returns 405 rather than opening an SSE
stream we would never write to. Requests carrying a non-loopback Origin are
rejected, since a page in a browser can POST to localhost.
Tool results are formatted text rather than JSON. The consumer is a model
reading the answer, and prose costs less context than the same data wrapped
in objects.
Required arguments are validated against each tool's inputSchema before
dispatch, so a missing parameter is an explicit tool error instead of a
result computed from a default. find_file groups by the canonical lowercase
path, otherwise an extracted directory and its ISO look like two files.
Database access is serialized on one lock because sqlite-jdbc shares a single
connection; the workload is read-only and single-client.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Script pipeline:
- decode: ScriptDecypher from :core into a content-addressed cache keyed by
blob SHA-1, so a script shared by several images is decoded once. Cache
invalidation is driven by artifact.tool_version, i.e. the pinned :core tag.
- find/cat: FTS5 index over decoded bodies. tokenchars '_' keeps identifiers
whole; a query that fails to parse as FTS5 is retried as a quoted phrase.
Catalog entities:
- analyze: MetadataDetector reads dane/application.def for build date, game
version, engine version and episodes. The APPLICATION object is located by
type, not by name, since it is GAME, UFO or PIRACI depending on the title.
CREATIONTIME is recorded separately from release_date because it is the
project creation date, shared across a whole series.
- promote: builds titles and editions. KnownHashes entries conflate levels
("Reksio i UFO (pierwsza wersja)" is title plus edition label), so the
parenthetical is split off and both UFO releases land under one title.
Editions are merged on a fingerprint of engine DLL plus application.def
hash; the DLL alone cannot separate the Herkules/Odyseusz two-in-one disc.
- set/lang: manual metadata a detector cannot infer - provenance, language
lists with roles, engine/compiler/date overrides. Re-running promote only
touches mechanical fields and leaves curated ones intact.
Schema:
- edition is rebuilt: dll_sha1 loses UNIQUE, since the two-in-one disc shares
one engine library across two games. fingerprint becomes the merge key and
*_override columns hold curated values. The rebuild only runs on an empty
table; otherwise it fails loudly rather than dropping curated data.
- script_fts, an FTS5 virtual table keyed by blob rather than by file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>