@talqing/mcp 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/SKILL.md +118 -36
  2. package/package.json +1 -1
  3. package/tools.json +84 -0
package/SKILL.md CHANGED
@@ -37,8 +37,10 @@ An agent is a single object, `config`, plus what you attach to it:
37
37
  - **`prompt`** — the system prompt. This is where the agent's behaviour lives.
38
38
  - **`greeting`** — the line spoken on connect, and on the way in from a
39
39
  handoff. Voice and video only. `greeting_interruptible: false` makes the
40
- caller unable to cut it off (cascade only); a greeting speaking the recording
41
- notice is always protected.
40
+ caller unable to cut it off (cascade only). To tell callers they are recorded,
41
+ set `recording.notice` to the sentence and put `{{recording.notice}}` in the
42
+ greeting where it should be spoken; it plays uninterruptibly, needs recording
43
+ on and a cascade pipeline, and `null` means no notice.
42
44
 
43
45
  Both are personalized per session: `{{userdata.field}}` is substituted from
44
46
  the session's userdata when the agent starts, so *"You are speaking with
@@ -55,22 +57,28 @@ An agent is a single object, `config`, plus what you attach to it:
55
57
  Two more roots are filled in from outside the session, and nothing inside one
56
58
  can write either. They differ in who fills them.
57
59
 
58
- **`{{system_vars.…}}` — ours.** Six keys, and any other is rejected at save;
59
- `GET /v1/catalog` returns them as `system_vars`.
60
-
61
- - `{{system_vars.human_phone_number}}` — the other party, the caller inbound
62
- and the person you called outbound
63
- - `{{system_vars.agent_phone_number}}` — your number on this call
64
- - `{{system_vars.direction}}` — `inbound` or `outbound`
60
+ **`{{system_vars.…}}` — ours.** Seven keys, and any other is rejected at save;
61
+ `GET /v1/catalog` returns them as `system_vars`, each with the `channels` it
62
+ has a value on.
63
+
64
+ - `{{system_vars.human_phone_number}}` — the person's number: who called or
65
+ wrote to you, or whom you called or wrote to
66
+ - `{{system_vars.agent_phone_number}}` — your number in this session
67
+ - `{{system_vars.direction}}` — `inbound` when they started the call or chat,
68
+ `outbound` when you did
69
+ - `{{system_vars.channel}}` — where the session is happening: `phone_call`,
70
+ `whatsapp_call`, `whatsapp_message`, `web_call`, `chat`, `telegram` or `stream`
65
71
  - `{{system_vars.now}}` — `2026-08-19T19:26:59+05:30`, the machine format;
66
72
  send it to an API, never read it aloud
67
73
  - `{{system_vars.date}}` — `Wednesday, 19 August 2026`
68
74
  - `{{system_vars.time}}` — `7:26 PM`
69
75
 
70
- The first three come from the call, so they are empty on web calls and on text
71
- conversations — do not make one the only source of a fact the agent needs. One
76
+ The first three come from a phone number — phone calls, WhatsApp calls,
77
+ WhatsApp chats and media streams — so they are empty on web calls, API chats
78
+ and Telegram; do not make one the only source of a fact the agent needs. One
72
79
  agent can greet a caller and someone it called differently by branching on
73
- `{{system_vars.direction}}`. The last three come from the agent's
80
+ `{{system_vars.direction}}`, and one agent on several channels can adapt by
81
+ branching on `{{system_vars.channel}}`. The last three come from the agent's
74
82
  **`timezone`** and work on every channel; using one without setting `timezone`
75
83
  is a save error. In a prompt or greeting the clock is frozen at the moment the
76
84
  agent started (re-resolving would throw away the model's prompt cache); inside
@@ -107,8 +115,9 @@ An agent is a single object, `config`, plus what you attach to it:
107
115
  Four things to get right:
108
116
 
109
117
  - **They are visible to the model.** Anything in `vars` may be read aloud or
110
- repeated back. A credential belongs in a workspace secret, read as
111
- `{{secrets.NAME}}` from a tool, where the model never sees it.
118
+ repeated back. A credential belongs in `secrets` on the same request when it
119
+ is per session, or in a workspace secret when it is shared — either is read
120
+ as `{{secrets.NAME}}` from a tool, where the model never sees it.
112
121
  - **`required: true` refuses the session** that supplies no value for a
113
122
  variable with no `default` — the call token, the dial, the batch and the chat,
114
123
  before anything is compiled and before any provider is called.
@@ -649,17 +658,21 @@ states what to add; do not try to turn the derived silence off.
649
658
  this tool run's own state, `{{userdata.field}}` the session's state,
650
659
  `{{system_vars.field}}` what the platform knows about this session,
651
660
  `{{vars.field}}` what the tenant supplied for it, and `{{secrets.NAME}}` a
652
- workspace secret. A string that is exactly one template token keeps the resolved
653
- value's type. Every one of these works in a URL, in the query, in the body **and
654
- in headers**. A token whose root is not one of those six is an error at save,
655
- not text.
656
-
657
- `system_vars` is read-only, and its six keys are the same ones the agent's prompt
658
- reads: `human_phone_number`, `agent_phone_number`, `direction`, `now`, `date`,
659
- `time`. So a tool can POST the caller's number to a CRM, stamp a record with
660
- `{{system_vars.now}}`, or branch an `if` on the direction without the agent
661
- having to ask. The phone-call keys are empty on web calls, on text conversations
662
- and in a dashboard test run; the clock keys resolve wherever the agent has a
661
+ secret — the session's own if it brought one of that name, else the workspace's.
662
+ A string that is exactly one template token keeps the resolved value's type.
663
+ Every one of these works in a URL, in the query, in the body **and in headers**.
664
+ A token whose root is not one of those six is an error at save, not text.
665
+ **A secret may only be sent by an `http` operation or read by a `code`
666
+ operation**: `{{secrets.…}}` in any other operation (`say`, `set_variable`,
667
+ `if`, `frontend_rpc`, `generate_reply`, a handoff…) is refused at save, because
668
+ it would be spoken, shown or stored.
669
+
670
+ `system_vars` is read-only, and its seven keys are the same ones the agent's prompt
671
+ reads: `human_phone_number`, `agent_phone_number`, `direction`, `channel`, `now`,
672
+ `date`, `time`. So a tool can POST the person's number to a CRM, stamp a record
673
+ with `{{system_vars.now}}`, or branch an `if` on the direction or the channel
674
+ without the agent having to ask. The phone keys are empty on web calls, API chats,
675
+ Telegram and in a dashboard test run; the clock keys resolve wherever the agent has a
663
676
  `timezone`, and read the time the **tool ran** rather than the time the call
664
677
  started.
665
678
 
@@ -916,7 +929,7 @@ message, draft an opening line, take a shipping address mid-call.
916
929
  reads `{{vars.name}}` for the values the run was given, and
917
930
  `{{system_vars.now}}` / `.date` / `.time` when `timezone` is set. It does
918
931
  **not** read `{{system_vars.human_phone_number}}` / `.agent_phone_number` /
919
- `.direction` — there is no call.
932
+ `.direction` / `.channel` — there is no session.
920
933
  - **`llm`** — one model, with the same `fallback`, `reasoning_effort`,
921
934
  `priority` and `builtin_tools` an agent's LLM has. A provider tool runs inside
922
935
  a step rather than as one, so it costs no steps and real seconds. It is the
@@ -1054,10 +1067,11 @@ rest — it never refuses for load. `run_task_batch` queues up to 1000 runs of o
1054
1067
  call, all or nothing: one invalid item refuses the batch, naming `runs[i]`. Give
1055
1068
  each run `metadata` (≤16 string labels, e.g. `{candidate_id: "c_42"}`) and an
1056
1069
  `idempotency_key`: resending a key returns the existing run (`deduplicated`)
1057
- instead of starting another, and the same key with a different request is a
1058
- `409`. Read results with `list_task_runs` (filter by `task_id`, `status`,
1059
- `metadata=key:value`, a creation window) and `get_task_run`, or subscribe a
1060
- webhook to `task_run.completed`, sent once per run as it finishes.
1070
+ instead of starting another — even after the task was republished — and the same
1071
+ key with a different request is a `409`. Read results with `list_task_runs`
1072
+ (filter by `task_id`, `status`, `metadata=key:value`, a creation window) and
1073
+ `get_task_run`, or subscribe a webhook to `task_run.completed`, sent once per run
1074
+ as it finishes.
1061
1075
 
1062
1076
  **Retries.** A background run is tried again — at most 3 tries — when its
1063
1077
  worker stopped under it, or when the model provider failed transiently before
@@ -1450,11 +1464,47 @@ Replies are answered by the agent on the sender's
1450
1464
  `{{userdata.<column>}}` and the whole template, buttons included, as its own
1451
1465
  first message — so write that agent's prompt against the CSV's column names.
1452
1466
 
1467
+ A tapped quick-reply button reaches the agent as its text; the item's `content`
1468
+ keeps the button's `payload` (never shown to the agent) and `replied_to`, the
1469
+ template it answers. Photos reach an agent whose model has `vision: true`; any
1470
+ other agent is told to ask for a description, so pick a vision model for a
1471
+ number people send photos to. Voice notes, video and documents are not read.
1472
+
1473
+ **One message to one person** is `create_conversation_item`, not a batch. `to`
1474
+ is a `conversation_id`, or `number` (your WhatsApp sender, E.164) plus `peer`
1475
+ (their number) to reach someone with no conversation yet. Four `type`s:
1476
+
1477
+ - `template` — an approved template with every variable filled
1478
+ (`template.variables`); may go any time.
1479
+ - `agent_text` — free text sent as the agent's own message.
1480
+ - `note` — background for the agent, never delivered (any contact, PSTN ones too).
1481
+ - `instruct` — the agent writes and sends the next message itself, in the
1482
+ conversation's language, without ever saying it was instructed. Refused with
1483
+ `voice_session_live` while they are on a call with the agent.
1484
+
1485
+ WhatsApp allows free text only within **24 hours of their last message or
1486
+ call** (`ref.whatsapp_window_expires_at`). Outside it `agent_text` and
1487
+ `instruct` are refused with `whatsapp_window_closed`, unless
1488
+ `on_window_closed: {opener: {id, variables}}` names a template to send first:
1489
+ the text is then `held` until they reply, and `expired` after 7 days. Prefer an
1490
+ opener over a bare template when what you want to say is free-form.
1491
+ `userdata` on a post joins the contact's and is what the agent answering their
1492
+ reply starts from. Send an `idempotency_key` when retrying is possible. A
1493
+ provider refusal still stores the item, `delivery_status: failed` (nothing resends it). While
1494
+ they have an open chat, post anything but a note into that chat's conversation:
1495
+ another one is refused with `chat_open_elsewhere`.
1496
+
1453
1497
  ## Secrets, keys and webhooks
1454
1498
 
1455
1499
  **Secrets** are workspace values referenced as `{{secrets.NAME}}` from tool
1456
1500
  operations and integration config. They are write-only: once stored, only the
1457
- runtime resolves them.
1501
+ runtime resolves them. A session can also bring its own, as `secrets` on the
1502
+ request that starts it; for that session they join the workspace's under the
1503
+ same `{{secrets.NAME}}`, the session's value winning. A tool that reads a name
1504
+ that is not a workspace secret saves with a warning, and starting a session
1505
+ without supplying it is refused — an inbound call or chat, which has no
1506
+ request, gets one only from the inbound webhook below. Integration and carrier
1507
+ credentials and MCP server headers must be workspace secrets.
1458
1508
 
1459
1509
  **BYOK.** Talqing runs agents on the workspace's own provider API keys and has
1460
1510
  none of its own. `list_provider_keys` says which providers are configured, and
@@ -1465,7 +1515,21 @@ there, tell them the key has to be added before the agent can publish.
1465
1515
 
1466
1516
  **Webhooks** are workspace-wide and fire for every agent. `event_types` lists
1467
1517
  what can be subscribed to, and `webhook_deliveries` is where to look when one
1468
- seems silent.
1518
+ seems silent. `session.refused` fires for every inbound call or channel chat
1519
+ turned away before an agent ran.
1520
+
1521
+ **The inbound webhook** is how an inbound PSTN call, WhatsApp call or new
1522
+ WhatsApp/Telegram chat gets what an outbound request would carry. An agent with
1523
+ `inbound_webhook: true` has Talqing POST `session.request` (channel, numbers,
1524
+ `contact_key`, the opening message) to the workspace's one URL
1525
+ (`set_inbound_webhook`) before the session starts; the answer may set `vars`,
1526
+ `secrets`, `agent_override`, `metadata` and `userdata`, each meaning what it
1527
+ means on `create_outbound_call`. No valid answer within 3 s **refuses the
1528
+ session** (`inbound_webhook_failed`, reason in `error`), so publishing such an
1529
+ agent needs the webhook set, and `test_inbound_webhook` checks a reply before
1530
+ real callers depend on it. A chat asks once, when it opens. `metadata` — the
1531
+ caller's own labels — appears on the call or chat and filters `list_calls` and
1532
+ `list_chats` (`metadata=key:value`).
1469
1533
 
1470
1534
  ## Running an agent, and reading what happened
1471
1535
 
@@ -1488,9 +1552,14 @@ every agent the session runs and is gone when the session ends. Use `userdata`
1488
1552
  for facts about the person and `vars` for configuration of the session; unlike
1489
1553
  `userdata`, `vars` is never written onto the caller's contact record and no tool
1490
1554
  can change it mid-session. An empty string is a deliberate blank, not a request
1491
- for the default. The model can see the values, so credentials stay in workspace
1492
- secrets. On a batch it is one bag for the whole campaign, copied onto every call
1493
- it places — per-person data is what a recipient's `userdata` is for.
1555
+ for the default. The model can see the values, so credentials go in secrets. On
1556
+ a batch it is one bag for the whole campaign, copied onto every call it places —
1557
+ per-person data is what a recipient's `userdata` is for.
1558
+
1559
+ All three (not batches) also take `secrets`, `{NAME: value}`: credentials for
1560
+ that one session, read by its tools as `{{secrets.NAME}}` and never shown to the
1561
+ model or returned. A web call's `resume_call` keeps them, and its own `secrets`
1562
+ adds or replaces.
1494
1563
 
1495
1564
  **Per-call configuration.** All three — and `create_call_batch` — also take four
1496
1565
  fields that change what runs on that one call:
@@ -1537,7 +1606,13 @@ rather than as two messages. The agent's model must have `vision` (see *Images*
1537
1606
  above) or the call is refused naming the model.
1538
1607
 
1539
1608
  **Reading it back.** A *conversation* is the thread with a person, on any
1540
- surface; a *call* is one voice or video session. `list_conversations` and
1609
+ surface; a *call* is one voice or video session. A person is one **contact**
1610
+ (`contact_key`) per business number: `phone:<your number>:<their number>` spans
1611
+ phone calls, WhatsApp messages and WhatsApp calls on that number, with one
1612
+ `userdata`. Which thread a session writes to is the answering agent's
1613
+ `conversation.context` (`transcript` joins their newest thread), except that a
1614
+ WhatsApp call always joins their open WhatsApp chat. Every item carries the
1615
+ `channel` it arrived on. `list_conversations` and
1541
1616
  `list_conversation_items` are the transcript; `list_conversation_sessions` lists
1542
1617
  its calls and chats, and `get_chat` gives one chat's cost and analysis.
1543
1618
  `list_calls` and `get_call` cover phone and web calls — `get_call` gives the transcript with every tool call and
@@ -1549,6 +1624,13 @@ What a run costs is the provider spend on the workspace's own keys plus
1549
1624
  Talqing's platform fee, which `get_catalog` gives: per minute on voice and
1550
1625
  video, and $0.0001 per answered message on text.
1551
1626
 
1627
+ Items posted through `create_conversation_item` carry `post_type` and the
1628
+ `author` you gave (shown to people, never to the agent or the contact). Notes and
1629
+ instructions have no `channel`. Outbound WhatsApp and Telegram messages move
1630
+ through `delivery_status` (`queued`, `sent`, `delivered`, `read`, or
1631
+ `undelivered`/`failed` with `delivery_error`), and each move fires the
1632
+ `conversation.item.status` webhook.
1633
+
1552
1634
  When an agent misbehaves, read the actual run before theorizing. The transcript
1553
1635
  and the final `userdata` usually name the cause.
1554
1636
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talqing/mcp",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "MCP server for building Talqing AI voice, video and text agents from Claude Code, Codex, or any MCP client.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://talqing.com",
package/tools.json CHANGED
@@ -1934,6 +1934,20 @@
1934
1934
  "read_only": false,
1935
1935
  "role": "write"
1936
1936
  },
1937
+ {
1938
+ "description": "Post a template, agent text, note or instruction into a conversation, or start one with a person.",
1939
+ "method": "POST",
1940
+ "name": "create_conversation_item",
1941
+ "parameters": {
1942
+ "additionalProperties": true,
1943
+ "description": "Arguments not inlined: call describe_function('create_conversation_item').",
1944
+ "properties": {},
1945
+ "type": "object"
1946
+ },
1947
+ "path": "/v1/conversations/items",
1948
+ "read_only": false,
1949
+ "role": "write"
1950
+ },
1937
1951
  {
1938
1952
  "description": "Workspace analytics: volume, endings, recordings, response time and spend. One snapshot of a date range, up to 7 days.",
1939
1953
  "method": "GET",
@@ -2102,6 +2116,76 @@
2102
2116
  "read_only": true,
2103
2117
  "role": "read"
2104
2118
  },
2119
+ {
2120
+ "description": "Get the workspace's inbound session webhook.",
2121
+ "method": "GET",
2122
+ "name": "get_inbound_webhook",
2123
+ "parameters": {
2124
+ "additionalProperties": true,
2125
+ "description": "Arguments not inlined: call describe_function('get_inbound_webhook').",
2126
+ "properties": {},
2127
+ "type": "object"
2128
+ },
2129
+ "path": "/v1/inbound-webhook",
2130
+ "read_only": true,
2131
+ "role": "read"
2132
+ },
2133
+ {
2134
+ "description": "Set the URL asked for an inbound session's configuration.",
2135
+ "method": "PUT",
2136
+ "name": "set_inbound_webhook",
2137
+ "parameters": {
2138
+ "additionalProperties": true,
2139
+ "description": "Arguments not inlined: call describe_function('set_inbound_webhook').",
2140
+ "properties": {},
2141
+ "type": "object"
2142
+ },
2143
+ "path": "/v1/inbound-webhook",
2144
+ "read_only": false,
2145
+ "role": "write"
2146
+ },
2147
+ {
2148
+ "description": "Remove the inbound session webhook.",
2149
+ "method": "DELETE",
2150
+ "name": "delete_inbound_webhook",
2151
+ "parameters": {
2152
+ "additionalProperties": true,
2153
+ "description": "Arguments not inlined: call describe_function('delete_inbound_webhook').",
2154
+ "properties": {},
2155
+ "type": "object"
2156
+ },
2157
+ "path": "/v1/inbound-webhook",
2158
+ "read_only": false,
2159
+ "role": "write"
2160
+ },
2161
+ {
2162
+ "description": "Issue a new signing secret; the old one stops working at once.",
2163
+ "method": "POST",
2164
+ "name": "rotate_inbound_webhook_secret",
2165
+ "parameters": {
2166
+ "additionalProperties": true,
2167
+ "description": "Arguments not inlined: call describe_function('rotate_inbound_webhook_secret').",
2168
+ "properties": {},
2169
+ "type": "object"
2170
+ },
2171
+ "path": "/v1/inbound-webhook/rotate-secret",
2172
+ "read_only": false,
2173
+ "role": "write"
2174
+ },
2175
+ {
2176
+ "description": "Send a sample request and check the reply against the response schema.",
2177
+ "method": "POST",
2178
+ "name": "test_inbound_webhook",
2179
+ "parameters": {
2180
+ "additionalProperties": true,
2181
+ "description": "Arguments not inlined: call describe_function('test_inbound_webhook').",
2182
+ "properties": {},
2183
+ "type": "object"
2184
+ },
2185
+ "path": "/v1/inbound-webhook/test",
2186
+ "read_only": false,
2187
+ "role": "write"
2188
+ },
2105
2189
  {
2106
2190
  "description": "The provider catalog: every LLM, STT, TTS, realtime and avatar model that agents may use.",
2107
2191
  "method": "GET",