@mt-tl/studio
v0.1.9
Published
Self-hosted interactive explorer + playground for an MTProto TL schema — the "Swagger/Redoc for MTProto". Point it at your .tl layers, get a static doc site with a layer-aware reference, scenario guides and a try-it playground.
Maintainers
Readme
@mt-tl/studio
A self-hosted, interactive explorer + playground for an MTProto TL schema — the
"Swagger/Redoc for MTProto". Point it at your .tl layers and get a static site with a
layer-aware reference, a full schema view, a changelog, prose guides, and a live "try it"
playground that speaks real MTProto from the browser.
It ships a pre-built static app; a small CLI assembles a site by generating the data
files (api.json, wire.json, …) from your schema and copying them next to the app.
Two ways to use it
- (a) Alongside
@mt-tl/server— deploy the site next to your gateway and read your own docs / run live calls against yourws://server (try-it + scenario runner + listener). - (b) Standalone docs (like Docusaurus) — point it at a directory of
.tlfiles, publish the static site (e.g. GitHub Pages) for your team. No server required to browse.
Install
Requires Node 20+. Installs a mt-tl-studio CLI; the package ships the pre-built
explorer UI, so there's nothing else to set up.
npm i -D @mt-tl/studio # or: yarn add -D @mt-tl/studioBuilding a server with
@mt-tl/server? The framework docs have a walkthrough of Studio in context: the Studio guide.
Quick start
Put your per-layer schema as scheme_<N>.tl (one file per layer; each is the full schema
at that layer) in a directory, then build:
mt-tl-studio build --layers ./schema --out ./site
npx serve ./site # browse http://localhost:3000--layers accepts either raw scheme_<N>.tl files or frozen scheme_<N>.json
snapshots (the framework's mt-tl freeze output); .json wins when both exist.
Using a custom filename prefix? Pass --prefix <p> (default scheme_) — it must
match the prefix the layers were frozen with, e.g. --prefix layer_ for layer_<N>.json.
Authoring docs (incremental)
Everything below is optional — add it over time. Re-run build to regenerate.
mt-tl-studio build \
--layers ./schema --out ./site \
--descriptions ./descriptions \ # <symbol>.md → rendered on method/type/constructor pages
--scenarios ./scenarios \ # <folder>/<guide>.md → grouped guides (tree in the sidebar)
--changelog ./changelog # <layer>.md → prose intro above the auto-diff- descriptions/ —
account.checkFields.md,User.md, … Markdown shown on each page. - scenarios/ — guides in folders, e.g.
auth/login.md. Embed a fenced```scenarioblock (mt-tl-test YAML) to make a guide runnable — the studio shows a ▶ badge and an "open as interactive scenario" button that pre-fills the builder. - changelog/ —
205.mdetc.; the per-layer prose sits above the auto-generated added / changed / removed diff.
Try it (live calls)
In the connection bar: set your server ws:// URL and paste its RSA public key (PEM)
(clients pin it for the handshake). Then call methods on the method page, build multi-user
scenarios, or watch pushed updates on the Listen page. Auth is per-request: auth:false
methods run anonymously; for logged-in flows write an auth recipe — a small ES module
that default-exports async (ctx) => { … } and does your login (it may import your own
crypto to sign at runtime).
By default the client speaks the mt-tl MTProto profile (RSA-pinned via the PEM you
provide, plain intermediate framing) — for servers built with @mt-tl/server.
Talking to real Telegram. Tick obfuscated transport (Telegram) in the key panel and the client switches to the WebSocket transport Telegram requires (
Sec-WebSocket-Protocol: binary+ the obfuscated/AES-CTR stream). Paste Telegram's server RSA key, set yourapi_id(from my.telegram.org), point the URL at a Telegram WS endpoint (e.g.wss://venus.web.telegram.org/apiws_testfor the test DC), and unauthenticated calls likehelp.getConfigwork. Logged-in methods still need the full Telegram auth flow.
CLI
mt-tl-studio build --layers <dir> --out <dir>
[--prefix <p>] [--protocol <dir>] [--descriptions <dir>] [--scenarios <dir>] [--changelog <dir>] [--recipes <dir>]
[--default-url <ws-url>] [--default-key <pem-file>] [--default-obfuscated]The reference renders your business API only — low-level MTProto types (handshake,
service messages, vector, rpc_error, …) are hidden; the initConnection/invokeWithLayer
wrappers stay. The playground still loads the full protocol, so live calls work.
--prefix <p>— snapshot filename prefix (defaultscheme_). Must match the prefix the layers were frozen with (mt-tl freeze … --prefix).--protocol <dir>— your overridden protocol schema (dir or.tl), the same one the server runs with. Hides its low-level types from the docs and lets the playground speak it.--recipes <dir>— bundle ready auth recipes (<name>.js/.mjsES modules, optional<name>.args.json) so your team reuses them out of the box (shown alongside locally-saved ones).--default-url/--default-key— bake a defaultws://URL + server RSA public-key PEM into the site (config.json); the connection bar seeds from them (a user's own saved value still wins). Handy for a team deployment so nobody pastes the URL/key by hand.--default-obfuscated— default the obfuscated WebSocket transport on. Required to talk to real Telegram (which also needs its server RSA key + yourapi_id); leave it off for an@mt-tl/servergateway.
Host <out> on any static host (GitHub Pages, S3, nginx, …).
