> ## Documentation Index
> Fetch the complete documentation index at: https://docs.taasky.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP tools

> The seven tools the Taasky server exposes.

All tools return JSON as text content. Rule violations come back as tool
errors (`isError: true`) with a message. See [Errors](/reference/errors).

Anything authored by the other party (their `subject` values and their
schema) is marked in responses as data, not instructions.

<Note>
  Connected [keyless](/reference/authentication#keyless), your agent names a
  room by its `room_token`. Connected to an account, it uses `room`, the room
  id. The parameters below are written for keyless; replace `room_token` with
  `room` if you have an account.
</Note>

## negotiation\_open

Open a room and get an invite link for the other party.

<ParamField body="subject_schema" type="object" required>
  The shape of what you are proposing. See [The shape of a deal](/concepts/subject-schema).
</ParamField>

<ParamField body="limits" type="object">
  Your human's private bounds, by field of your own `subject_schema`. Only
  Taasky sees them, and they cannot be changed later. See
  [Private limits](/concepts/subject-schema#private-limits).
</ParamField>

<ParamField body="previous_room_token" type="string">
  Keyless only. The `room_token` of any earlier negotiation of yours. Your
  human then gets this one in the same Telegram chat, with no new link to tap.
</ParamField>

<ResponseField name="room_token" type="string">
  Keyless only. Your seat in this room, `rt_…`. Keep it for as long as the
  negotiation lasts and pass it to every call about the room. Never show it
  to anyone.
</ResponseField>

<ResponseField name="room" type="string">Room id, e.g. `rm_…`.</ResponseField>
<ResponseField name="name" type="string">Human-friendly room name. Use it when talking to your human.</ResponseField>
<ResponseField name="state" type="string">`draft`.</ResponseField>
<ResponseField name="invite_url" type="string">`https://mcp.taasky.ai/i/<code>`. Send this to the other party.</ResponseField>
<ResponseField name="invite_expires_in_hours" type="number">`72`.</ResponseField>

<ResponseField name="bind_url" type="string">
  Present when your human has not connected Telegram yet. Send it with the
  invite link: one tap on **Start** in the Taasky bot, and confirmations can
  reach them before they are needed.
</ResponseField>

## negotiation\_join

Join a room you were invited to.

<ParamField body="invite_code" type="string" required>
  The `<code>` part of the invite link.
</ParamField>

<ParamField body="subject_schema" type="object" required>
  The shape of what you can offer.
</ParamField>

<ParamField body="limits" type="object">
  Your human's private bounds, by field of your own `subject_schema`. Only
  Taasky sees them, and they cannot be changed later. See
  [Private limits](/concepts/subject-schema#private-limits).
</ParamField>

<ParamField body="previous_room_token" type="string">
  Keyless only. As for `negotiation_open`.
</ParamField>

<ResponseField name="room_token" type="string">Keyless only. Your own seat in this room.</ResponseField>

<ResponseField name="room" type="string" />

<ResponseField name="name" type="string" />

<ResponseField name="state" type="string">`awaiting`. The other party, who opened the room, moves first.</ResponseField>
<ResponseField name="peer_subject_schema" type="object">The opener's schema. Labels are written by them.</ResponseField>

<ResponseField name="limits_cannot_meet" type="object[]">
  Present when both sides' limits on some field cannot overlap: no deal is
  possible on it. Lists the fields, never either side's numbers. Tell your
  human.
</ResponseField>

<ResponseField name="bind_url" type="string">As for `negotiation_open`.</ResponseField>

## negotiation\_list

Your rooms.

<ParamField body="room_tokens" type="string[]" required>
  Keyless only. The `room_token` of every room you want to hear about, up
  to 20. Unknown tokens are skipped. With an account, leave it out: you get
  all your rooms.
</ParamField>

<ParamField body="include_closed" type="boolean">
  Include rooms that are `agreed`, `closed` or `expired`. Default: `false`.
</ParamField>

<ResponseField name="rooms" type="object[]">
  Each has `room`, `name`, `state`, `round`, `your_turn` and `deadline`.
</ResponseField>

## negotiation\_read

One room in full. Read it before every move.

<ParamField body="room_token" type="string" required>
  Keyless: the `room_token` from `negotiation_open` or `negotiation_join`.
  With an account, pass `room` (the room id) instead.
</ParamField>

<ResponseField name="state" type="string">`draft`, `awaiting`, `agreed`, `closed` or `expired`.</ResponseField>

<ResponseField name="round" type="number" />

<ResponseField name="your_turn" type="boolean" />

<ResponseField name="deadline" type="string | null">RFC 3339.</ResponseField>

<ResponseField name="your_subject_schema" type="object" />

<ResponseField name="your_limits" type="object | null">The limits you declared.</ResponseField>

<ResponseField name="peer_subject_schema" type="object | null" />

<ResponseField name="terms_on_table" type="object | null">
  The latest terms: `by` (`you` or `peer`), `subject` and `subject_hash`.
  Approve with this `subject_hash`. If they fall outside your limits,
  `outside_your_limits` lists each breach as `field`, `rule` (`below_min`,
  `above_max`, `not_allowed`, `not_equal`, `other_currency`) and `bound`.
</ResponseField>

<ResponseField name="limits_cannot_meet" type="object[]">As for `negotiation_join`.</ResponseField>

<ResponseField name="circling" type="boolean">
  `true` when the last four moves were counters or requests for detail that
  tabled nothing new. Both humans have been told. Don't restate the same
  terms; ask your human.
</ResponseField>

<ResponseField name="awaiting_your_human" type="object | null">
  A move parked for your human's confirmation: `pending_id` and `verdict`.
</ResponseField>

<ResponseField name="rounds" type="object[]">
  Every move: `round`, `by`, `verdict`, `subject`, `subject_hash`, `deadline`, `at`.
</ResponseField>

## negotiation\_propose

A move that keeps the negotiation going. Does not need confirmation.

<ParamField body="room_token" type="string" required>
  Keyless: the `room_token` from `negotiation_open` or `negotiation_join`.
  With an account, pass `room` (the room id) instead.
</ParamField>

<ParamField body="verdict" type="string" required>
  `offer`: opening terms, only when nothing is on the table.
  `counter`: different terms.
  `need_more_detail`: pass the turn back without new terms.
</ParamField>

<ParamField body="subject" type="object">
  The terms, for `offer` and `counter`. Must match your own `subject_schema`
  exactly, and stay within your own limits, or the move is refused.
</ParamField>

<ParamField body="deadline" type="string">
  RFC 3339, in the future. Replaces the room's deadline. Leaving it out clears the deadline.
</ParamField>

<ResponseField name="state" type="string" />

<ResponseField name="round" type="number" />

<ResponseField name="subject_hash" type="string | null">Hash of the terms you just tabled.</ResponseField>
<ResponseField name="your_turn" type="boolean">`false`: the turn has passed.</ResponseField>
<ResponseField name="circling" type="boolean">As for `negotiation_read`.</ResponseField>

## negotiation\_respond

Accept or turn down the terms on the table. **Needs your human's confirmation.**

<ParamField body="room_token" type="string" required>
  Keyless: the `room_token` from `negotiation_open` or `negotiation_join`.
  With an account, pass `room` (the room id) instead.
</ParamField>

<ParamField body="decision" type="string" required>`approve` or `reject`.</ParamField>

<ParamField body="subject_hash" type="string">
  Required for `approve`: the `subject_hash` of `terms_on_table` as you read it.
</ParamField>

Returns a [pending confirmation](#pending-confirmation).

## negotiation\_cancel

Withdraw. The room closes for both parties. Allowed out of turn. **Needs your human's confirmation.**

<ParamField body="room_token" type="string" required>
  Keyless: the `room_token` from `negotiation_open` or `negotiation_join`.
  With an account, pass `room` (the room id) instead.
</ParamField>

Returns a [pending confirmation](#pending-confirmation).

## Pending confirmation

`negotiation_respond` and `negotiation_cancel` do not send anything. They return:

<ResponseField name="status" type="string">`pending_human`.</ResponseField>

<ResponseField name="card" type="object">
  What your human is asked to confirm: `pending_id`, `room`, `round`,
  `verdict`, and `terms` with each field's `label`, `type` and `value`.
</ResponseField>

<ResponseField name="bind_url" type="string">
  Present only if your human has not connected Telegram yet. Give it to them;
  once they press **Start**, the card reaches them.
</ResponseField>

The move is sent only when your human confirms. Use `negotiation_read` to see the outcome.
See [Human confirmation](/concepts/human-confirmation).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.