Skip to content
ttyinv

invoice.

An invoice is one Markdown file you own. Write it in the browser, drive it from the terminal, or let an agent edit it — every surface runs the same ttyinv/v2 contract.

AGPL-3.0your draft stays in your browserno account to try it

Four ways in. One file. One document.

Every path below writes the same invoice.md, checked by the same Rust engine against the same contract.

  • cli

    Open-source Rust binary. Offline, scriptable, non-zero exit on a bad document.

    $ ttyinv validate invoice.md
    $ echo $?
    0
    
    $ ttyinv edit set-gap \
        invoice.md --section 2 \
        --gap roomy

    writes invoice.md in place

  • webmcp

    Eight tools the open editor offers a browser agent. Every call shows up in the page, and undo reverses it.

    set_invoice_value
    { "path": "metadata.number",
      "value": "INV-0043" }

    changes the open document

  • api

    REST and MCP for an agent with no browser. Bearer token, nothing stored.

    POST /api/v1/invoices
    Authorization: Bearer
      $TTYINV_AGENT_TOKEN
    
    200 { source, document,
          summary, warnings }

    returns canonical invoice.md

  • markdown

    Your editor, your repository. Diff it, review it, keep it for years.

    ---
    schema: ttyinv/v2
    format: code-comma-dot
    ---
    
    # Interface design sprint

    is invoice.md

invoice.mdttyinv/v2 · one contract · one engine
hosted render · answers 501 · planned

invoice.pdf — created in your browserPDF uses the browser print dialog; PNG and HTML download directly. Nothing is uploaded to make the file.

Where your invoice actually is.

One row per surface. No qualifiers.

Data boundary by surface
SURFACEWHERE THE DOCUMENT LIVESWHAT LEAVES YOUR MACHINE
browser editorin this browser, while the tab is opennothing, until you export or send the file yourself
clion your disknothing; the binary makes no network call
webmcpin the open pagenothing; the agent presses the buttons you press
rest + mcpin the request your agent sendsthe document you post; processed transiently, not stored

Open source, and specific about what ships.

SHIPPED

  • Browser editor: create, edit, validate, export
  • ttyinv CLI: validate, convert, schema, sections, edit
  • REST: create, validate, edit
  • MCP server, and eight WebMCP page tools
  • Browser export: PDF, PNG, HTML

DECLARED, NOT SHIPPED

  • Hosted render: POST /api/v1/invoices/render answers 501
  • One canonical renderer shared by every surface

The route is published before the implementation, so an agent reads an honest refusal today instead of a surprise later.

Start with an empty invoice, or paste Markdown you already have.