Repository navigation
EN Bridge Connector Telnet
Français · How-to + reference · Published, reviewed by a person · Applies from: 4.2.5
The Telnet connector opens a small virtual terminal on a TCP port: a player connects, types the pairing code their
game shows, then the commands the game declares (lamp on), and each declared command proposes its signal. Nothing
typed is ever run: there is no shell behind it. It is experimental, like every connector (Connectors overview).
Audience, context, and the statuses of what this page rests on
Audience: admin · Context: Reality Bridge
The connectors (email, Telnet, SSH, Open Badges) · contract: experimental · verified by CI (support matrix of 4.4.0, 2026-10-23): Node 22 on Ubuntu (Telnet and SSH not on Windows) · automated checks: jobs
connectors,connector-archive-e2e; CI planreality; 3 test files · people's passes:connectors-real-securitynot run (#79) · known limits:bridge-telnet-clear-text
A quest-n-click-connector telnet process listening on a port, printing the game's banner and prompt, answering the
commands of reality.connectors.telnet, and proposing their signals for the player who linked the session.
- A connector beside a running Bridge, from 4.1.9; this page applies from 4.2.5 (the
quest-n-click-connectorname). -
Verified on: the steps were run on 23 October 2026 against a local Bridge of the game
signals(macOS, Node 22.14, engine 4.4.0,ncas the client): the banner,Linked. Resume word, for 30 minutes: R…, thenlamp onanswered "Click. Somewhere in the garden, a lamp glows." and accepted by the Bridge.
Limit ·
bridge-telnet-clear-textTelnet is clear text: the pairing code and every line cross the network as typed. Keep it on a local network, behind a VPN or TLS (stunnel), or prefer SSH.
-
A running Bridge (Install and run the Bridge) and a game whose
reality.connectors.telnetdeclares its commands (Signals and the manifest):telnet: { banner: 'GARDEN SHED TERMINAL.', prompt: 'shed> ', commands: [{ says: 'lamp on', reply: 'Click.', signal: 'terminal.lamp' }] }
grant where the Bridge's folder is; the connector on the machine players connect to, in a folder holding its
configuration and token. npm run connector -- telnet … in the engine repository, npx quest-n-click-connector telnet … with the package.
-
Grant the connector its token, for the terminal's signals only, with pairing:
# in the engine repository (the Bridge's folder is .cache/bridge) npm run bridge -- grant --connector=shed-telnet --source=terminal --signals=terminal.lamp --pair > telnet.token
-
Write its configuration,
telnet.json:{ "bridge": { "url": "http://127.0.0.1:8787/", "tokenFile": "telnet.token" }, "gameId": "signals", "limits": { "maxBytes": 4096, "maxPerMinute": 60, "timeoutMs": 5000 }, "health": { "port": 9301 }, "telnet": { "port": 2323 } }
-
Start it:
# in the engine repository npm run connector -- telnet --config telnet.jsonIt logs
{"event":"telnet.started","connector":"telnet","port":2323}.
-
Connect as a player would, type the code the game shows, then a declared command:
# on a machine that reaches the port nc 127.0.0.1 2323The terminal prints the banner, asks for the pairing code, answers
Linked. Resume word, for 30 minutes: RABCD-EFGH, thenType help to see what this terminal knows.and the prompt.lamp onprints the command's reply and proposesterminal.lamp.
-
GET http://127.0.0.1:9301/healthanswers 200{"connector":"telnet","ok":true,"detail":"<n> session(s) on port 2323",…};GET /metricsgivesproposed,accepted,duplicates,refused,rejectedInputs,retries. - The Bridge logs
"event":"pairing.confirmed", then"event":"signal.accepted"withterminal.lamp.
| What the terminal says | Cause | Fix |
|---|---|---|
That code does not work. Try again., then Too many wrong codes. Goodbye.
|
A wrong or expired code, three times on one connection | A new code from the game's World link |
| The connection is refused at once | Six wrong codes from that address in ten minutes, across reconnections; or 3 connections already open from it, or 20 in all | Wait; close idle sessions |
Unknown command. Type help. |
Not a declared command (matched whole, lower case) |
help lists them |
(the world did not answer: <code>) |
The Bridge refused the proposal (denied, player, bridge-quota, unreachable…) |
Read the connector's and the Bridge's logs |
| The connection closes after a minute | No complete line for a minute, or not linked within 20 seconds | Type the code at once |
Slow down. / Line too long (512 bytes at most).
|
Over 100 lines a minute / a line over 512 bytes | Type less, shorter |
None on disk. Resume words live in memory for 30 minutes; nothing typed is stored.
Stop the process (SIGTERM: it reads nothing more, drains, exits 0). If its token leaked, revoke it on the Bridge
(revoke --token=<revocation id>) and grant a new one.
-
telnet: { "port": 2323, "host": "127.0.0.1", "limits": { … } }:hostdefaults to127.0.0.1;limitsoverrides the terminal's limits below, by name. - A TCP server that refuses every Telnet option and filters the protocol's bytes.
- The player types the pairing code (or the resume word printed at a previous pairing), then the commands the game
declares.
help,clearandexit(orquit) are the terminal's own. - Each line typed is a new fact: its key is
sha256('telnet:' + session + ':' + line number). A command typed twice proposes its signal twice; the game'soncedecides whether it acts twice.
Limit (limits name) |
Default |
|---|---|
A line (maxLine) |
512 bytes; a longer one is refused whole, Line too long (512 bytes at most).
|
Lines (linesPerMinute) |
100 a minute; beyond, Slow down. and the line is dropped |
Input (bytesPerSecond) |
64 KB a second received; beyond, the connection is closed |
Time to link (pairMs) |
20 seconds |
Time between lines (idleMs) |
1 minute |
A session (sessionMs) |
30 minutes |
Connections per address (perAddress) / in all (maxConnections) |
3 / 20 |
Wrong codes per address (triesPerAddress in triesWindowMs) |
6 in 10 minutes, across reconnections |
Guarantee ·
bridge-telnet-address-limits· referenced · executed onb061c4ae6fbe· scope reviewed One address holds three connections at most, and its wrong codes are counted across reconnections; an unlinked connection is closed.
Nothing typed is stored: a line is matched against the game's commands and forgotten; the Bridge receives only the signal's name. A resume word links a later session to the same player for 30 minutes, in memory. The client's address is used by the operating system for the connection, and counted in memory for the limits; the connector keeps no list of them.
- The code:
connectors/src/telnet/connector.ts,connectors/src/terminal/(limits, lines, the virtual shell). - The threat model:
docs/dev/threat-models/telnet.md. - Tested by
tests/connectors-terminal.test.ts: floods, slow clients, a thousand connections.
Generated publication · publication générée — current documentation · documentation courante: quest'n'click 4.5.3 r1, documentation revision · révision de la documentation b061c4ae6fbeb0be47a11ba8a442ba7e23ecb0a1.
Latest documentation · dernière documentation: https://quest-n-click.cleverapps.io/docs · https://quest-n-click.cleverapps.io/fr/docs; earlier versions · versions précédentes: each release's quest-n-click-docs-<version>.tar.gz · l'archive quest-n-click-docs-<version>.tar.gz de chaque release, https://github.com/Quest-n-Click/quest-n-click/releases
An edit made in this wiki is overwritten at the next publication · une modification faite dans ce wiki est écrasée à la publication suivante.
Edit the source · Modifier la source · Report an error · Signaler une erreur
Index (6)
Start (6)
Play (9)
Install (18)
- Requirements
- Install from the release archive
- Install from npm
- Install from the repository to work on the engine
- doctor: checking your machine
- Image toolchain
- Audio toolchain: ffmpeg, fluidsynth, Furnace, uv
- Upgrade
- Upgrade notes: 4.5
- Upgrade notes: 4.4
- Upgrade notes: 4.3
- Upgrade notes: 4.2
- Upgrade notes: 4.1
- Upgrade notes: v3
- Upgrade notes: v2 to v3
- Coming from web-scumm
- Package reference
- Install troubleshooting
Create a game (55)
- Your first game
- Layout of a created project and of the engine repository
- The working loop
- Content principles and the identity contract
- Rooms
- Geometry: placement, walk zones, masks, layers, camera
- Something is visible but unreachable
- Reactions
- Game commands
- Conditions
- Flags, variables and events: which to use
- Custom code
- Characters
- Items and inventory
- World map
- Dialogues
- Scripts and events
- Moving characters: patrols and walks
- Exits
- Chapters and objectives
- State and saves: persistent or temporary, renaming an id, migrations
- Staging: wide rooms and animations
- The stage: lights, particles, floors
- Skin and fonts
- Title and credits
- Heroes: several characters and hero choice
- Built-in minigames
- A custom minigame
- Translations
- Music in stems
- Sound effects
- Voices: per language and per hero
- Images: prompts, cutting sheets, transparency, scale
- Asset provenance
- The storyboard, source of truth
- Puzzle design
- Classic mechanics
- Review pages
- DSL reference
- Checking your game
- What the solver proves
- Solver options
- Playtests
- Remix
- Speedrun for authors
- The sealed ending
- Production template
- Example games
- Working with an AI
- Build and release a game
- Publish on GitHub Pages
- The static game on Clever Cloud
- Other static hosts
- Sub-path, cache and service worker, incomplete deploys, going back
- Testing on a phone over the LAN
Local Studio (24)
- The local Studio: overview and launch
- Edit a room
- Placement and stage
- Preview, apply, undo
- Storyboard
- Assets and cutting
- Check: validator, solver, critical path, heat, health, coverage
- Before and after captures
- Semantic diff
- Play and replay a session
- Rule explainer
- Language and objectives
- Voices and the heroes × languages matrix
- Map
- Notes
- Remix in the Studio
- Music
- The Assistant: bring your own key
- Demo mode and studio-apply
- Local and LAN security
- Studio API
- Local MCP: setting up each client
- MCP tools
- Studio troubleshooting
Team Studio (21)
- What runs where
- Concepts: revision, transaction, span, lease, preview, build
- Starting as an invited dev
- Working together day to day
- Roles and actions: the full matrix
- Invitations
- Managing members
- Write refused on the hosted Studio: stale base revision (409)
- Write refused on the hosted Studio: span locked (423)
- Recovering after a lost lease, a disconnection or a stale preview
- Comments
- Map and semantic diff
- Publishing builds
- Remote MCP
- The game in Git
- Upgrading the engine of a hosted game
- Hosted assets
- The server's command line
- Health and metrics routes
- Trying it locally with compose.yml
- Known limits
Clever Cloud (23)
- Clever Cloud: overview, cost and prerequisites
- Apps and add-ons
- Domains and TLS
- Keycloak
- Generic OIDC and GitLab
- Configuration
- First deployment
- Backups
- RPO and RTO
- Restore the Studio on a fresh installation
- Redeploys
- Upgrading the server and checking state after a migration
- Limits of going back
- Monitoring
- Security
- Rotating keys
- Recovering admin access
- Changing domain or OIDC provider
- Worker, PostgreSQL or Cellar down
- Exporting the game and leaving the installation
- Retention
- Clever Cloud troubleshooting
- Costs and teardown
Reality Bridge and connectors (16)
- The Reality Bridge: what it is
- Quick start
- Guarantees
- Install and run the Bridge
- Backup and restore
- Several tenants
- Signals and the manifest
- The Bridge's command line
- Connectors overview
- Email connector
- Telnet connector
- SSH connector
- Open Badges connector
- The connector SDK
- Security: Biscuit and signatures
- Bridge and connector troubleshooting
Contribute (25)
- Welcome
- Developer setup
- The dev loop
- Before a pull request
- Conventions
- Writing documentation
- Architecture
- Code tour
- Import boundaries
- Which tests run when
- Mutation testing
- The coverage ratchet
- The quality baseline
- CI explained
- Field passes
- Benchmarks
- Releasing
- npm packages
- Decisions and ADRs
- Governance
- Bot pull requests
- Contributing with AI agents
- Security policy
- Code of conduct
- Licences and credits