Guide
POLYTONE for agents
The toolchain speaks machine: ptc check --json returns structured teaching errors, and polytone-mcp exposes check, run, test, fmt, doc, and render as MCP tools.
A teaching error is already a repair prompt: one line that names the canonical form to write instead. Since Sprint 54 the same diagnostic is available as data — ptc check --json emits the polytone-diagnostics document on stdout, with the position structural instead of embedded in prose:
record User:
name: Text
age: Int
fn main() -> Void:
let u = User(name: "ada", age: 36)
if u.age:
print("{u.name}")The document is a stability contract: fields are only ever added (never renamed or removed), version bumps only on a breaking change, line/col are 1-based (0 = no position), phase is one of read | parse | module | type, diagnostics from imported modules carry their own file, and the exit code is 0 exactly when ok is true. severity is always "error" today — the field is reserved. The classic text output is unchanged.
Since Sprint 56 the toolchain also computes context, not just diagnostics: ptc context emits the minimal true slice for an edit — the file's own items plus the pub surface of its direct imports as structured signatures with docs, current diagnostics, and at --at the one enclosing item with its body. Never other bodies, never the prelude (that surface is frozen and lives in one provider-cached language card):
import greeting
fn main() -> Void:
for name in ["ada", "grace"]:
print(greeting.greet(name))polytone-mcp is the same machinery as an MCP server: newline-delimited JSON-RPC over stdio, seven tools — check (the diagnostics document), context (the slice above), run, test, fmt, doc, render. Register it and any MCP-speaking agent has the whole verified loop:
claude mcp add polytone -- /path/to/polytone-mcp
# run it from your project directory — file arguments
# resolve against the server's cwd→ {"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"check","arguments":{"file":"login.pt"}}}
← {"id":2,"jsonrpc":"2.0","result":{"content":[{"text":
"{ …polytone-diagnostics, ok: false, line 7, col 8… }",
"type":"text"}],"isError":false}}Tool failures come back as teaching errors in the result (isError: true) — check is the exception: diagnostics are data, so isError stays false and agents branch on the payload's ok. Boundary note: run, test, and render execute programs with the server's file-system access and no instruction budget, exactly like ptc run — point the server at code you trust.