Skip to content

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.

Edit in the playground

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 }
    }
  }

rag pipeline
build it up