Start it
For a first look, keep everything in memory:
docker run --rm -p 127.0.0.1:8080:8080 \
-e SCREENJSON_STORAGE_DRIVER=memory \
ghcr.io/screenjson/screenjson-server:latest
Open http://127.0.0.1:8080 for the library, and
/swagger/ for the API explorer. Nothing survives a restart in memory mode;
set SCREENJSON_STORAGE_DRIVER and SCREENJSON_STORAGE_URL to use a real
database.
Get a token
S=http://127.0.0.1:8080
T=$(curl -s -X POST $S/tokens -d '{"name":"me"}' | jq -r .token)
H="Authorization: Bearer $T"
A token names who’s making each change and who holds a checkout.
Add scripts
ScreenJSON goes straight in:
DOC=$(curl -s -X POST $S/documents -H "$H" --data-binary @screenplay.json | jq -r .id)
Or drop files on the Import page of the web app. With a
Greenlight server configured
(SCREENJSON_GREENLIGHT_SERVERS), Final Draft, Fade In, Fountain, and PDF
files are converted on the way in.
Edit a line
SCENE=$(curl -s $S/documents/$DOC/scenes | jq -r '.[0].id')
EL=$(curl -s $S/documents/$DOC/scenes/$SCENE/elements/action | jq -r '.[0].id')
curl -si $S/documents/$DOC/scenes/$SCENE/elements/action/$EL | grep -i etag
# ETag: "1"
curl -s -X PATCH $S/documents/$DOC/scenes/$SCENE/elements/action/$EL -H "$H" \
-H 'If-Match: "1"' -d '{"text": {"en": "The door opens."}}'
Open the script in the web app first and you’ll see the line change. If
someone else edited it after you read it, the PATCH answers 412 instead
of overwriting their work.
Connect Claude Code
claude mcp add --transport http screenjson http://127.0.0.1:8080/mcp \
--header "Authorization: Bearer $T"
Claude can now list the library, read outlines and scenes, search, and edit lines, with the same validation and revision checks as any other client. Ask it something like “Find every night exterior in this script and tighten the action lines”.
Next
- screenjson-server: what else it does.
- Load a folder of scripts into PostgreSQL with the free importer, then point the server at it.
- Server documentation.