launch, negotiate, call¶
The handshake cinegram mcp performs. An agent host launches the server on stdin and stdout, agrees a protocol version with it, asks what it can do, and only then calls a tool — here sheet, which comes back as a picture of a whole scenario.
The source — 05-ai-systems/04-mcp-handshake.dgm
%% The handshake `cinegram mcp` performs. An agent host launches the server on
%% stdin and stdout, agrees a protocol version with it, asks what it can do,
%% and only then calls a tool — here `sheet`, which comes back as a picture of
%% a whole scenario.
%% ---
%% Every message below is one the server in this repository actually sends or
%% answers: five tools, one resource, and a `tools/call` that returns an image
%% rather than text. The version pinned in the badge is the protocol revision
%% the server negotiates.
%% ---
%% The flows carry no `label`. A sequence diagram draws its own message text,
%% so a label would print a second copy on top of it — and where the same pair
%% exchanges several messages in the same direction, `msg:` picks which arrow a
%% flow travels rather than leaving the compiler to guess.
sequenceDiagram
participant A as Agent
participant C as MCP Client
participant S as cinegram mcp
A->>C: I have a .dgm to check
C->>S: initialize
S-->>C: result: protocolVersion, capabilities
C->>S: notifications/initialized
C->>S: tools/list
S-->>C: 5 tools, 1 resource
A->>C: show me the whole scenario
C->>S: tools/call sheet {path}
S-->>C: image/png + cell manifest
C-->>A: contact sheet
scenario "launch, negotiate, call" { speed: 1.0 }
step spawn "The host starts the server as a subprocess" {
desc: "There is no port and no daemon. The client launches `cinegram mcp` and speaks JSON-RPC down its stdin and stdout, which is why the server needs no configuration beyond the command that starts it."
flow A -> C { dur: 600ms, msg: 1 }
note S "stdio transport\nno port, no server to run"
}
step initialize "The client opens with initialize" {
desc: "The first message names the protocol version the client would like to speak and what it supports. Nothing else may be sent until this exchange has completed — a tool call before it is a protocol error."
focus S
flow C -> S { dur: 700ms, msg: 1 }
}
step negotiate "The server answers with the version it will speak" {
desc: "The reply pins the revision for the whole session. A client that asked for something newer either accepts what it is offered here or closes the connection; there is no renegotiation later."
flow S -> C { dur: 700ms, msg: 1, style: response }
set S { badge: "2025-06-18", state: ok, color: "#16a34a" }
}
step ready "A notification closes the handshake" {
desc: "`notifications/initialized` has no reply, because it is not a question. It is the client saying it has finished reading the server's capabilities, and it is the moment the session becomes usable."
flow C -> S { dur: 500ms, msg: 2 }
}
step discover "The client asks what the server can do" {
desc: "Five tools — lint, narrate, mermaid, frame and sheet — plus one resource, the language reference itself. Discovery is why the host needs no cinegram-specific code: the schemas arrive at runtime."
seq {
flow C -> S { dur: 600ms, msg: 3 }
flow S -> C { dur: 600ms, msg: 2, style: response }
}
gauge S { label: "tools", value: 5 }
}
step call "The agent picks a tool and the client calls it" {
desc: "The agent chose `sheet` from the schemas it was handed. The call carries `path` — or `source` for a draft that was never saved, never both, a rule the handler enforces rather than trusting the client to."
seq {
flow A -> C { dur: 500ms, msg: 2 }
flow C -> S { dur: 600ms, msg: 4 }
}
focus S
}
step image "The result is a picture, not a paragraph" {
desc: "`sheet` renders the scenario in a headless Chrome and answers with a PNG plus the manifest that maps each cell to its step. A model that can see the sheet can check the animation it just wrote in one look."
seq {
flow S -> C { dur: 700ms, msg: 3, style: response }
flow C -> A { dur: 600ms, msg: 1, style: response }
}
}