# Playing online

Any game on the [games page](https://tabletwin.com/games/) that can be played in the player can
also be played at an **online table**: everyone at their own screen, with a link per seat, and
seats for computer players and for AI agents. Hidden cards stay hidden: the game runs on the server,
and each seat receives only what that seat may see.

## Opening a table

1. Open the game in the [player](https://tabletwin.com/play/) and press **Play online**.
2. Choose for every seat: **Me**, **Someone else** (a person, or their AI agent) or a **computer
   player** (the game's tactics, random choices, or a heuristic from the model).
3. Press **Open the table**. Your page now follows the table, and a panel above the game shows the
   seats and a link for every seat that someone else plays. Copy a link and send it.

Whoever opens a seat's link plays that seat; the link is the key to the seat, so share it only with
the person who plays it. The panel shows who has joined and whose turn it is; the page updates as
soon as someone else has chosen. You can give yourself a name for the others to see. "Leave the
table" goes back to playing on your own; the table's link keeps working.

## What each seat sees

The rules decide, exactly as in the player's "view as":

- a zone with visibility `public` is seen by everyone; `owner` only by its owner; `hidden` by nobody.
  Cards a seat may not see reach its browser as "?": their number, not what they are;
- a decision or a draw with a visibility list (secret choices, private draws) shows its options and
  its outcome only to those players;
- variables are public: a model that wants to keep something secret keeps it in a zone or a secret
  choice (see [the engine](https://tabletwin.com/docs/engine/)).

Only the seat whose turn it is receives the options, and the server checks every answer: the right
seat, the right moment, an option that exists.

## Your own AI agent at the table

Tabletwin is also an **MCP server**, so an AI agent can take a seat. In your AI app, add a custom
(remote) connector with the address

```
https://tabletwin.com/mcp
```

No account or sign-in is needed: a seat's link is the key to that seat, and the agent passes it to
the tools.

| Tool | What it does |
|---|---|
| `tabletwin_games` | The games that can be played online, with their computer players |
| `tabletwin_rules` | A game's summary and the flow of play as a tree |
| `tabletwin_new_table` | Open a table; per seat `agent` (the AI itself), `person` or `computer` (`computer:<player>`). Returns a link per seat |
| `tabletwin_look` | The table as the seat sees it: whose turn, the table, what happened lately and, on its turn, numbered options. `wait: true` waits until it is the seat's turn |
| `tabletwin_choose` | Choose an option by its number |

Ask for example: *"Open a Tabletwin table for Ashmoor Delve, with me as player 1 and you as player 2.
Give me my link, read the rules, and play your hero."* Or give the agent the link of a seat at a
table you opened yourself: *"Play player 1 at this table: &lt;link&gt;."* The agent sees exactly
what its seat may see, no more.

## Storage and privacy

- A table stores the game, the random seed, the seats (with their link keys and the names people
  gave themselves) and the choices made. Nothing else: no accounts, no addresses, no chat.
- Tables are removed 30 days after the last move.
- Only published games can be played online: the games whose rules are already public on the
  [games page](https://tabletwin.com/games/). Your own models and images from the
  [workshop](https://tabletwin.com/docs/workshop/) stay in your browser and cannot be played at an online table.

## For developers

The same tables have a small JSON API (the MCP tools use it too). A seat's key goes in the header
`Authorization: Bearer <key>`.

| Request | Does |
|---|---|
| `GET /api/games` | Playable games |
| `POST /api/tables` `{game, seats: [{kind: "person" \| "bot", agent?, name?}]}` | A new table: `{id, seats: [{kind, agent, token}]}` |
| `GET /api/tables/<id>?since=<k>` | This seat's view: the recorded requests from `k` on (as this seat sees them), whose turn it is, the end |
| `POST /api/tables/<id>/choose` `{step, option}` | Answer the open question (`step`: the index of the question being answered) |
| `GET /api/tables/<id>/live` (WebSocket) | `{"type": "update", steps, turn, end}` whenever the game moves on |

A seat's page is `https://tabletwin.com/play/#table=<id>&seat=<key>`.
