# TalkBar MCP & CLI documentation > Official learning reference for AI assistants using TalkBar through its local MCP server or talkbar-cli. Language: en. Read setup and permissions before calling tools. For current operation schemas, use the discovery commands documented in the tools and CLI guides. - [Full reference in one request](https://docs.talkbar.app/mcp/llms-full.txt) ## Recommended reading order - [MCP and CLI overview](https://docs.talkbar.app/mcp/overview.md): What TalkBar's MCP server and talkbar-cli let an AI assistant do with your sessions, notes and knowledge, and what always stays in the app. [Web page](https://docs.talkbar.app/mcp/overview) - [Set up MCP](https://docs.talkbar.app/mcp/setup.md): Turn on MCP in TalkBar and connect Claude Desktop, ChatGPT, Claude Code, Codex, agy, Grok, OpenCode or any other MCP client. [Web page](https://docs.talkbar.app/mcp/setup) - [Access and permissions](https://docs.talkbar.app/mcp/access-and-permissions.md): Choose which TalkBar operations an AI assistant may run, how deletes are confirmed, and how administrator rules and the CLI fit in. [Web page](https://docs.talkbar.app/mcp/access-and-permissions) - [The five MCP tools](https://docs.talkbar.app/mcp/tools.md): How talkbar_find, talkbar_read, talkbar_change, talkbar_delete and talkbar_tools work, with their arguments, batches, annotations, paging and wire format. [Web page](https://docs.talkbar.app/mcp/tools) - [talkbar-cli](https://docs.talkbar.app/mcp/cli.md): Run TalkBar operations from a terminal or script with talkbar-cli, the same program that serves MCP. Commands, options, input, output and exit codes. [Web page](https://docs.talkbar.app/mcp/cli) - [Operations reference](https://docs.talkbar.app/mcp/operations.md): Every operation an assistant can run through TalkBar MCP or the TalkBar CLI, with arguments, defaults, permissions and results. [Web page](https://docs.talkbar.app/mcp/operations) - [Examples](https://docs.talkbar.app/mcp/examples.md): Practical TalkBar MCP and CLI walkthroughs with real requests and responses, from asking about last week's sessions to bookmarking a live recording. [Web page](https://docs.talkbar.app/mcp/examples) - [Errors and limits](https://docs.talkbar.app/mcp/errors-and-limits.md): Every error code TalkBar MCP and talkbar-cli return, what to do about each, plus plan limits, concurrency, argument rules and safe retries. [Web page](https://docs.talkbar.app/mcp/errors-and-limits) - [Action items](https://docs.talkbar.app/mcp/operations/action-items.md): MCP and CLI operations to list, read, create, update, complete and remove action items, follow-ups, questions and decisions. [Web page](https://docs.talkbar.app/mcp/operations/action-items) - [Calendar and series](https://docs.talkbar.app/mcp/operations/calendar-and-series.md): MCP and CLI operations to list, schedule, prepare, move, snooze, skip and cancel planned meetings, and to manage session series and their schedules. [Web page](https://docs.talkbar.app/mcp/operations/calendar-and-series) - [Chats and documents](https://docs.talkbar.app/mcp/operations/chats-and-documents.md): MCP and CLI operations to list and read Ask TalkBar chats and documents, read document text, and rename, pin, file, trash and restore them. [Web page](https://docs.talkbar.app/mcp/operations/chats-and-documents) - [Exports](https://docs.talkbar.app/mcp/operations/exports.md): MCP and CLI operations to configure export destinations and automatic export rules, and to preview, queue, run, cancel, retry and resolve session exports. [Web page](https://docs.talkbar.app/mcp/operations/exports) - [Knowledge](https://docs.talkbar.app/mcp/operations/knowledge.md): MCP and CLI operations for knowledge cards and the suggestions knowledge scans propose, to list, read, create, update, pin, file, archive and review them. [Web page](https://docs.talkbar.app/mcp/operations/knowledge) - [People and companies](https://docs.talkbar.app/mcp/operations/people-and-companies.md): MCP and CLI operations to list, read, create, update and archive people and companies, and to find the sessions a person spoke in. [Web page](https://docs.talkbar.app/mcp/operations/people-and-companies) - [Projects and notes](https://docs.talkbar.app/mcp/operations/projects-and-notes.md): MCP and CLI operations to list, read, create, update, file, pin, trash and restore projects and notes. [Web page](https://docs.talkbar.app/mcp/operations/projects-and-notes) - [Scheduler](https://docs.talkbar.app/mcp/operations/scheduler.md): MCP and CLI operations to inspect TalkBar's scheduled jobs and to cancel or retry one. [Web page](https://docs.talkbar.app/mcp/operations/scheduler) - [Sessions](https://docs.talkbar.app/mcp/operations/sessions.md): MCP and CLI operations to list, read, file, pin, trash and restore sessions, read transcripts and timelines, name speakers and manage session cards. [Web page](https://docs.talkbar.app/mcp/operations/sessions) - [Topics and markers](https://docs.talkbar.app/mcp/operations/topics-and-markers.md): MCP and CLI operations for topics that label sessions and notes, session keywords, and markers on moments in a session. [Web page](https://docs.talkbar.app/mcp/operations/topics-and-markers) - [Workspace and profile](https://docs.talkbar.app/mcp/operations/workspace-and-profile.md): MCP and CLI operations for workspaces, workspace search and statistics, your profile and your plan. [Web page](https://docs.talkbar.app/mcp/operations/workspace-and-profile) --- # MCP and CLI overview What TalkBar's MCP server and talkbar-cli let an AI assistant do with your sessions, notes and knowledge, and what always stays in the app. Canonical URL: https://docs.talkbar.app/mcp/overview TalkBar can share your workspace with AI assistants such as Claude, ChatGPT and Codex through MCP (Model Context Protocol). An assistant can search your sessions, read summaries and transcripts, and, if you allow it, add notes, action items and bookmarks. Everything runs on your computer, and you choose what each assistant may do in **Settings → MCP Access**. ## Two ways in TalkBar ships one small program, `talkbar-cli`, installed next to the app. It gives you two ways to reach the same set of operations: | Way in | Who uses it | How it works | | --- | --- | --- | | **MCP server** | AI apps that speak MCP. **MCP Access** has ready-made setups for ChatGPT, Claude Desktop, Claude Code, Codex, agy CLI, Grok CLI and OpenCode; other clients, such as Cursor, use **Generic JSON**. | The AI app starts `talkbar-cli serve --transport stdio` and talks to it over standard input and output. It obeys every switch in **Settings → MCP Access**. | | **Command line** | You, your scripts, and AI agents that can run commands | You run `talkbar-cli tools call`, `tools batch` or `search` in a terminal. It ignores the MCP Access switches, because it only does what you type. | Both use the same data, the same ownership checks and the same administrator rules. Both work while the TalkBar app is open or closed. When the app is open, it refreshes the screens that show anything an assistant or script changed. ## What an assistant can do An assistant works with what TalkBar holds: sessions with their summaries and transcripts, notes, projects, action items, knowledge cards, people and companies, topics, bookmarks, chats, documents, planned meetings, session series and exports. | Kind of work | Examples | Default | | --- | --- | --- | | **Read** | Search everything, list last week's sessions, read a summary or a full transcript, read a note, list open action items | On (once MCP is on) | | **Write** | Create a note, add an action item or bookmark (also during a live recording), rename a session, file it under a project, approve a knowledge card, name a speaker or link a speaker to a person, rename a workspace, update your profile's name, email or job title | Off, except calendar, series, scheduler and export operations | | **Delete** | Move a note, session, project or chat to the Trash; archive a card, person, company or series; remove an action item, topic or bookmark | Off for your content. An AI app that can ask you is always asked to confirm; other apps are refused unless you allow deletes without confirmation. | Speaker changes work only after a session stops recording: an assistant can give a speaker a name, link the speaker to a person already in TalkBar, or remove the name. These change speaker names and person links only; what was said and the voice data stay as they are. Nothing an assistant does deletes a trashable item for good. Trashed items can be restored in the app, and archived items stay editable. Action items, topics and bookmarks have no Trash: removing one removes it, as it does in the app. For every operation, see the [operations reference](/mcp/operations). ## What always stays in the app Some things an assistant can never do, whatever you switch on: - Start, pause or stop a recording, or control a live session. - Edit a transcript. - Generate or regenerate a summary, or run any of TalkBar's AI features. - Change settings, including the MCP Access switches. - Delete anything permanently, or empty the Trash. - Add documents or re-index them. - Create, switch or trash workspaces (renaming one is allowed). An assistant can still work alongside a live recording: it can read the transcript as it grows and add bookmarks, action items and knowledge cards that show up on the recording screen right away. ## Privacy - **Local only.** The MCP server is a program on your computer, started by your AI app. It talks to that app over standard input and output and opens no network port. Your data is read from the TalkBar data folder on this computer. - **Off until you turn it on.** MCP is off when you install TalkBar. While it is off, a connected AI app sees no TalkBar tools. - **What the assistant receives.** An assistant gets what TalkBar shows you, transcripts included. Sessions you marked as Private AI come back with `"private": true`, and speakers you excluded from AI are marked `excludedFromAi`; they are marked, not hidden. Whatever the assistant reads goes to that AI app and its model provider, under their privacy terms. If that matters for a session, keep the read switches off, or don't connect a cloud AI app. - **You decide.** Each operation has its own switch. Deletes are confirmed with you when your AI app supports it, and refused otherwise unless you turn on **Allow deletes without confirmation**. See [Access and permissions](/mcp/access-and-permissions). Private AI Mode keeps TalkBar's own AI on your computer. It does not stop an MCP client from reading a session. The assistant's model runs wherever that AI app runs it. ## The five tools at a glance An MCP client does not see one tool per operation. It sees at most five tools, so connecting TalkBar costs the assistant very little context: | Tool | What it does | | --- | --- | | [`talkbar_find`](/mcp/tools#talkbar_find) | Searches the workspace by name and content. Usually the first step, to get ids. | | [`talkbar_read`](/mcp/tools#talkbar_read) | Runs read operations, one or a batch of up to 20. | | [`talkbar_change`](/mcp/tools#talkbar_change) | Runs operations that create or change data. | | [`talkbar_delete`](/mcp/tools#talkbar_delete) | Runs operations that trash, archive or delete. You confirm each call. | | [`talkbar_tools`](/mcp/tools#talkbar_tools) | Lists the operations you switched on, or one operation's arguments. | When it connects, TalkBar also gives the assistant a few lines of instructions: find ids first, then read or change, batch with `{"calls": [...]}`, and ask you to turn operations on in **Settings → MCP Access**. Most assistants need no other prompt. ## Workspaces Every operation works in one workspace. Without a `workspaceId`, TalkBar uses the workspace open in the app at that moment, so if you switch workspaces in the app, the assistant follows. The `workspace.list` operation lists your workspaces and marks the open one. An assistant can rename a workspace (if you allow it), but creating, switching and trashing workspaces stay in the app. ## Related - [Set up MCP](/mcp/setup) - [Access and permissions](/mcp/access-and-permissions) - [The five MCP tools](/mcp/tools) - [talkbar-cli](/mcp/cli) - [Examples](/mcp/examples) - [Operations reference](/mcp/operations) --- # Set up MCP Turn on MCP in TalkBar and connect Claude Desktop, ChatGPT, Claude Code, Codex, agy, Grok, OpenCode or any other MCP client. Canonical URL: https://docs.talkbar.app/mcp/setup Connecting an AI app to TalkBar takes two steps: turn MCP on in **Settings → MCP Access**, then copy the ready-made setup for your app. TalkBar fills in the real paths for your computer, so you never have to type them. ## Before you start - TalkBar is installed on this computer. - Your AI app supports local MCP servers (the kind that start a program on your computer, often called "stdio" servers). - If your organization manages TalkBar, MCP may be turned off for you. See [Administrator rules](/mcp/access-and-permissions#administrator-rules). ## Turn on MCP 1. Open **Settings → MCP Access**. 2. Turn on the switch at the top right of the page. It changes from **Disabled** to **Enabled**. 3. Check the badge next to the page title: | Badge | What it means | | --- | --- | | **Ready** | TalkBar found `talkbar-cli` and it answered. You can connect your app. | | **Missing** | TalkBar could not find `talkbar-cli`. Reinstall TalkBar. | | **Error** | `talkbar-cli` was found but failed to start. A warning above the page shows its message. | | **Disabled** | MCP is off. Connected apps see no TalkBar tools. | When MCP is on, reading is allowed and most changes are not. You can change that later in [Access and permissions](/mcp/access-and-permissions). ## Copy the setup for your app The **MCP Connect** card shows one button per app. Pick yours, then use **Copy *app* MCP Connect** under the code box. Depending on the app, you get either a JSON block to paste into its settings or a command to run in a terminal. Every setup does the same thing: it tells your app to start `talkbar-cli` with `serve --transport stdio`, and sets `TALKBAR_DATA_ROOT` to your TalkBar data folder. The examples use placeholders for the executable and data folder. Replace them with the paths shown in **MCP Access**, or copy the ready-made setup from TalkBar. The executable name and paths depend on your operating system. Escape backslashes in JSON paths (or use forward slashes where supported). ### Claude Desktop Copy the JSON and add it to Claude Desktop's configuration file, `claude_desktop_config.json` (in Claude Desktop: **Settings → Developer → Edit Config**). If the file already has an `mcpServers` section, add the `talkbar` entry inside it. Then quit and reopen Claude Desktop. ```json [claude_desktop_config.json] { "mcpServers": { "talkbar": { "command": "PATH_TO_TALKBAR_CLI", "args": [ "serve", "--transport", "stdio" ], "env": { "TALKBAR_DATA_ROOT": "PATH_TO_TALKBAR_DATA" } } } } ``` ### ChatGPT ChatGPT gets the same `mcpServers` JSON as Claude Desktop. Paste it where your ChatGPT app takes MCP server settings, then restart the app. ```json { "mcpServers": { "talkbar": { "command": "PATH_TO_TALKBAR_CLI", "args": [ "serve", "--transport", "stdio" ], "env": { "TALKBAR_DATA_ROOT": "PATH_TO_TALKBAR_DATA" } } } } ``` ### Claude Code Run the copied command once in a terminal. `-s user` adds TalkBar for all your projects. ```shell claude mcp add talkbar -s user -e "TALKBAR_DATA_ROOT=PATH_TO_TALKBAR_DATA" -- "PATH_TO_TALKBAR_CLI" serve --transport stdio ``` Claude Code can also run `talkbar-cli` directly instead of through MCP. See [For AI agents with a shell](/mcp/cli#for-ai-agents-with-a-shell). ### Codex Run the copied command once in a terminal. ```shell codex mcp add talkbar --env "TALKBAR_DATA_ROOT=PATH_TO_TALKBAR_DATA" -- "PATH_TO_TALKBAR_CLI" serve --transport stdio ``` ### agy CLI Run the copied command once in a terminal. agy takes its options before the server name. ```shell agy mcp add --env "TALKBAR_DATA_ROOT=PATH_TO_TALKBAR_DATA" talkbar -- "PATH_TO_TALKBAR_CLI" serve --transport stdio ``` ### Grok CLI Run the copied command once in a terminal. ```shell grok mcp add talkbar -e "TALKBAR_DATA_ROOT=PATH_TO_TALKBAR_DATA" -- "PATH_TO_TALKBAR_CLI" serve --transport stdio ``` ### OpenCode Add the copied block to your OpenCode configuration. If it already has an `mcp` section, add the `talkbar` entry inside it. ```json [opencode.json] { "$schema": "https://opencode.ai/config.json", "mcp": { "talkbar": { "type": "local", "command": [ "PATH_TO_TALKBAR_CLI", "serve", "--transport", "stdio" ], "environment": { "TALKBAR_DATA_ROOT": "PATH_TO_TALKBAR_DATA" }, "enabled": true } } } ``` ### Other apps For any other MCP client, such as Cursor, pick **Generic JSON**. It holds the four facts every client needs: a stdio server, the program, its arguments and the environment variable. Put them where your client expects them. ```json { "type": "stdio", "command": "PATH_TO_TALKBAR_CLI", "args": [ "serve", "--transport", "stdio" ], "env": { "TALKBAR_DATA_ROOT": "PATH_TO_TALKBAR_DATA" } } ``` After you add TalkBar, restart your app or reload its MCP servers. Then ask it something like "What TalkBar sessions did I have this week?" to check the connection. See [Examples](/mcp/examples) for more. ## Copy the serve command **Copy CLI MCP Serve Command** copies the platform-specific command to start the MCP server manually. Run the copied command in a terminal for testing or for a client that needs one command. The server then waits for an MCP client on standard input. Press `Ctrl+C` to stop it. ## Where talkbar-cli is installed `talkbar-cli` is installed with TalkBar. The **Server Settings** card on **MCP Access** shows: | Setting | What it shows | | --- | --- | | **Executable path** | The full path to `talkbar-cli`. **Copy** copies it. | | **Add to PATH** | Copies a command to add the executable folder to your PATH. Follow the command shown for your system, then open a new terminal to use `talkbar-cli` by name. | | **Data root** | Your TalkBar data folder. **Copy** copies it. | ## TALKBAR_DATA_ROOT `TALKBAR_DATA_ROOT` tells `talkbar-cli` which TalkBar data folder to open. TalkBar's ready-made setups always set it to the folder the app uses, shown as **Data root**. ### Windows The default data folder is `%LOCALAPPDATA%\TalkBar`. Check **Data root** for the path in use. ### macOS Check **Data root** for the data folder on your Mac. - Point it only at a TalkBar data folder. A folder without TalkBar data gets a new, empty database, and the assistant would see an empty workspace. - To open a database file directly from the command line, use `--db` instead. See [talkbar-cli](/mcp/cli#global-options). ## After a TalkBar update Installing a TalkBar update closes any `talkbar-cli` that is running from the app folder, including MCP servers your AI apps started. If an app loses its TalkBar tools after an update, restart the app or reconnect its TalkBar server. ## Troubleshooting | Problem | What to try | | --- | --- | | The app shows no TalkBar tools | Check that MCP is **Enabled** in **MCP Access**. If the app connected while MCP was off, restart the app or reconnect TalkBar. | | The assistant says an operation "is turned off in TalkBar" | Turn that operation on in **MCP Access**. See [Access and permissions](/mcp/access-and-permissions). | | The assistant sees an empty workspace | Check that `TALKBAR_DATA_ROOT` in your app's setup matches **Data root** in **MCP Access**. Copy the setup again if you moved your data. | | Deletes are refused with `confirmation_unavailable` | Your app cannot ask you to confirm. See [Confirming deletes](/mcp/access-and-permissions#confirming-deletes). | | The badge shows **Missing** | TalkBar cannot find `talkbar-cli`. Reinstall TalkBar. | | The page is locked with a notice from your organization | An administrator turned off the MCP server or the command-line tool on this computer. | ## Related - [MCP overview](/mcp/overview) - [Access and permissions](/mcp/access-and-permissions) - [MCP Access settings](/settings/mcp-access) - [talkbar-cli](/mcp/cli) - [Examples](/mcp/examples) --- # Access and permissions Choose which TalkBar operations an AI assistant may run, how deletes are confirmed, and how administrator rules and the CLI fit in. Canonical URL: https://docs.talkbar.app/mcp/access-and-permissions You decide what a connected AI assistant may do, one operation at a time, in **Settings → MCP Access**. Reading is on by default, changes to your content are off, and anything that trashes, archives or deletes is confirmed with you when your AI app can ask. Apps that cannot ask are refused, unless you turn on **Allow deletes without confirmation**. ## The MCP switch The switch at the top right of **MCP Access** turns MCP on or off for every connected app. It is off when you install TalkBar. - **Off:** a connected app sees no TalkBar tools, and every operation answers that it is turned off. The permission switches below are greyed out. - **On:** a connected app sees the [TalkBar tools](/mcp/tools) and can run the operations you switched on. ## Read and Write switches The **Permissions** card has one row per kind of data: **Sessions**, **Notes**, **Projects**, **Action items**, **Knowledge**, **People**, **Topics**, **Markers**, **Chats**, **Documents**, **Calendar**, **Session Series**, **Scheduler**, **Exports**, **Workspace** and **Profile**. Each row has two switches: | Switch | What it allows | Default | | --- | --- | --- | | **Read** | Listing, searching and reading that kind of data. Reading never changes anything. | On | | **Write** | Creating, changing, trashing, archiving and restoring that kind of data. Nothing is deleted permanently. | Off, except Calendar, Session Series, Scheduler and Exports | Next to each row switch, a count such as `3/7` shows how many of its operations are on. The switch shows as on only when all of them are; switching a partly-on row turns them all on. Operations your organization blocked are left out of both the count and the switch; a row whose operations are all blocked shows a locked switch. The **Read** and **Write** badges in the card header count how many operations are on in total. A **Write** switch covers every change for that kind of data, including moving items to the Trash. TalkBar still asks you before each trash, archive or delete (see [Confirming deletes](#confirming-deletes)), but turn on only what you need. ### Single operations Open a row (click its name) to see each operation with its own switch, a short description and its id, such as `notes.create`. Switch single operations on or off here when a whole row is more than you want, for example to let an assistant add notes but not trash them. Operations that start work or remove something carry a **Confirmation advised** badge. The badge is a hint for you and for AI apps; the confirmation TalkBar enforces is the one for deletes described below. ### Writes that are on by default These write operations are on as soon as you turn MCP on. They plan meetings and move exports and background jobs along, rather than change your sessions, notes or knowledge: | Area | Operations on by default | | --- | --- | | Calendar | `calendar.schedule`, `calendar.prepare`, `calendar.prep.edit`, `calendar.move`, `calendar.snooze`, `calendar.start`, `calendar.skip`, `calendar.cancel` | | Session Series | `series.create`, `series.update`, `series.sessions.assign`, `series.schedule.set`, `series.archive` | | Scheduler | `scheduler.job.cancel`, `scheduler.job.retry` | | Exports | `exports.destination.save`, `exports.destination.delete`, `exports.rule.save`, `exports.rule.delete`, `exports.enqueue`, `exports.run`, `exports.cancel`, `exports.retry`, `exports.resolve` | `calendar.skip`, `calendar.cancel`, `series.archive`, `exports.destination.delete` and `exports.rule.delete` run through `talkbar_delete`, like every delete, so they are confirmed with you (or refused for apps that cannot ask). `calendar.start` never records: recording only starts in the app. ### Quick buttons | Button | What it does | | --- | --- | | **Reset to Default** | Puts every operation back to its default. Shown only when something differs from the defaults. | | **Enable All** | Turns on every operation, after a warning. | | **Disable All** | Turns off every operation, after a warning. Connected apps can then read and change nothing. | ## Which tool runs what TalkBar keeps reads, changes and deletes in separate MCP tools, so your AI app can treat them differently, for example run reads freely but ask you before changes: | Tool | Runs | Listed when | | --- | --- | --- | | `talkbar_read` | Read operations | At least one read is on | | `talkbar_change` | Writes that remove nothing | At least one of them is on | | `talkbar_delete` | Trash, archive and delete operations | At least one of them is on | The operations that only `talkbar_delete` runs are: `notes.trash`, `projects.trash`, `sessions.trash`, `chats.trash`, `knowledge.archive`, `contacts.archive`, `organizations.archive`, `series.archive`, `action_items.remove`, `topics.delete`, `markers.delete`, `exports.destination.delete`, `exports.rule.delete`, `calendar.cancel` and `calendar.skip`. Restoring something from the Trash, unarchiving and other changes go through `talkbar_change`. See [The five MCP tools](/mcp/tools) for how each tool is called. ## When a change takes effect TalkBar checks your switches on every call, so a change in **MCP Access** applies to the next call without restarting anything. - A switched-off operation answers with `turned_off` and the message "… is turned off in TalkBar. Ask the user to turn it on in TalkBar Settings > MCP Access." A good assistant then asks you. - `talkbar_tools` lists switched-off operations under `off`, so the assistant can tell you which switch to turn on instead of assuming the operation does not exist. - When a switch changes the tool list itself (for example, the first write turned on adds `talkbar_change`), TalkBar tells the app at its next call so it can refresh its tools. See [Tool list changes](/mcp/tools#tool-list-changes). ## Confirming deletes Before a `talkbar_delete` call runs, TalkBar asks you to confirm it through your AI app, using MCP's way for a server to ask the user a question (called elicitation, in its form mode). This works only in apps that support it; for apps that cannot ask, see [Apps that cannot ask](#apps-that-cannot-ask). The question lists each operation and its ids: ```text An assistant wants TalkBar to run: - notes.trash {"noteId":"note-k2v9w8x7c6b5n4m3l2j1h0g9"} Confirm to run it, or decline to run nothing. ``` | Your answer | What happens | | --- | --- | | Confirm | The call runs. | | Decline, cancel, or no answer within 5 minutes | Nothing runs. The assistant gets `declined`. | A few details: - A call that would be refused anyway (an unknown or switched-off operation, a missing or wrong argument) is refused at once, without a question. - A batch is asked about as a whole, with every operation in it listed. Other writes may share the batch. - The question is in English. - The command line never asks. It runs only what you typed yourself. ### Apps that cannot ask Some AI apps cannot show a question from a server. For those, TalkBar refuses every `talkbar_delete` call with `confirmation_unavailable`, and nothing runs, unless you turn on **Allow deletes without confirmation** in the **Server Settings** card. | Setting | What it does | Default | | --- | --- | --- | | **Allow deletes without confirmation** | Lets AI apps that cannot ask you first move items to the Trash, archive or delete them. An app that can ask is still always asked. | Off | With this setting on, an app that cannot ask runs every delete you switched on without checking with you. Turn on only the delete operations you are comfortable with, and remember that trashed items can be restored in the app. ## Audit logging **Audit logging** in **Server Settings** (off by default) makes the MCP server write a line for every tool call to its error output (stderr), with the operation and its arguments, and another when the call succeeds. Your AI app usually keeps that output in its MCP logs. Use it for debugging or to review what an assistant did. Export calls are logged without their arguments. The command line does not write audit lines. ## Administrator rules If your organization manages TalkBar on this computer, an administrator can limit MCP and the command line. You see it on **MCP Access**: | Rule | What you see | Effect | | --- | --- | --- | | MCP server turned off | The MCP switch is locked, with "Your organization turned off the MCP server." | `talkbar-cli serve` refuses to start. The command line's other commands still work. | | Command-line tool turned off | The MCP switch is locked, with "Your organization turned off the command-line tool." | Every `talkbar-cli` command is refused, including the MCP server. Only `--help` and `--version` work. | | Allowed MCP tools limited | "Your organization limits which tools AI assistants can use." Blocked operations show a lock and **Blocked by your organization**. | Blocked operations stay off whatever your switches say, for MCP and the command line alike. | An administrator allows or blocks operations in groups: | Group | Covers | | --- | --- | | Lists and counts | `workspace.list`, `workspace.stats`, `sessions.list`, `sessions.stats`, `sessions.recording`, `projects.list`, `plan.get`, and calendar and series reads | | Meeting content | Every other read, including search, transcripts, `exports.preview` and `calendar.prep` | | Exports | Export operations, except `exports.preview` | | Scheduling changes | Calendar and series writes | | Background jobs | `scheduler.*` operations | | Changes to items | Every other write: sessions, notes, projects, action items, knowledge, people, topics, markers, chats, documents, workspace and profile | A blocked operation is left out of the tool list and of `talkbar_tools`. If an assistant calls it anyway, it gets `failed` with a message saying the setting is managed by your organization. ## What the command line ignores `talkbar-cli tools call`, `tools batch` and `search` run what you type, as you. They: - **Ignore** the MCP switch, every Read and Write switch, and **Allow deletes without confirmation**. The command line never asks for confirmation. - **Keep** the administrator rules, your plan limits and every ownership check: a command reaches only your own workspaces in that data folder, and nothing is deleted permanently. `talkbar-cli serve` is the MCP server, so it follows every switch on this page. See [talkbar-cli](/mcp/cli). ## Related - [MCP overview](/mcp/overview) - [Set up MCP](/mcp/setup) - [The five MCP tools](/mcp/tools) - [Errors and limits](/mcp/errors-and-limits) - [MCP Access settings](/settings/mcp-access) - [Operations reference](/mcp/operations) --- # The five MCP tools How talkbar_find, talkbar_read, talkbar_change, talkbar_delete and talkbar_tools work, with their arguments, batches, annotations, paging and wire format. Canonical URL: https://docs.talkbar.app/mcp/tools TalkBar's MCP server does not list one tool per operation. It lists at most five tools that sit in front of every operation, so an assistant pays for the same few tool definitions however many operations TalkBar offers. This page is for people building or tuning agents; for each operation's own arguments, see the [operations reference](/mcp/operations). ## What a client sees When an app connects, the server introduces itself as `talkbar` (title "TalkBar") and sends these instructions: ```text TalkBar holds the user's meetings: sessions with summaries and transcripts, notes, projects, action items, knowledge cards, people and schedules. Find ids with talkbar_find, then read with talkbar_read and change with talkbar_change; trash, archive and delete go through talkbar_delete, which the user confirms. Batch with {"calls":[...]}: calls run in order and continue past errors unless stopOnError is true. workspaceId is optional (default: the workspace open in the app). Notes are Markdown. The live session: sessions.recording. Recording, settings and emptying the Trash stay in the app. The user turns operations on in TalkBar Settings > MCP Access; item changes start off. ``` `tools/list` then returns only the tools that have something to run: | Tool | Listed when | | --- | --- | | `talkbar_find` | The `workspace.search` read is on | | `talkbar_read` | At least one read is on | | `talkbar_change` | At least one write that removes nothing is on | | `talkbar_delete` | At least one trash, archive or delete operation is on | | `talkbar_tools` | Anything at all is on | With MCP off in TalkBar, or every operation off or blocked, the list is empty. ### Annotations Every tool carries MCP annotations, so your app can decide which calls to approve automatically: | Tool | `readOnlyHint` | `destructiveHint` | `idempotentHint` | `openWorldHint` | | --- | --- | --- | --- | --- | | `talkbar_find` | true | false | true | false | | `talkbar_read` | true | false | true | false | | `talkbar_change` | false | false | false | false | | `talkbar_delete` | false | true | false | false | | `talkbar_tools` | true | false | true | false | `talkbar_delete` is not idempotent because one of its batches may also hold other writes. ## Calling an operation `talkbar_read`, `talkbar_change` and `talkbar_delete` take the same arguments. Name one operation with `tool` and its arguments with `args`: ```json { "tool": "notes.get", "args": { "noteId": "note-k2v9w8x7c6b5n4m3l2j1h0g9" } } ``` Or run up to 20 operations in order with `calls`: ```json { "calls": [ { "tool": "sessions.list", "args": { "limit": 5 } }, { "tool": "notes.list" } ], "stopOnError": false } ``` **tool** (string) The operation id, such as `sessions.get`. Use with `args`, not with `calls`. **args** (object) The operation's arguments. Leave it out, or send `null`, for none. **calls** (array) 1 to 20 objects of `{"tool", "args"}`, run in order. **stopOnError** (boolean) With `calls`: stop at the first failed operation. Default `false`, so later calls still run. Every operation takes an optional `workspaceId`. Without it, TalkBar uses the workspace open in the app. ## `talkbar_find` The universal search, the same one the app's search uses, transcript snippets included. It is usually the first step, to turn a name or a phrase into ids. **query** (string, required) What to look for. Must not be empty. **kinds** (string[]) Limit the search to some kinds: `session`, `note`, `document`, `chat`, `action_item`, `project`, `series`, `person`, `company`, `memory` (knowledge cards). **match** (string) `any` (default) reads the query as a natural-language request. `all` requires every word. **projectId** (string) Only items in this project. **limit** (integer) 1 to 100 results. Default 20. **includeArchived** (boolean) Also find archived series, people, companies and knowledge cards. Trashed items are never found. **workspaceId** (string) The workspace to search. Default: the one open in the app. ```json [Request] { "query": "pricing review", "kinds": ["session", "note"], "limit": 5 } ``` ```json [Response] { "matches": [ { "kind": "session", "id": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "title": "Pricing review with Acme", "snippet": "…agreed to keep the pricing review on Thursdays…", "href": "/sessions/6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "score": 14.2, "projectId": "project-p8d3k2m1q9w7e5r4t6y0u2i1", "matchedIn": "title", "atMs": 1792594800000, "detail": null, "context": null, "itemCount": null, "archived": false, "content": null } ], "contentSearch": "on" } ``` Best matches come first. `score` is 10 or more for a match in a name or text, and below 10 for a match only in indexed content; such a match carries `content` with the passage's `sourceType`, `sourceId`, `locator` and `tMs` (the moment in the transcript). `matchedIn` is `title`, `body` or `content`. `contentSearch` says whether content search ran (`on`), ran on keywords only (`keywordOnly`), was not available (`off`) or failed (`failed`); name and text matches come back either way. ## `talkbar_read` Runs read operations. Its description lists every read that is on, grouped by area with its required arguments, for example `notes.list|get(noteId)|trash.list; sessions.get(sessionId)|transcript(sessionId)|…`, so an assistant can make its first read without looking anything up. ```json { "tool": "sessions.transcript", "args": { "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10" } } ``` It refuses writes: a batch that holds a write is refused as a whole, and the message names the tool to use. ## `talkbar_change` Runs writes that remove nothing: creating, changing, filing, pinning, restoring. Its description lists no operations; an assistant gets their ids and arguments from [`talkbar_tools`](#talkbar_tools). ```json { "tool": "notes.create", "args": { "title": "Follow-ups", "markdown": "- Send the revised quote\n- Book the next call" } } ``` It refuses reads and the operations of `talkbar_delete`. A batch holding one of them is refused as a whole, with "Nothing in this call ran". This keeps an app's approval of `talkbar_change` from ever approving a delete. ## `talkbar_delete` Runs the operations that move items to the Trash, archive or delete them: `notes.trash`, `projects.trash`, `sessions.trash`, `chats.trash`, `knowledge.archive`, `contacts.archive`, `organizations.archive`, `series.archive`, `action_items.remove`, `topics.delete`, `markers.delete`, `exports.destination.delete`, `exports.rule.delete`, `calendar.cancel` and `calendar.skip`. ```json { "tool": "notes.trash", "args": { "noteId": "note-k2v9w8x7c6b5n4m3l2j1h0g9" } } ``` - Before it runs, TalkBar asks the user to confirm when the client supports MCP elicitation (form mode). A client that cannot ask is refused with `confirmation_unavailable`, unless the user turned on **Allow deletes without confirmation**. See [Confirming deletes](/mcp/access-and-permissions#confirming-deletes). - A batch sent here may also hold other writes, for example a `notes.create` followed by a `notes.trash`. Reads are refused. - A batch whose calls would all be refused anyway is answered without a question, with each call's own error. ## `talkbar_tools` The operation index. Call it with no arguments to see every operation you can run now, grouped by the tool that runs it: ```json [Response] { "talkbar_read": { "notes.list": "Page document notes in an owned workspace, most recently updated first, optionally scoped to a project or a title/body search.", "notes.get": "Read one note's title, Markdown body (paged with maxChars and offset) and links." }, "talkbar_change": { "notes.create": "Create a note from Markdown, optionally filed under a project and sessions." }, "talkbar_delete": { "notes.trash": "Move a note to the Trash; it can be restored." }, "off": "Turned off; the user can turn them on in TalkBar Settings > MCP Access: notes.update|append|move|pin; projects.create|update" } ``` The example is shortened. `off` lists operations you switched off, so the assistant can ask you to turn one on. Operations an administrator blocked are not listed. Call it with `{"tool": ""}` to get one operation's arguments: ```json [Request] { "tool": "notes.append" } ``` ```json [Response] { "tool": "notes.append", "kind": "change", "runWith": "talkbar_change", "summary": "Add Markdown to the end of a note.", "args": { "type": "object", "properties": { "workspaceId": { "type": "string" }, "noteId": { "type": "string" }, "markdown": { "type": "string", "minLength": 1 } }, "required": ["noteId", "markdown"], "additionalProperties": false } } ``` `kind` is `read` or `change`; `runWith` names the tool to send it to. `args` is the operation's JSON Schema; unknown arguments are refused, so it is closed with `"additionalProperties": false`. An unknown id answers `not_found` (with a "did you mean" hint when one is close), a switched-off one `turned_off`, and a blocked one `failed`. ## Batches A `{"calls": [...]}` batch runs its operations one after another, in order, in one call: - 1 to 20 operations. Send either `tool` (with `args`) or `calls`, never both. - Every known operation in the batch must belong to the tool you sent it to. If one does not, the whole batch is refused and nothing in it runs. - An operation that fails does not stop the batch unless `stopOnError` is `true`. - An unknown operation fails on its own with `not_found`; the rest still run. - The open TalkBar app refreshes once for the whole batch. The answer has one entry per operation that ran: ```json { "results": [ { "tool": "sessions.list", "ok": true, "result": { "items": [], "nextCursor": null, "hasMore": false, "totalCount": 0 } }, { "tool": "notes.get", "ok": false, "error": { "code": "not_found", "message": "Note not found in workspace" } } ] } ``` An entry that could not be read at all (no `tool`, or `args` that is not an object) has `ok: false` and an error, but no `tool`. To make one operation depend on another (create a note, then file it), put both in one batch or wait for the first answer before sending the second call. ## Results and errors A successful call returns one text item holding the result as compact JSON. An operation that is refused or fails is still a normal tool result. It has `isError: true` and holds: ```json { "error": { "code": "turned_off", "message": "notes.create is turned off in TalkBar. Ask the user to turn it on in TalkBar Settings > MCP Access." } } ``` Codes are `invalid_arguments`, `not_found`, `turned_off`, `failed`, `declined`, `confirmation_unavailable`, `busy`, `conflict`, `session_recording`, `limit_reached` and `plan_limit`. Batch entries carry the same object. See [Errors and limits](/mcp/errors-and-limits) for what each means. When the arguments are wrong, the message ends with a pointer to the operation's schema, such as `Arguments: talkbar_tools {"tool":"notes.get"}`. The five tools also refuse keys they do not take, by name. Only a tool name other than these five is a protocol error (JSON-RPC `-32602`), and so is a call your client cancels (see [Wire format](#wire-format)). ## Tool list changes TalkBar announces `notifications/tools/list_changed` when a switch in **MCP Access** changes the definitions of these five tools. It checks at the start of each tool call and does not poll, so the notice arrives with your next call. The definitions change when: - you turn a read on or off (because `talkbar_read` lists the reads), - you turn `workspace.search` on or off (`talkbar_find` appears or goes), - you turn on the first, or turn off the last, operation behind `talkbar_change` or `talkbar_delete` (the tool appears or goes). Other write switches, and **Allow deletes without confirmation**, leave the five tools as they are and are not announced. A switched-off write shows under `off` in `talkbar_tools` and answers `turned_off` when called. If MCP was off when your app connected, the server did not offer tools at all. Reconnect TalkBar in your app after you turn MCP on. ## Paging Each list says how to get the next page. Pass the value back in the matching argument: | The answer holds | Send it back as | Operations | | --- | --- | --- | | `nextCursor` | `cursor` | `sessions.list`, `notes.list`, `chats.list`, `knowledge.suggestions.list` | | `nextOffset` | `offset` | `projects.list`, `knowledge.list`, `contacts.sessions`, `calendar.upcoming`, `notes.get`, `documents.read` | | `nextTurnOffset` | `turnOffset` | `sessions.transcript` | | `nextBeforeSequence` | `beforeSequence` | `chats.get` | | the last session id | `after` | `exports.sessions` | - A cursor must be one TalkBar returned. A missing or `null` next value means you have the last page. - Page sizes differ by operation. Each operation's schema gives its `limit` range; a value outside it is refused, never clamped. - `notes.get`, `documents.read` and `sessions.transcript` page long text with `maxChars`, from 1,000 to 200,000 characters (20,000 by default). An offset past the end is refused. - `sessions.transcript` pages hold whole turns. See [Read a transcript in pages](/mcp/examples#find-a-session-and-read-its-transcript-in-pages). ## Wire format For people writing their own MCP client: - **Transport:** standard input and output, one JSON-RPC 2.0 message per line, up to 8 MB per message. - **Start:** send `initialize` first. Any other request before it gets `-32601` ("Send initialize first"); notifications before it are dropped. A second `initialize` gets `-32600`. - **Malformed input:** a line that is not JSON gets `-32700` with `"id": null`. A JSON array (a JSON-RPC batch) gets one `-32600` reply: MCP has no batches, so send one message per line, or use `{"calls": [...]}`. A message that is not an object, lacks `"jsonrpc": "2.0"`, or has an id that is not a string or an integer gets `-32600`. - **Tool calls:** `tools/call` needs `{"name": ""}`, and `arguments` must be an object (or left out). Otherwise it gets `-32602`. - **Order:** up to four tool calls from one client run at the same time, so answers can come back in a different order than the requests. Match them by `id`. - **Cancelling:** when your client cancels a tool call, the server answers it with a JSON-RPC error (`-32603`, "Request cancelled by the client"), not a tool result. A request cancelled before its operation starts never runs, and in a batch, operations that had not started yet do not run. - **Resources and prompts:** none are offered. The resource lists are empty. ## Related - [Operations reference](/mcp/operations) - [Access and permissions](/mcp/access-and-permissions) - [Errors and limits](/mcp/errors-and-limits) - [Examples](/mcp/examples) - [talkbar-cli](/mcp/cli) --- # talkbar-cli Run TalkBar operations from a terminal or script with talkbar-cli, the same program that serves MCP. Commands, options, input, output and exit codes. Canonical URL: https://docs.talkbar.app/mcp/cli `talkbar-cli` is the command-line program that ships with TalkBar. It runs the same operations an AI assistant can run over MCP, from a terminal, a script or an AI agent that can run commands. It also starts the MCP server and runs exports in the background. ## Before you start - `talkbar-cli` ships with TalkBar. **Settings → MCP Access → Executable path** shows where. Use **Add to PATH** there to run it by name from any terminal. See [Where talkbar-cli is installed](/mcp/setup#where-talkbar-cli-is-installed). - It opens your TalkBar data folder, or the folder in `TALKBAR_DATA_ROOT` when that is set. Find the actual path in **Settings → MCP Access → Data root**. The app can be open or closed. - It does what you type, as you. The MCP Access switches do not apply to it, but administrator rules and plan limits do. See [What the command line ignores](/mcp/access-and-permissions#what-the-command-line-ignores). ```shell talkbar-cli --version talkbar-cli --help talkbar-cli tools --help ``` Examples use a POSIX shell on macOS or PowerShell on Windows. If a shell handles JSON quotes differently, use `--args-file`. ## Commands | Command | What it does | | --- | --- | | `tools list [--compact]` | Lists the operations. | | `tools info ` | Shows one operation: what it does, its default MCP switch and its arguments. | | `tools call [--args \| --args - \| --args-file ]` | Runs one operation and prints its result as JSON. | | `tools batch [--file ] [--stop-on-error]` | Runs many operations in one process and prints their results as one JSON array. | | `search …` | Searches the workspace, as the app's search does. | | `serve [--transport stdio]` | Starts the MCP server. Your AI app runs this for you. | | `exports run`, `exports worker`, `exports notion connect` | Delivers queued exports and connects Notion. See [Exports](#exports). | `talkbar-cli call …` (without `tools`) is a usage error that suggests `talkbar-cli tools call`. ## Global options These work before or after the command: | Option | What it does | Default | | --- | --- | --- | | `--output json` | Prints JSON instead of a table for `tools list`, `tools info` and `search`, and prints errors as JSON on standard output. `tools call` and `tools batch` always print JSON. | `table` | | `--db ` | Opens this TalkBar database file instead of the data folder. The file must already exist and be a TalkBar database; a wrong path is refused, never created. | The data folder's database | | `-v`, `--verbose` | Prints TalkBar's internal events on standard error as JSON lines. A command that raises none prints nothing extra. | Off | ## List and inspect operations ```shell talkbar-cli tools list talkbar-cli tools list --compact talkbar-cli tools info notes.create talkbar-cli --output json tools info notes.create ``` - `tools list` prints a table of id, kind (`read` or `mutation`), category and description, then a total. With `--output json`, each operation comes with its title, description, category, kind, default MCP switch and full input schema. - `tools list --compact` prints one line per operation: id, kind (`read` or `change`) and summary, separated by tabs. It is the cheapest index for scripts and AI agents. - `tools info ` prints the operation's description, whether it is on by default in MCP, a usage line, and the arguments it accepts as a JSON Schema. Arguments are camelCase JSON. The list holds every operation an administrator has not blocked. For each operation's arguments and results, see the [operations reference](/mcp/operations). ## Run one operation Pass the arguments as a JSON object: ```shell talkbar-cli tools call sessions.list --args '{"limit":5}' talkbar-cli tools call notes.get --args '{"noteId":"note-k2v9w8x7c6b5n4m3l2j1h0g9"}' ``` `workspaceId` is optional, as in MCP: without it, the workspace open in the app is used. ### Arguments from standard input or a file Long text, such as a note body, is easier to pass through standard input or a file than on the command line: | Form | Reads the arguments from | | --- | --- | | `--args ''` | The command line. Default `{}`. | | `--args -` | Standard input | | `--args-file ` | A file. `--args-file -` also means standard input. | ### Windows ```powershell Get-Content note.json -Raw | talkbar-cli tools call notes.create --args - ``` ### macOS ```shell cat note.json | talkbar-cli tools call notes.create --args - ``` ```shell talkbar-cli tools call notes.create --args-file note.json ``` ```json [note.json] { "title": "Weekly sync follow-ups", "markdown": "## Follow-ups\n\n- Send the revised quote to Dana\n- Book the next sync" } ``` Files and piped text saved with a UTF-8 byte order mark, as Windows PowerShell 5 writes them, are read correctly. PowerShell and `cmd` treat quotes in JSON differently. If `--args '{...}'` gives "Invalid JSON arguments", put the JSON in a file and use `--args-file`. ## Run a batch `tools batch` runs many operations in one process, in order. It is faster than one command per operation, and the open app refreshes once for all of them. ```shell '[{"tool":"notes.list","args":{"limit":3}},{"tool":"sessions.list","args":{"limit":5}}]' | talkbar-cli tools batch talkbar-cli tools batch --file calls.json --stop-on-error ``` - Input is a JSON array of `{"tool", "args"}`, or the MCP form `{"calls": [...], "stopOnError": true}`. It comes from `--file`, or from standard input when `--file` is left out or is `-`. - There is no 20-operation cap, as there is in MCP. `[]` prints `[]`. - `--stop-on-error` (or `"stopOnError": true`) stops at the first failed operation. - The output is always one JSON array, one entry per operation that ran: ```json [ { "tool": "notes.list", "ok": true, "result": { "items": [], "nextCursor": null, "hasMore": false, "totalCount": 0 } }, { "tool": "sessions.get", "ok": false, "error": { "code": "not_found", "message": "Session not found in workspace" } } ] ``` The command exits with 1 when any operation failed, after printing every result. Standard error then says how many failed, for example `1 of 2 operations failed`. ## Search `search` is the app's universal search from the terminal, transcript snippets included: ```shell talkbar-cli search pricing review talkbar-cli search "renewal date" --kinds session,note --limit 10 talkbar-cli search budget --match any --output json ``` | Option | What it does | Default | | --- | --- | --- | | `--workspace ` | Searches this workspace | The workspace open in the app | | `--project ` | Only items in this project | All projects | | `--kinds ` | Comma-separated: `session`, `note`, `chat`, `action_item`, `document`, `memory`, `person`, `company`, `project`, `series` | All kinds | | `--limit ` | Most results, 1 to 100 | 20 | | `--match all\|any` | `all`: every word must match. `any`: reads the words as a natural-language request. | `all` | | `--include-archived` | Also finds archived series, people, companies and knowledge cards | Off | The table output groups matches by kind, each with its title, a snippet and its app link. `--output json` prints the same object as [`talkbar_find`](/mcp/tools#talkbar_find). `search` requires every word by default, like the search box in the app. `talkbar_find` over MCP defaults to `any`. ## Serve MCP ```shell talkbar-cli serve --transport stdio ``` Starts the MCP server on standard input and output. `stdio` is the only transport and the default. Your AI app runs this command itself, with `TALKBAR_DATA_ROOT` set; see [Set up MCP](/mcp/setup). Unlike the other commands, `serve` follows every switch in **Settings → MCP Access**. `--output` has no effect on it. ## Exports The `exports` command delivers queued exports, the same work the app does while it runs. Set up destinations in the app first; see [Exports](/sharing/exports). ```shell talkbar-cli exports run --workspace WORKSPACE_ID --batch BATCH_ID --wait talkbar-cli exports worker talkbar-cli exports worker --drain ``` | Command | What it does | | --- | --- | | `exports run --workspace --batch ` | Runs one pass of the export batch you name, then prints the batch's status as JSON. | | `… --wait` | Keeps going while any delivery in the batch is scheduled or exporting. | | `… --timeout ` | With `--wait`, gives up after this many seconds and exits with 1. Default 600. | | `exports worker` | Runs automatic and other due exports until you stop it with `Ctrl+C`. | | `exports worker --drain` | Runs the exports due now, then exits. | | `exports notion connect --workspace --destination ` | Reads a Notion token from standard input and saves it, encrypted, for that Notion destination. | `exports` commands need `--workspace` (find it with `tools call workspace.list`). `exports notion connect` refuses to read the token from the keyboard, so it is never shown on screen; pipe it from your password manager instead: ### Windows ```powershell Get-Secret -Name TalkBarNotionToken -AsPlainText | talkbar-cli exports notion connect --workspace WORKSPACE_ID --destination DESTINATION_ID ``` ### macOS Pipe your password manager’s token output to `talkbar-cli exports notion connect --workspace WORKSPACE_ID --destination DESTINATION_ID`. To queue an export in the first place, use `tools call exports.enqueue`. See [Export a session](/mcp/examples#export-a-session). ## Output and errors - **Standard output holds only results.** Results are JSON: pretty-printed at a terminal, compact when piped to another program or an AI agent. - **Errors go to standard error** as a line starting with `Error:`. For a wrong argument, it also suggests `tools info `; for an unknown operation, `tools list`. - **With `--output json`**, a failed command also prints the error on standard output, in the same shape MCP uses: ```json {"error":{"code":"not_found","message":"Note not found in workspace"}} ``` `tools call` prints the operation's own code (`not_found`, `invalid_arguments`, `plan_limit` and so on); other failures, such as a wrong `--db` path or an administrator rule, print `"code": "failed"`. `tools batch` prints only its results array. Read standard output on its own; don't merge standard error into it (`2>&1`). ### Exit codes | Code | Meaning | | --- | --- | | `0` | Done | | `1` | Refused or failed. For `tools batch`, at least one operation failed. | | `2` | Usage error: an unknown command or option, or a missing argument | ## For AI agents with a shell An agent that can run commands, such as Claude Code or Codex, can use `talkbar-cli` instead of MCP. It costs no tool definitions, and one command can run many operations. - Get the index with `talkbar-cli tools list --compact`, and one operation's arguments with `talkbar-cli tools info `. - Batch instead of looping: one `tools batch` replaces many `tools call` runs, and each run of `talkbar-cli` takes time to start. - Send long text through `--args -` or `--args-file`. - Branch on `--output json` error codes, not on the wording of messages. - Remember that the command line ignores the MCP Access switches. Give the agent this route only if you are comfortable with it running any operation you could run yourself. ## The app refreshes itself After a successful write, `talkbar-cli` (and the MCP server) tells the running TalkBar app what changed, over a private local channel. The app refreshes the screens and the tray menu that show those items. When the app is closed, nothing is sent and nothing slows down. ## Related - [MCP overview](/mcp/overview) - [Access and permissions](/mcp/access-and-permissions) - [Errors and limits](/mcp/errors-and-limits) - [Examples](/mcp/examples) - [Operations reference](/mcp/operations) --- # Operations reference Every operation an assistant can run through TalkBar MCP or the TalkBar CLI, with arguments, defaults, permissions and results. Canonical URL: https://docs.talkbar.app/mcp/operations TalkBar offers 144 operations (57 reads and 87 writes) to AI assistants through MCP and to scripts through the TalkBar CLI. This reference documents each one: what it does, which MCP tool runs it, whether it is on by default, its arguments and what it returns. ## Operations by category | Category | Read | Write | Total | | --- | ---: | ---: | ---: | | [Workspace and profile](/mcp/operations/workspace-and-profile) | 5 | 2 | 7 | | [Sessions](/mcp/operations/sessions) | 10 | 11 | 21 | | [Projects and notes](/mcp/operations/projects-and-notes) | 6 | 12 | 18 | | [Action items](/mcp/operations/action-items) | 2 | 4 | 6 | | [Knowledge](/mcp/operations/knowledge) | 3 | 13 | 16 | | [People and companies](/mcp/operations/people-and-companies) | 5 | 8 | 13 | | [Topics and markers](/mcp/operations/topics-and-markers) | 3 | 8 | 11 | | [Chats and documents](/mcp/operations/chats-and-documents) | 6 | 4 | 10 | | [Calendar and series](/mcp/operations/calendar-and-series) | 8 | 14 | 22 | | [Scheduler](/mcp/operations/scheduler) | 3 | 2 | 5 | | [Exports](/mcp/operations/exports) | 6 | 9 | 15 | | **All** | **57** | **87** | **144** | ## How to read this reference Each operation has its own section, headed by its name (for example `sessions.get`), with a line like this: **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` | Label | Meaning | | --- | --- | | **Kind** | **Read** operations only read. **Write** operations change something. | | **Runs with** | The MCP tool that runs it. Reads run with [`talkbar_read`](/mcp/tools#talkbar_read). Writes run with [`talkbar_change`](/mcp/tools#talkbar_change), except the 15 that move items to the Trash, archive or delete them, or call off a planned meeting: those run only with [`talkbar_delete`](/mcp/tools#talkbar_delete). They are [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused, unless you turn on **Allow deletes without confirmation**. | | **MCP switch** | Whether the operation is on when you first set up MCP. You turn each one on or off in **Settings → MCP Access**. 81 operations start on and 63 start off: reads start on; changes to your items start off, while most calendar, series, scheduler and export operations start on. A switched-off operation answers `turned_off`. The CLI ignores these switches. | | **Policy group** | The group an administrator's policy can allow or block. If your organization manages TalkBar, a blocked group is refused for MCP and the CLI alike. See [Access and permissions](/mcp/access-and-permissions). | ### Policy groups | Group | What it covers | Operations | | --- | --- | --- | | `metadata` | Names, counts, lists and schedules, with no meeting text: workspaces, plan, session lists and figures, the recording session, project lists, and calendar and series reads. | 14 | | `content` | Reads that return meeting text: summaries, transcripts, notes, chats, cards, people, search snippets, meeting prep and export previews. | 35 | | `contentChanges` | Every change to sessions, projects, notes, action items, knowledge, people, topics, markers, chats, documents, your profile and workspace names. | 62 | | `scheduling` | Changes to planned meetings and session series. | 14 | | `scheduler` | Reading and managing scheduled jobs. | 5 | | `exports` | Export settings, batches and deliveries (except `exports.preview`, which is `content`). | 14 | ### Arguments Each argument is listed with its type, and required ones are marked. Ranges, allowed values and defaults come from the operation's schema; you can also get the full schema of any operation from [`talkbar_tools`](/mcp/tools#talkbar_tools) with `{"tool": ""}`. - **`workspaceId` is optional everywhere** and is left out of the argument lists. Without it, the workspace open in the app is used. `workspace.list` takes no arguments at all and lists the workspaces you can name. - An argument an operation does not take is refused by name, never ignored. A value outside the allowed range is refused, never clamped. - Time fields ending in `Ms` are epoch milliseconds (or, where noted, milliseconds from the session start). Transcript and timeline text show times as `mm:ss` or `h:mm:ss`. - Where an argument accepts `null`, `null` clears the value, while leaving the argument out keeps it. See [Errors and limits](/mcp/errors-and-limits) for error codes, paging and plan limits. ## Calling an operation Through MCP, send the operation and its arguments to the tool that runs it: ```json {"tool": "sessions.get", "args": {"sessionId": "ses_123"}} ``` From the command line, the same call is: ```bash talkbar-cli tools call sessions.get --args '{"sessionId":"ses_123"}' ``` Run up to 20 operations in order with `{"calls": [...]}`. Calls continue past an error unless you add `"stopOnError": true` (the default is `false`). The ids in the examples on these pages are placeholders. Find real ones with [`talkbar_find`](/mcp/tools#talkbar_find) or a list operation. See [The five MCP tools](/mcp/tools) and [CLI](/mcp/cli) for the details. ## What assistants cannot do No operation records or controls recording, edits a transcript, generates a summary, changes your app settings (export destinations and rules are the exception, through the `exports.*` operations), empties the Trash, permanently deletes an item that has a Trash, or adds documents. Those stay in the app. ## Related - [MCP overview](/mcp/overview) - [The five MCP tools](/mcp/tools) - [Access and permissions](/mcp/access-and-permissions) - [Errors and limits](/mcp/errors-and-limits) - [Examples](/mcp/examples) --- # Examples Practical TalkBar MCP and CLI walkthroughs with real requests and responses, from asking about last week's sessions to bookmarking a live recording. Canonical URL: https://docs.talkbar.app/mcp/examples These walkthroughs show what happens when you ask an assistant to work with TalkBar: which tool it calls, with which arguments, and what comes back. Ids, times and text are made up, and long answers are shortened, but every request and response has the shape TalkBar really uses. You don't have to write these requests yourself. Your AI app writes them from your question. They are here so you know what an assistant can do and how to check its work. ## Ask about last week's sessions **Setup:** turn on MCP and connect Claude Desktop, as in [Set up MCP](/mcp/setup). Reading is on by default, so nothing else is needed. Then ask Claude: "What did I discuss in my TalkBar sessions last week?" The assistant lists the sessions that started in that week with `talkbar_read`. Times are in milliseconds since 1970 (UTC); `startedBeforeMs` is exclusive. ```json [talkbar_read] { "tool": "sessions.list", "args": { "startedAfterMs": 1792368000000, "startedBeforeMs": 1792972800000, "limit": 20 } } ``` ```json [Response] { "items": [ { "sessionId": "0b7e4d1a-93c2-4f5e-8a61-2f9d3c7b5e08", "title": "Weekly sync", "status": "complete", "startedAtMs": 1792747800000, "endedAtMs": 1792749940000, "projectId": "project-p8d3k2m1q9w7e5r4t6y0u2i1", "seriesId": null, "participantCount": 4, "pinned": false, "source": "live", "private": false }, { "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "title": "Pricing review with Acme", "status": "complete", "startedAtMs": 1792594800000, "endedAtMs": 1792597632000, "projectId": "project-p8d3k2m1q9w7e5r4t6y0u2i1", "seriesId": null, "participantCount": 3, "pinned": true, "source": "live", "private": false } ], "nextCursor": null, "hasMore": false, "totalCount": 2 } ``` Newest sessions come first. To read the summaries, the assistant batches one `sessions.get` per session in a single call: ```json [talkbar_read] { "calls": [ { "tool": "sessions.get", "args": { "sessionId": "0b7e4d1a-93c2-4f5e-8a61-2f9d3c7b5e08" } }, { "tool": "sessions.get", "args": { "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10" } } ] } ``` The answer is `{"results": [...]}`, one entry per session, each with the full final summary, its sections, action items and decisions. Claude then writes you a recap. ## Find a session and read its transcript in pages Ask: "Find my pricing review with Acme and show me what Dana said about the discount." First the assistant searches, to get the session's id: ```json [talkbar_find] { "query": "pricing review Acme", "kinds": ["session"], "limit": 3 } ``` The first match has `"kind": "session"` and `"id": "6f1c2a9e-…"`. Then it reads the transcript. A transcript comes in pages of whole turns, 20,000 characters each by default. `speaker` keeps one person's turns (any part of the name, ignoring case): ```json [talkbar_read] { "tool": "sessions.transcript", "args": { "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "speaker": "Dana", "maxChars": 4000 } } ``` ```json [Response] { "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "title": "Pricing review with Acme", "startedAtMs": 1792594800000, "private": false, "truncated": true, "excludedFromAiSpeakers": [], "nextCursor": null, "totalTurns": 38, "turnOffset": 0, "nextTurnOffset": 14, "transcript": "[02:15] Dana Lee: We can go to twelve percent if the contract is two years.\n[02:41] Dana Lee: That's the most I can do this quarter.\n…" } ``` `truncated: true` means there is more. The assistant passes `nextTurnOffset` back as `turnOffset` for the next page, and stops when `nextTurnOffset` is `null`: ```json [talkbar_read] { "tool": "sessions.transcript", "args": { "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "speaker": "Dana", "maxChars": 4000, "turnOffset": 14 } } ``` With `"format": "json"`, the transcript comes back as `turns` instead, each with `turnId`, `startMs` and `endMs` (milliseconds from the session start), `speaker` and `text`. Use that form when you want to bookmark a turn or tie an action item to it. The same read from a terminal: ```shell talkbar-cli tools call sessions.transcript --args-file read.json ``` ## Create a note and an action item **Setup:** in **Settings → MCP Access**, open the **Notes** row and switch on **Create note**, then open **Action items** and switch on **Create action item** (`action_items.create`). Leave the other writes off if you don't need them. Ask: "Write up the follow-ups from the Acme pricing review as a note on that session, and give me an action item to send the revised quote by Tuesday." The assistant sends both writes in one `talkbar_change` batch: ```json [talkbar_change] { "calls": [ { "tool": "notes.create", "args": { "title": "Acme pricing follow-ups", "markdown": "## Follow-ups\n\n- Revised quote at 12% for a two-year term\n- Confirm the start date with legal", "sessionIds": ["6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10"] } }, { "tool": "action_items.create", "args": { "title": "Send the revised quote to Acme", "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "itemType": "task", "dueAtMs": 1793725200000, "assignees": ["Alex Kim"] } } ], "stopOnError": true } ``` ```json [Response] { "results": [ { "tool": "notes.create", "ok": true, "result": { "noteId": "note-k2v9w8x7c6b5n4m3l2j1h0g9", "title": "Acme pricing follow-ups", "pinned": false, "sessionId": null, "updatedAt": 1793369525000, "projectId": null, "sessionIds": ["6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10"] } }, { "tool": "action_items.create", "ok": true, "result": { "itemId": "outcome-x4c8v2b6n1m9q3w7e5r0t2y8", "itemType": "task", "title": "Send the revised quote to Acme", "status": "open", "dueAtMs": 1793725200000, "sessionId": "6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10", "sessionTitle": "Pricing review with Acme", "projectId": "project-p8d3k2m1q9w7e5r4t6y0u2i1", "assignees": [{ "name": "Alex Kim", "contactId": null }], "origin": "manual", "sources": [], "sessionStatus": "complete" } } ] } ``` The action item response is shortened. A note filed under a session shows on that session's page; `sessionId` stays `null` because it is not the session's own note. The action item takes the session's project unless you give another. If TalkBar is open, both show up right away. ## Add a bookmark to a live recording **Setup:** switch on **Add marker** (`markers.create`) under **Markers**. Recording itself always stays in the app. While you record, ask: "Bookmark the moment Sam mentioned the budget freeze." First the assistant finds the session that is recording now: ```json [talkbar_read] { "tool": "sessions.recording" } ``` ```json [Response] { "recording": { "sessionId": "c3a9f2e7-1d84-4b6a-9e05-7f2b8d1c6a34", "title": "Budget planning", "startedAtMs": 1793368800000, "elapsedMs": 725000, "revision": "…", "appRunning": true, "stale": false } } ``` `recording` is `null` when nothing is recording. `stale: true` would mean TalkBar is not running, so the session only looks like it is recording. Then it reads the transcript so far as JSON. A read with `cursor: "0:"` returns turns in the order they changed, plus a `nextCursor` to fetch only what is new next time: ```json [talkbar_read] { "tool": "sessions.transcript", "args": { "sessionId": "c3a9f2e7-1d84-4b6a-9e05-7f2b8d1c6a34", "format": "json", "cursor": "0:" } } ``` ```json [Response] { "sessionId": "c3a9f2e7-1d84-4b6a-9e05-7f2b8d1c6a34", "title": "Budget planning", "startedAtMs": 1793368800000, "private": false, "truncated": false, "excludedFromAiSpeakers": [], "nextCursor": "1793369523871:turn-42", "recording": true, "turns": [ { "turnId": "turn-42", "chunkId": "chunk-17", "provisional": true, "startMs": 641000, "endMs": 652500, "speaker": "Sam Ortiz", "isUser": false, "excludedFromAi": false, "text": "Heads up, finance just told us there's a budget freeze until January.", "translatedText": null } ] } ``` It adds the bookmark at that turn, with a short note: ```json [talkbar_change] { "tool": "markers.create", "args": { "sessionId": "c3a9f2e7-1d84-4b6a-9e05-7f2b8d1c6a34", "turnId": "turn-42", "body": "Budget freeze until January" } } ``` ```json [Response] { "markerId": "…", "sessionId": "c3a9f2e7-1d84-4b6a-9e05-7f2b8d1c6a34", "kind": "bookmark", "body": "Budget freeze until January", "quote": null, "atMs": 641000, "turnId": "turn-42", "chunkId": null, "pointId": null, "color": "", "updatedAt": 1793369525000, "sessionStatus": "recording" } ``` The bookmark appears on the recording screen right away. Instead of `turnId`, an assistant can place a bookmark with `chunkId`, `pointId` (a timeline point from `sessions.timeline`), `atMs` (a moment from the session start) or `quote` (the words it is about). ## Export a session **Setup:** add an export destination in the app first, for example a folder in your Obsidian vault; see [Exports](/sharing/exports). Export operations are on by default once MCP is on. Ask: "Export the Acme pricing review to my Obsidian vault." The assistant looks up your destinations: ```json [talkbar_read] { "tool": "exports.config" } ``` ```json [Response] { "destinations": [ { "destinationId": "5d2e7a10-8c3b-4f69-b1e4-0a9c6d3f2b87", "workspaceId": "…", "name": "Obsidian vault", "format": "obsidian", "location": "PATH_TO_VAULT/Meetings", "enabled": true, "layout": "flat", "credentialRef": null } ], "rules": [] } ``` Then it queues the export, choosing what to include: ```json [talkbar_change] { "tool": "exports.enqueue", "args": { "sessionIds": ["6f1c2a9e-4b7d-4c1e-9a53-0d2e8b7f4c10"], "destinationIds": ["5d2e7a10-8c3b-4f69-b1e4-0a9c6d3f2b87"], "selection": { "summary": true, "transcript": true, "metadata": true, "notes": true, "audio": "none" } } } ``` The answer is the new export batch, with its `batchId`, a `status` and one entry in `deliveries` per session and destination. `exports.enqueue` only queues the work. The TalkBar app delivers queued exports while it runs. To deliver now, the assistant can call `exports.run` with the `batchId`, then check with `exports.status`: ```json [talkbar_change] { "tool": "exports.run", "args": { "batchId": "…" } } ``` A delivered entry has `"status": "exported"` and its `location`. A session that is still recording cannot be queued; that call answers `session_recording`. From a terminal, `talkbar-cli exports run --workspace WORKSPACE_ID --batch BATCH_ID --wait` keeps delivering until the batch is done. See [talkbar-cli exports](/mcp/cli#exports). ## Delete safely **Setup:** switch on **Move note to Trash** (`notes.trash`) under **Notes**. Keep **Allow deletes without confirmation** off. Ask: "Trash the old Acme draft note." The assistant finds the note with `talkbar_find`, then calls `talkbar_delete`: ```json [talkbar_delete] { "tool": "notes.trash", "args": { "noteId": "note-a1s2d3f4g5h6j7k8l9z0x1c2" } } ``` Before anything runs, your AI app shows TalkBar's question: ```text An assistant wants TalkBar to run: - notes.trash {"noteId":"note-a1s2d3f4g5h6j7k8l9z0x1c2"} Confirm to run it, or decline to run nothing. ``` If you decline, or don't answer within 5 minutes, nothing runs and the assistant gets: ```json { "error": { "code": "declined", "message": "The user did not confirm, so nothing ran" } } ``` If you confirm, the note moves to the Trash: ```json { "noteId": "note-a1s2d3f4g5h6j7k8l9z0x1c2", "trashed": true } ``` Changed your mind? `notes.restore` brings it back. It runs through `talkbar_change`, so it needs no confirmation, but you have to switch on **Restore note**: ```json [talkbar_change] { "tool": "notes.restore", "args": { "noteId": "note-a1s2d3f4g5h6j7k8l9z0x1c2" } } ``` ```json [Response] { "noteId": "note-a1s2d3f4g5h6j7k8l9z0x1c2", "restored": true } ``` `notes.trash.list` lists what is in the notes Trash. Nothing an assistant does deletes a note for good; emptying the Trash stays in the app. If your AI app cannot show questions from a server, the delete is refused with `confirmation_unavailable` instead, and nothing runs. See [Apps that cannot ask](/mcp/access-and-permissions#apps-that-cannot-ask). ## Related - [Set up MCP](/mcp/setup) - [The five MCP tools](/mcp/tools) - [Access and permissions](/mcp/access-and-permissions) - [Errors and limits](/mcp/errors-and-limits) - [talkbar-cli](/mcp/cli) - [Operations reference](/mcp/operations) --- # Errors and limits Every error code TalkBar MCP and talkbar-cli return, what to do about each, plus plan limits, concurrency, argument rules and safe retries. Canonical URL: https://docs.talkbar.app/mcp/errors-and-limits When an operation is refused or fails, TalkBar answers with a short code and a sentence that says what to change. Assistants and scripts should branch on the code; the sentence is for people. This page lists every code and the rules behind them. ## Error shape Over MCP, a refused or failed operation is a normal tool result with `isError: true`. In a batch, it is the entry's `error`. With `talkbar-cli --output json`, it is printed on standard output. The shape is the same everywhere: ```json { "error": { "code": "invalid_arguments", "message": "notes.create does not take `content`. Note text goes in markdown. It takes: markdown, pinned, projectId, sessionIds, title, workspaceId. Arguments: talkbar_tools {\"tool\":\"notes.create\"}" } } ``` Some codes add fields, listed below. Only a call to a tool name other than the [five MCP tools](/mcp/tools), or a call your client cancels, gets a JSON-RPC protocol error instead. ## Error codes | Code | What it means | What to do | | --- | --- | --- | | `invalid_arguments` | The request itself is wrong: an unknown argument, a wrong type, a value out of range or not in the allowed list, a missing required argument, an empty id. | Change the request. The message names the argument; `talkbar_tools {"tool": ""}` or `talkbar-cli tools info ` shows what the operation takes. | | `not_found` | The id is unknown, belongs to another workspace, or the item is in the Trash. Also an unknown operation name. | Find the right id with `talkbar_find` or a list. For an item in the Trash, the message says "… is in the Trash; restore it first". | | `turned_off` | You switched the operation off in **Settings → MCP Access**, or MCP is off. MCP only. | Ask the user to turn it on. Repeating the call will not help. | | `failed` | The request is well formed, but the item's current state refuses it (for example "A topic with this name already exists"), an administrator rule blocks it, or something went wrong inside TalkBar. | Read the message. Change the item's state or the request; don't repeat the same call unchanged. | | `declined` | The user did not confirm a `talkbar_delete` call, or did not answer within 5 minutes. Nothing ran. | Don't retry on your own. Ask the user what they want. | | `confirmation_unavailable` | A `talkbar_delete` call came from a client that cannot ask the user, and **Allow deletes without confirmation** is off. Nothing ran. | Use a client that supports MCP elicitation, or ask the user to change the setting. | | `busy` | Another write got to the database first, or an export run is already in progress. Carries `"retryable": true` and `retryAfterMs`. | Wait `retryAfterMs`, then send the same call again. If it created something, check first that it is not already there. | | `conflict` | `notes.update` was sent with an `expectedUpdatedAt` the note no longer has: someone changed it since you read it. Carries the note's current `updatedAt`. | Read the note again with `notes.get` and make your edit on what it holds now. | | `session_recording` | The session is still recording. Answers `sessions.trash`, the speaker edits (`sessions.speakers.rename`, `.link`, `.unlink`) and `exports.enqueue`. | Try again after the recording stops, when `sessions.recording` no longer returns it. | | `limit_reached` | A fixed limit of the item, not of your plan. Carries `limit` and `max`. Today: a session holds at most 24 knowledge cards (`"limit": "sessionCards"`). | Make room first, for example take a card out with `sessions.cards.detach`. | | `plan_limit` | Your TalkBar plan does not allow it. Carries `limit`, and for counted limits `max`, `used` and `plan`. | Free up room or upgrade in the app. Retrying will not help. See [Plan limits](#plan-limits). | ### `invalid_arguments` or `failed`? - `invalid_arguments` means change the request: a bad value, an unknown type or color, an empty name. - `failed` means the request was fine, but the current state of the item refuses it: "A topic with this name already exists", "A series with this id already exists; use another id or change the existing one", "Archived series cannot take new sessions". ### `busy` and retrying ```json { "error": { "code": "busy", "message": "TalkBar's database was busy with another write. Try the same call again; if it created something, check first that it is not already there.", "retryable": true, "retryAfterMs": 1000 } } ``` `retryAfterMs` is 1,000 ms when the database was busy, and 5,000 ms when an export run is already in progress. ## Plan limits Most of what an assistant does is not limited by plan. These operations are, because they add to a count your plan caps: | Operation | `limit` | Counts | | --- | --- | --- | | `projects.create`, `projects.restore` | `projects` | Projects in the workspace the call acts on | | `sessions.restore` | `sessions` | Stored sessions in that workspace | At the limit, the call is refused: ```json { "error": { "code": "plan_limit", "limit": "projects", "max": 1, "used": 1, "plan": "free", "message": "Project limit reached (1 of 1 on Free): your plan includes 1 project, and this workspace already has 1. Move a project to Trash or upgrade the plan in TalkBar, then try again; plan.get lists the plans above Free." } } ``` - The plan comes from the license activated in the app. An assistant cannot change it. - `plan.get` reports the plan, each limit with what is used, and the plans above it. - On Business, the highest plan, the message ends "Move a project to Trash, then try again." See [Plans and license](/data/plans-and-license) for what each plan includes. ## Concurrency - **Writes run one at a time** inside one MCP server or `talkbar-cli` process, so parallel calls from one assistant never collide. Reads run in parallel. - **Other processes:** when another program is writing (the app while it records, or a second MCP server), a write waits up to 5 seconds for it before answering `busy`. - **Exports:** `exports.run` runs outside that queue, because a delivery can take a long time and must not hold up `exports.cancel`. Only one export run at a time per server; a second answers `busy`. - **Up to four calls at once:** one MCP connection runs at most four tool calls at the same time. Answers can arrive in a different order than the requests. - **Cancelled requests:** when your client cancels a call, it gets a JSON-RPC error (`-32603`, "Request cancelled by the client") rather than an error code from this page. A request cancelled before it starts never runs, and a write that was still waiting for its turn is dropped. If you switch an operation off while a write waits, it answers `turned_off`. One long-running MCP session is faster than starting `talkbar-cli` for every call. From the command line, prefer [`tools batch`](/mcp/cli#run-a-batch). ## Argument rules TalkBar checks arguments strictly, so a mistake is named rather than silently ignored: - **Unknown arguments are refused by name**, with the list the operation takes. Note text sent as `content`, `text` or `body` gets the hint "Note text goes in markdown." Unknown keys inside a nested object the schema describes are refused too. - **Wrong values are refused before any lookup.** A wrong type, a value outside the allowed list or range, or a bad array item is `invalid_arguments` before TalkBar looks up any id. So an unknown id with a wrong value names the value; a right value with an unknown id is `not_found`. - **Missing required arguments** are named next (`noteId is required`), also before any lookup. - **Exact values.** Allowed values must match exactly: `"Note"` or `" any "` is refused where `note` or `any` is expected. - **Ranges are not clamped.** A `limit`, `maxChars` or `offset` outside the range in the schema is refused. - **Ids must not be empty.** An argument ending in `Id` must not be `""` when given; use `null` to clear an optional one. A list ending in `Ids` must not hold an empty id. - **No control characters** in any argument, except tabs and line breaks. - **`args` is an object.** Leave it out or send `null` for no arguments; an array, number or string is refused as "arguments must be an object". - **Names that must not be empty** are checked after trimming spaces, so `" "` counts as empty. Notes, chat titles and the profile name may be empty, as in the app. - **Times in the past** are accepted where the app accepts them, for example logging a meeting after it happened. - **The five MCP tools** refuse keys they do not take. `talkbar_read`, `talkbar_change` and `talkbar_delete` take `tool` (with `args`) or `calls`, not both, and `stopOnError` must be `true` or `false`. ## Repeating changes safely Sending the same change twice is safe. It succeeds again and reports the current state: - Trashing what is already in the Trash, or restoring what is already live. - Archiving what is archived, or unarchiving what is not. - Pinning what is pinned. The first trash or archive date is kept. An unknown id is still `not_found`. The exception is `action_items.remove`: it removes the item for good (an item you added is deleted, an item from a summary is dismissed), so a second remove is `not_found`. Creating is not repeatable: two `notes.create` calls make two notes. After a `busy` answer to a create, check before you send it again. ## Things that are never available Whatever you switch on, an assistant cannot record or control a live session, edit a transcript, generate a summary, run TalkBar's AI features, change settings, delete anything permanently, empty a Trash, or add or re-index documents. There is no error code for these: the operations do not exist. ## Related - [The five MCP tools](/mcp/tools) - [Access and permissions](/mcp/access-and-permissions) - [talkbar-cli](/mcp/cli) - [Operations reference](/mcp/operations) --- # Action items MCP and CLI operations to list, read, create, update, complete and remove action items, follow-ups, questions and decisions. Canonical URL: https://docs.talkbar.app/mcp/operations/action-items Action item operations work with the four kinds of item TalkBar tracks: tasks, follow-ups, questions and decisions. An item belongs to a session, a project or General, and can point at the moment in a session it came from. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`action_items.list`](#action_itemslist) | Read | `talkbar_read` | On | `content` | | [`action_items.get`](#action_itemsget) | Read | `talkbar_read` | On | `content` | | [`action_items.create`](#action_itemscreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`action_items.update`](#action_itemsupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`action_items.set_status`](#action_itemsset_status) | Write | `talkbar_change` | Off | `contentChanges` | | [`action_items.remove`](#action_itemsremove) | Write | `talkbar_delete` | Off | `contentChanges` | ## Statuses by type | Type | Statuses | | --- | --- | | `task` | `open`, `done` | | `follow_up` | `open`, `done` | | `question` | `open`, `answered` | | `decision` | `active`, `superseded` | ## `action_items.list` Lists action items: tasks, follow-ups, questions and decisions. Filter by session, project, series, General, type, status, assignee or text. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string) Only the items of this session. With it, `projectId`, `seriesId`, `generalOnly` and `includeStopped` are ignored. **projectId** (string) Only items of this project. **seriesId** (string) Only items of this series. **generalOnly** (boolean) Only items in General (not tied to a project). Cannot be combined with `projectId` or `seriesId`. **itemTypes** (string[]) Only these types: `task`, `follow_up`, `question`, `decision`. **statuses** (string[]) Only these statuses: `open`, `done`, `answered`, `active`, `superseded`. **contactIds** (string[]) Only items assigned to these people. **text** (string) Text to find in titles and details. **includeStopped** (boolean) Also list carried-over items that were stopped. **limit** (integer) How many to return. From 1 to 200. Default `50`. **Returns:** `{items: [{itemId, itemType, label, title, status, dueAtMs, sessionId, sessionTitle, projectId, assignees, anchor, updatedAt}]}`. `anchor` (`{turnId, pointId, atMs}` or `null`) is the moment an item is tied to. - Resolved items (done, answered, superseded) sort last. Type and status values outside the lists above match nothing. ```json {"tool": "action_items.list", "args": {"projectId": "proj_456", "statuses": ["open"]}} ``` ## `action_items.get` Reads one action item with its details, assignees, status and sources. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **itemId** (string, required) The action item, from `action_items.list`. **Returns:** `{itemId, itemType, labelId, label, title, details, status, dueAtMs, answer, sessionId, sessionTitle, projectId, assignees: [{name, contactId}], origin, sources, resolvedAtMs, createdAt, updatedAt}`. `sources` lists the quotes and moments the item comes from. ## `action_items.create` Adds an action item to a session, a project or General. Works while the session records, and shows live. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **title** (string, required) What needs doing. Must not be empty. **sessionId** (string) Add it to this session. Without `projectId`, it takes the session's project. **projectId** (string) Add it to this project. With neither `sessionId` nor `projectId`, it goes to General. **itemType** (string) One of `task`, `follow_up`, `question`, `decision`. Default `task`. **labelId** (string) A label (such as Idea or Blocker) for the item, by id; `action_items.get` shows an item's `labelId`. Each label belongs to one item type. **details** (string) More detail. **status** (string) One of `open`, `done`, `answered`, `active`, `superseded`, as allowed for the type. Default `open` (`active` for a decision). **dueAtMs** (integer | null) Due date in epoch ms (tasks and follow-ups only). `null` for none. **answer** (string) The answer (questions only). **assignees** ((string | object)[]) Who it is for: names, or `{name, contactId}` objects with a non-empty `name`. **turnId** (string) A transcript turn (`sessions.transcript` with `format: "json"`). Ties the item to a moment in its session. Needs `sessionId`. **chunkId** (string) A live transcript chunk (`sessions.transcript` with `format: "json"`). Ties the item to a moment in its session. Needs `sessionId`. **pointId** (string) A timeline point (`sessions.timeline`). Cannot be combined with `turnId` or `chunkId`. Ties the item to a moment in its session. Needs `sessionId`. **atMs** (integer) A moment in ms from the session start. With a turn, chunk or point it must fall inside it; while recording it cannot be later than now. Ties the item to a moment in its session. Needs `sessionId`. **quote** (string) The words the item is about. On its own, it finds the one turn holding those words. Ties the item to a moment in its session. Needs `sessionId`. **Returns:** The item, as `action_items.get` returns it; in a session, also `sessionStatus` (and a `warning` when the session was interrupted or TalkBar is not running). - An id the session does not have is refused with `invalid_arguments`. - A due date on a question or decision, or an answer on anything but a question, is refused. - The item keeps its moment as well as the ids, so the app still places it after the transcript is enhanced. ```json {"tool": "action_items.create", "args": {"sessionId": "ses_123", "title": "Send revised quote", "itemType": "follow_up", "assignees": ["Dana Lee"], "quote": "send you a revised quote"}} ``` ## `action_items.update` Changes an action item's title, details, type, label, status, due date, answer or assignees. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **itemId** (string, required) The action item, from `action_items.list`. **title** (string) The new title. Must not be empty. **details** (string | null) More detail. `null` clears it. **itemType** (string) One of `task`, `follow_up`, `question`, `decision`. **labelId** (string) A label (such as Idea or Blocker) for the item, by id; `action_items.get` shows an item's `labelId`. Each label belongs to one item type. **status** (string) One of `open`, `done`, `answered`, `active`, `superseded`, as allowed for the type. **dueAtMs** (integer | null) Due date in epoch ms. `null` clears it. **answer** (string | null) The answer (questions only). `null` clears it. **assignees** ((string | object)[]) Replaces the assignees: names, or `{name, contactId}` objects. **Returns:** The item, as `action_items.get` returns it. - Give at least one field. ## `action_items.set_status` Completes or reopens an action item, with an optional answer. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **itemId** (string, required) The action item, from `action_items.list`. **status** (string, required) The new status. Tasks and follow-ups: `open` or `done`. Questions: `open` or `answered`. Decisions: `active` or `superseded`. **answer** (string) An answer to record (questions). **Returns:** The item, as `action_items.get` returns it. - A status the type does not allow is refused with `invalid_arguments`, listing the allowed ones. ```json {"tool": "action_items.set_status", "args": {"itemId": "ai_42", "status": "done"}} ``` ## `action_items.remove` Removes an action item from its board, as the app does: an item you added is deleted, an item from a summary is dismissed. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **itemId** (string, required) The action item, from `action_items.list`. **Returns:** `{removed: true, itemId, sessionId, projectId}`, plus `sessionStatus` for a session item. - There is no Trash for action items: a second remove is `not_found`. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## Related - [Operations reference](/mcp/operations) - [Sessions](/mcp/operations/sessions) - [Action items in the app](/knowledge/action-items) --- # Calendar and series MCP and CLI operations to list, schedule, prepare, move, snooze, skip and cancel planned meetings, and to manage session series and their schedules. Canonical URL: https://docs.talkbar.app/mcp/operations/calendar-and-series Calendar operations work with planned meetings (occurrences), the same ones the app's calendar and Prepare page show. Series operations manage session series and their schedules. Most of these operations are on by default in MCP Access. Assistants can plan and prepare meetings, but recording always starts in the app. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`calendar.upcoming`](#calendarupcoming) | Read | `talkbar_read` | On | `metadata` | | [`calendar.get`](#calendarget) | Read | `talkbar_read` | On | `metadata` | | [`calendar.prep`](#calendarprep) | Read | `talkbar_read` | On | `content` | | [`calendar.actionable`](#calendaractionable) | Read | `talkbar_read` | On | `metadata` | | [`calendar.schedule`](#calendarschedule) | Write | `talkbar_change` | On | `scheduling` | | [`calendar.prepare`](#calendarprepare) | Write | `talkbar_change` | On | `scheduling` | | [`calendar.prep.edit`](#calendarprepedit) | Write | `talkbar_change` | On | `scheduling` | | [`calendar.move`](#calendarmove) | Write | `talkbar_change` | On | `scheduling` | | [`calendar.snooze`](#calendarsnooze) | Write | `talkbar_change` | On | `scheduling` | | [`calendar.cancel`](#calendarcancel) | Write | `talkbar_delete` | On | `scheduling` | | [`calendar.skip`](#calendarskip) | Write | `talkbar_delete` | On | `scheduling` | | [`calendar.start`](#calendarstart) | Write | `talkbar_change` | On | `scheduling` | | [`calendar.tick`](#calendartick) | Write | `talkbar_change` | Off | `scheduling` | | [`series.list`](#serieslist) | Read | `talkbar_read` | On | `metadata` | | [`series.get`](#seriesget) | Read | `talkbar_read` | On | `metadata` | | [`series.kinds.list`](#serieskindslist) | Read | `talkbar_read` | On | `metadata` | | [`series.schedule.get`](#seriesscheduleget) | Read | `talkbar_read` | On | `metadata` | | [`series.create`](#seriescreate) | Write | `talkbar_change` | On | `scheduling` | | [`series.update`](#seriesupdate) | Write | `talkbar_change` | On | `scheduling` | | [`series.archive`](#seriesarchive) | Write | `talkbar_delete` | On | `scheduling` | | [`series.sessions.assign`](#seriessessionsassign) | Write | `talkbar_change` | On | `scheduling` | | [`series.schedule.set`](#seriesscheduleset) | Write | `talkbar_change` | On | `scheduling` | ## Meeting statuses A meeting is `planned`, `started`, `completed`, `missed`, `skipped`, `cancelled` or `unscheduled`. Times are epoch milliseconds. ## `calendar.upcoming` Lists standalone and series meetings in a time window, soonest first, in pages. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **startAtMs** (integer, required) Window start, epoch ms. Meetings that overlap the window are listed. **endAtMs** (integer, required) Window end, epoch ms. Must not be before `startAtMs`. **includeArchived** (boolean) Also list the planned meetings of archived series, which the app's calendar hides. Default `false`. **statuses** (string[]) Which meetings to list. Values: `planned`, `started`, `completed`, `missed`, `skipped`, `cancelled`. Empty or left out: planned, started, completed and missed. **limit** (integer) How many to return. From 1 to 500. Default `100`. **offset** (integer) `nextOffset` from the previous page. **Returns:** `{occurrences, nextOffset}`. Rows are meetings as `calendar.get` returns them, except that `prepared: true/false` replaces the setup itself (read it with `calendar.get` or `calendar.prep`). ```json {"tool": "calendar.upcoming", "args": {"startAtMs": 1761955200000, "endAtMs": 1762560000000}} ``` ## `calendar.get` Reads one planned meeting. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **Returns:** The meeting (occurrence): `occurrenceId`, `seriesId`, `scheduleId`, `plannedStartAtMs`, `originalStartAtMs`, `durationMinutes`, `timezone`, `status`, `sessionId`, `title`, `preparedSetupJson` (the saved start setup, as a JSON string), `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `moved`, `wasScheduled` (false for a meeting prepared without a planned time), `sessionTitle` (the linked session's name, once it has one), `quiet` (muted in the app: shown on the calendar, but never reminded or started automatically), `createdAt`, `updatedAt`. ```json {"tool": "calendar.get", "args": {"occurrenceId": "occ_1"}} ``` ## `calendar.prep` Reads what the app's Prepare page shows for a meeting: prep notes, the cards and documents it starts with, the action items it brings in, and the series' previous session. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **Returns:** `occurrenceId`, `title`, `status`, `plannedStartAtMs`, `durationMinutes`, `seriesId`, `sessionId`, `prepared`, `preparable`, `projectId`, `sessionTemplateId`, `notes` (`[{noteId, title, preview, updatedAt}]`), `cards` (`[{memoryId, title, type, status}]`), `documents`, `actionItems` (`{carried, carriedOverflow, added, skipped, suggested}`) and `previousSession` (`{sessionId, title, startedAtMs, private}` or `null`). - Read a prep note with `notes.get` and the previous session's summary with `sessions.get`. Prep notes are written in the app. ```json {"tool": "calendar.prep", "args": {"occurrenceId": "occ_1"}} ``` ## `calendar.actionable` Lists meeting reminders waiting for Start, Snooze or Skip. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments:** none besides `workspaceId`. **Returns:** An array of reminders: `[{jobId, occurrenceId, offsetMinutes, remindAtMs, status, snoozedUntilMs, createdAt, updatedAt}]`, soonest first. Read the meeting with `calendar.get`. ## `calendar.schedule` Schedules a standalone or series meeting. It never starts recording. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) An id you choose for the new meeting. Must be new. **plannedStartAtMs** (integer, required) Start time, epoch ms. A past time is accepted, so a meeting can be logged after it happened. **durationMinutes** (integer, required) Length in minutes. At least 1. **timezone** (string, required) IANA time zone, for example `America/New_York`. **seriesId** (string) Add the meeting to this series. It must be an active (not archived) series. **title** (string) The meeting title. 1 to 200 characters. **reminderOffsetsMinutes** (integer[]) Minutes before the start to remind you. Up to 6 values, each from 0 to 10,080; duplicates are removed. Default `[10]`. **startMode** (string) `prompt` (ask before starting) or `automatic` (start after a countdown, in the app). Default `prompt`. **autoStartCountdownSeconds** (integer) Seconds of countdown before an automatic start. From 5 to 300. Default `60`. **preparedSetup** (object) The start setup the app's meeting prep saves. Fields left out keep the app's defaults. Unknown fields are refused. - `source`: `mic`, `system` or `both`; `micDeviceId`. - `sessionTemplateId`, `projectId`, `topicIds`, `memoryIds` (knowledge cards), `documentIds`. - `summariesEnabled`, `summaryLanguage` (`auto` or a summary language code), `summaryLength` (`short`, `standard` or `detailed`), `summaryModel` (`{providerId, modelId}`). - `participants`: `[{name, contactId}]`; each needs a `name`. - `memoryMode`: `normal`, `session_only`, `manual_only` or `sensitive`. `speakerMode`: `solo`, `duo`, `small` or `large`. `privateSession`. - `origin`: `{name, url}`. - `actionItemIds`, `skippedActionItemIds`: read-only; the meeting keeps the lists it has (change them with `calendar.prep.edit`). Templates, projects, people, cards and documents must be in the workspace, and cards must be approved. **Returns:** The meeting (occurrence): `occurrenceId`, `seriesId`, `scheduleId`, `plannedStartAtMs`, `originalStartAtMs`, `durationMinutes`, `timezone`, `status`, `sessionId`, `title`, `preparedSetupJson` (the saved start setup, as a JSON string), `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `moved`, `wasScheduled` (false for a meeting prepared without a planned time), `sessionTitle` (the linked session's name, once it has one), `quiet` (muted in the app: shown on the calendar, but never reminded or started automatically), `createdAt`, `updatedAt`. Its status is `planned`. - Creates reminders as the app does. A duplicate `occurrenceId` is refused with `failed`. ```json {"tool": "calendar.schedule", "args": {"occurrenceId": "occ_weekly_sync_1107", "plannedStartAtMs": 1762531200000, "durationMinutes": 30, "timezone": "America/New_York", "title": "Weekly sync"}} ``` ## `calendar.prepare` Changes a meeting's title, start setup, reminders or start mode. Fields left out keep their values. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **title** (string | null) The new title, 1 to 200 characters, or `null` to clear it. **reminderOffsetsMinutes** (integer[]) Minutes before the start to remind you. Up to 6 values, each from 0 to 10,080. **startMode** (string) `prompt` or `automatic`. **autoStartCountdownSeconds** (integer) Seconds of countdown before an automatic start. From 5 to 300. **preparedSetup** (object) The start setup, as for `calendar.schedule`. When given, it replaces the stored setup as a whole: read it with `calendar.get`, change it, and send it all back. `null` clears it. **Returns:** The meeting (occurrence): `occurrenceId`, `seriesId`, `scheduleId`, `plannedStartAtMs`, `originalStartAtMs`, `durationMinutes`, `timezone`, `status`, `sessionId`, `title`, `preparedSetupJson` (the saved start setup, as a JSON string), `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `moved`, `wasScheduled` (false for a meeting prepared without a planned time), `sessionTitle` (the linked session's name, once it has one), `quiet` (muted in the app: shown on the calendar, but never reminded or started automatically), `createdAt`, `updatedAt`. - Works on planned, missed and unscheduled meetings; others are refused with `failed`. Preparing a missed meeting makes it planned again. - A meeting whose start has passed always gets `prompt`. ```json {"tool": "calendar.prepare", "args": {"occurrenceId": "occ_1", "title": "Northwind kickoff", "reminderOffsetsMinutes": [15, 5]}} ``` ## `calendar.prep.edit` Adds or removes the knowledge cards, documents and action items from other meetings that a meeting starts with, or skips a carried-over action item, as the app's Prepare page does. Every edit applies, or none does. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **edits** (object[], required) The changes, 1 to 50. Each is `{kind, id, add}`: - `kind`: `memory` (a knowledge card), `document`, `actionItem` (a task, follow-up or question from another meeting) or `skippedActionItem` (a carried-over item to leave out of this meeting). - `id`: the item's id. - `add`: `true` adds (or skips); `false` removes (or brings a skipped item back). **Returns:** The meeting's prep: `occurrenceId`, `prepared`, `preparable`, `sessionId`, `projectId`, `memoryIds`, `documentIds`, `maxMemoryCount`, `maxDocumentCount`, `sessionTemplateId`, `hasContent`, `draftCount` and `actionItemCount`. `calendar.prep` shows the lists in full. - A wrong id or kind, skipping an item that is not carried over, or an item both added and skipped is refused with `invalid_arguments`, and nothing changes. - A meeting that started, was cancelled or was skipped is refused with `failed`. ```json {"tool": "calendar.prep.edit", "args": {"occurrenceId": "occ_1", "edits": [{"kind": "memory", "id": "mem_321", "add": true}, {"kind": "document", "id": "doc_8", "add": true}]}} ``` ## `calendar.move` Reschedules one meeting and updates its reminders and automatic start. Other meetings of the series are unchanged. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **plannedStartAtMs** (integer, required) The new start time, epoch ms. Must be in the future. **Returns:** The meeting (occurrence): `occurrenceId`, `seriesId`, `scheduleId`, `plannedStartAtMs`, `originalStartAtMs`, `durationMinutes`, `timezone`, `status`, `sessionId`, `title`, `preparedSetupJson` (the saved start setup, as a JSON string), `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `moved`, `wasScheduled` (false for a meeting prepared without a planned time), `sessionTitle` (the linked session's name, once it has one), `quiet` (muted in the app: shown on the calendar, but never reminded or started automatically), `createdAt`, `updatedAt`. Its status is `planned`. - Works on planned, missed and unscheduled meetings. ```json {"tool": "calendar.move", "args": {"occurrenceId": "occ_1", "plannedStartAtMs": 1762617600000}} ``` ## `calendar.snooze` Snoozes a planned meeting's reminder and cancels any automatic start countdown. The meeting stays planned. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **snoozedUntilMs** (integer, required) When to remind you again, epoch ms. Must be in the future. **Returns:** The meeting (occurrence): `occurrenceId`, `seriesId`, `scheduleId`, `plannedStartAtMs`, `originalStartAtMs`, `durationMinutes`, `timezone`, `status`, `sessionId`, `title`, `preparedSetupJson` (the saved start setup, as a JSON string), `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `moved`, `wasScheduled` (false for a meeting prepared without a planned time), `sessionTitle` (the linked session's name, once it has one), `quiet` (muted in the app: shown on the calendar, but never reminded or started automatically), `createdAt`, `updatedAt`. - Only a planned meeting can be snoozed. - Snoozing sets the meeting's start mode to `prompt`. ## `calendar.cancel` Cancels one planned meeting, with its reminders and automatic start. It does not archive the series. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **Returns:** The meeting (occurrence): `occurrenceId`, `seriesId`, `scheduleId`, `plannedStartAtMs`, `originalStartAtMs`, `durationMinutes`, `timezone`, `status`, `sessionId`, `title`, `preparedSetupJson` (the saved start setup, as a JSON string), `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `moved`, `wasScheduled` (false for a meeting prepared without a planned time), `sessionTitle` (the linked session's name, once it has one), `quiet` (muted in the app: shown on the calendar, but never reminded or started automatically), `createdAt`, `updatedAt`. Its status is `cancelled`. - Only a planned meeting can be cancelled; otherwise `failed` names its current status. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `calendar.skip` Skips one planned meeting and cancels its reminders and countdown. The series and its other meetings are unchanged. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **Returns:** The meeting (occurrence): `occurrenceId`, `seriesId`, `scheduleId`, `plannedStartAtMs`, `originalStartAtMs`, `durationMinutes`, `timezone`, `status`, `sessionId`, `title`, `preparedSetupJson` (the saved start setup, as a JSON string), `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `moved`, `wasScheduled` (false for a meeting prepared without a planned time), `sessionTitle` (the linked session's name, once it has one), `quiet` (muted in the app: shown on the calendar, but never reminded or started automatically), `createdAt`, `updatedAt`. Its status is `skipped`. - Only a planned meeting can be skipped; otherwise `failed` names its current status. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `calendar.start` Checks whether a meeting can start here. MCP and the CLI never record, so this changes nothing and only explains why the meeting cannot start. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **occurrenceId** (string, required) The planned meeting, from `calendar.upcoming`. **Returns:** `{intent: null, unavailableReason}`. `unavailableReason` is `captureHostUnavailable` for a planned meeting and `notPlanned` otherwise. - It does not check whether the app could start the meeting now. Start recording in the app. ## `calendar.tick` Runs one pass of the meeting scheduler: creates upcoming meetings from series schedules, prepares their reminders, and marks meetings that passed unrecorded as missed. It delivers no notifications and records nothing. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `scheduling` **Arguments** **horizonEndMs** (integer, required) Create meetings up to this time, epoch ms. Must not be before `nowMs`. **nowMs** (integer, required) The time to run the pass for, epoch ms. **limit** (integer) Most due items to handle in this pass. From 1 to 100. Default `32`. **Returns:** An array of automatic-start countdowns that are due: `[{kind, intent, occurrence}]`. - The app runs this itself; it is off by default in MCP Access and rarely needed by an assistant. ## `series.list` Lists session series with counts. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **includeArchived** (boolean) Also list archived series. **Returns:** An array of series (as `series.get` returns them) with `sessionCount`, `lastSessionStartedAtMs`, `nextPlannedAtMs`, `projectName`, `customKind` and `schedule` (`{enabled, scheduleKind, rrule, localDate, localTime, timezone, durationMinutes}` or `null`). ```json {"tool": "series.list", "args": {}} ``` ## `series.get` Reads one session series. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **seriesId** (string, required) The series, from `series.list`. **Returns:** The series: `seriesId`, `workspaceId`, `name`, `kind`, `customKindId`, `description`, `projectId`, `anchorContactId`, `templateId`, `startTemplateJson`, `archivedAtMs`, `createdAt`, `updatedAt`. ## `series.kinds.list` Lists the built-in series types with their suggested templates, the workspace's own series types, and the icons a type may use. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments:** none besides `workspaceId`. **Returns:** `{builtin: [{key, suggestedTemplateId}], custom: [{kindId, name, icon, createdAt, updatedAt}], icons}`. ## `series.schedule.get` Reads a series' schedule, if it has one. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **seriesId** (string, required) The series, from `series.list`. **Returns:** The schedule or `null`: `scheduleId`, `seriesId`, `enabled`, `scheduleKind`, `timezone`, `localDate`, `localTime`, `durationMinutes`, `title`, `rrule`, `reminderOffsetsMinutes`, `startMode`, `autoStartCountdownSeconds`, `effectiveFromOriginalStartMs` (set when the schedule applies from a given meeting on), `createdAt`, `updatedAt`. ## `series.create` Creates a session series, optionally linked to a project, a person and a template. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **seriesId** (string, required) An id you choose for the new series. Must be new. **name** (string, required) The series name. 1 to 120 characters. **kind** (string, required) The series type: `oneOnOne`, `standup`, `teamMeeting`, `inPersonMeeting`, `clientMeeting`, `phoneCall`, `interview`, `hiringInterview`, `userResearch`, `salesCall`, `customerCheckIn`, `investorCall`, `legalConsultation`, `boardMeeting`, `leadershipSync`, `coaching`, `mentoring`, `workshop`, `training`, `brainstorm`, `retro`, `presentation`, `presentationPractice`, `productLaunch`, `lecture`, `class`, `course`, `educationalTalk`, `tutorial`, `webinar`, `panelDiscussion`, `podcast`, `videoWatching`, `voiceJournal`, `speakingPractice` or `custom`. **customKindId** (string) With `kind: "custom"`, one of the workspace's own series types (`series.kinds.list`). **description** (string) A description. **projectId** (string) The project the series belongs to. **anchorContactId** (string) The main person the series is with. **templateId** (string) The template its sessions start with. **Returns:** The series: `seriesId`, `workspaceId`, `name`, `kind`, `customKindId`, `description`, `projectId`, `anchorContactId`, `templateId`, `startTemplateJson`, `archivedAtMs`, `createdAt`, `updatedAt`. - Sessions stay independent until you assign them with `series.sessions.assign`. A duplicate `seriesId` is refused with `failed`. ```json {"tool": "series.create", "args": {"seriesId": "ser_dana_1on1", "name": "1:1 with Dana", "kind": "oneOnOne", "anchorContactId": "ct_77"}} ``` ## `series.update` Changes a series' details. Nullable fields take `null` to clear them. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **seriesId** (string, required) The series, from `series.list`. **name** (string) The new name. 1 to 120 characters. **kind** (string) The series type, as for `series.create`. **customKindId** (string | null) One of the workspace's own series types, for `kind: "custom"`. `null` clears it. **description** (string | null) A description. `null` clears it. **projectId** (string | null) The project the series belongs to. `null` clears it. **anchorContactId** (string | null) The main person the series is with. `null` clears it. **templateId** (string | null) The template its sessions start with. `null` clears it. **Returns:** The series: `seriesId`, `workspaceId`, `name`, `kind`, `customKindId`, `description`, `projectId`, `anchorContactId`, `templateId`, `startTemplateJson`, `archivedAtMs`, `createdAt`, `updatedAt`. - Give at least one field. Member sessions are not changed. ## `series.archive` Archives or restores a series. Its sessions and history are kept. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **On** by default · policy group `scheduling` **Arguments** **seriesId** (string, required) The series, from `series.list`. **archived** (boolean, required) `true` archives, `false` restores. **Returns:** The series: `seriesId`, `workspaceId`, `name`, `kind`, `customKindId`, `description`, `projectId`, `anchorContactId`, `templateId`, `startTemplateJson`, `archivedAtMs`, `createdAt`, `updatedAt`. - Archiving hides the series' planned meetings (from the app calendar, and from `calendar.upcoming` unless `includeArchived` is set) and stops their reminders and automatic starts. It does not mark them missed. - Restoring brings future meetings back and marks the ones whose time passed while archived as `skipped`. - Archiving an archived series keeps its first archive date. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `series.sessions.assign` Moves sessions into a series, or out of their series. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **sessionIds** (string[], required) The sessions to move. At least one. A session named twice counts once. **seriesId** (string | null, required) The series, or `null` to take the sessions out of their series. Required. **Returns:** `{changed}`: how many sessions changed. - An archived series cannot take new sessions (`failed`). Unknown sessions and sessions in the Trash are `not_found`, each one named. - Only series membership changes; session content, projects and files are untouched. ```json {"tool": "series.sessions.assign", "args": {"sessionIds": ["ses_123", "ses_124"], "seriesId": "ser_dana_1on1"}} ``` ## `series.schedule.set` Creates or replaces a series' one-time or recurring schedule, and creates its upcoming meetings. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduling` **Arguments** **seriesId** (string, required) The series, from `series.list`. **scheduleKind** (string, required) `one_time` or `recurring`. **timezone** (string, required) IANA time zone, for example `Europe/London`. **localDate** (string, required) The first (or only) date, as `YYYY-MM-DD`. **localTime** (string, required) The start time, as `HH:MM`. **durationMinutes** (integer, required) Length in minutes. At least 1. **scheduleId** (string) A series keeps one schedule. Leave this out (an id is made the first time) or pass the existing schedule's id; a different id is refused. **title** (string) A title for the meetings. May be empty. **rrule** (string) The recurrence rule, required for `recurring` and not allowed for `one_time`. Supports `FREQ` `DAILY`, `WEEKLY` or `MONTHLY` with `INTERVAL`, `BYDAY`, `BYMONTHDAY`, `COUNT` and `UNTIL`, for example `FREQ=WEEKLY;BYDAY=TU`. **reminderOffsetsMinutes** (integer[]) Minutes before the start to remind you. Up to 6 values, each from 0 to 10,080; duplicates are removed. Default `[10]`. **startMode** (string) `prompt` (ask before starting) or `automatic` (start after a countdown, in the app). Default `prompt`. **autoStartCountdownSeconds** (integer) Seconds of countdown before an automatic start. From 5 to 300. Default `60`. **effectiveFromOccurrenceId** (string) Change the schedule from this meeting on ("this and following"); earlier meetings keep the old schedule. **horizonEndMs** (integer) Create meetings up to this time, epoch ms. Default: 90 days from now. **Returns:** The schedule, as `series.schedule.get` returns it, including its `scheduleId`. - An archived series is refused with `failed`. ```json {"tool": "series.schedule.set", "args": {"seriesId": "ser_dana_1on1", "scheduleKind": "recurring", "timezone": "America/New_York", "localDate": "2026-11-03", "localTime": "10:00", "durationMinutes": 30, "rrule": "FREQ=WEEKLY;BYDAY=TU"}} ``` ## Related - [Operations reference](/mcp/operations) - [Scheduler](/mcp/operations/scheduler) - [Scheduling and preparing in the app](/sessions/scheduling-and-preparing) - [Series in the app](/sessions/series) --- # Chats and documents MCP and CLI operations to list and read Ask TalkBar chats and documents, read document text, and rename, pin, file, trash and restore them. Canonical URL: https://docs.talkbar.app/mcp/operations/chats-and-documents Chat operations read and organize your Ask TalkBar chats; an assistant cannot send a message in one. Document operations list documents, read their extracted text and rename, pin or file them. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`chats.list`](#chatslist) | Read | `talkbar_read` | On | `content` | | [`chats.get`](#chatsget) | Read | `talkbar_read` | On | `content` | | [`chats.trash.list`](#chatstrashlist) | Read | `talkbar_read` | On | `content` | | [`chats.update`](#chatsupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`chats.trash`](#chatstrash) | Write | `talkbar_delete` | Off | `contentChanges` | | [`chats.restore`](#chatsrestore) | Write | `talkbar_change` | Off | `contentChanges` | | [`documents.list`](#documentslist) | Read | `talkbar_read` | On | `content` | | [`documents.get`](#documentsget) | Read | `talkbar_read` | On | `content` | | [`documents.read`](#documentsread) | Read | `talkbar_read` | On | `content` | | [`documents.update`](#documentsupdate) | Write | `talkbar_change` | Off | `contentChanges` | ## `chats.list` Pages the AI chats (Ask TalkBar) in a workspace: pinned chats first, then by most recent activity. Messages are not returned. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **projectId** (string) Only chats filed under this project. **search** (string) Words to find in the chat title or its messages. Every word must appear; case and accents are ignored. **view** (string) `active` (default), `pinned` or `trash`. **limit** (integer) How many to return. From 1 to 100. Default `40`. **cursor** (string) The `nextCursor` from the previous page. Must not be empty. **Returns:** `{items, nextCursor, totalCount}`. Each item has `chatId`, `title`, `snippet`, `groundingMode`, `projectId`, `pinned`, `createdAt`, `updatedAt`, `lastMessageAtMs`, `trashedAtMs` and `currentTurnStatus`. ```json {"tool": "chats.list", "args": {"search": "pricing"}} ``` ## `chats.get` Reads one chat and its most recent messages: your questions and the answers, with cited sources and skill names. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **chatId** (string, required) The chat, from `chats.list`. **limit** (integer) How many of the most recent messages to return. From 1 to 200. Default `20`. **beforeSequence** (integer) `nextBeforeSequence` from the previous call, to page older messages. **Returns:** The chat (as in `chats.list`, plus `workspaceId` and `replyLanguage`), `messages`, `hasMoreMessages` and `nextBeforeSequence`. Each message has `messageId`, `role`, `content`, `createdAt`, `sources` (`[{n, label, sourceType, sourceId, sessionId, documentId, atMs, locator, snippet, href}]`) and `skill`. - A chat in the Trash can still be read; its `trashedAtMs` is set. ```json {"tool": "chats.get", "args": {"chatId": "chat_12", "limit": 50}} ``` ## `chats.trash.list` Lists the chats in the Trash. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **limit** (integer) How many to return. From 1 to 200. Default `50`. **Returns:** `{chats: [{chatId, title, trashedAt}]}`. ## `chats.update` Renames a chat, pins it, or files it under a project. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **chatId** (string, required) The chat, from `chats.list`. **title** (string) The new title. May be empty, as in the app. **pinned** (boolean) `true` pins, `false` unpins. **projectId** (string | null) The project, or `null` to take the chat out of its project. **Returns:** `{chatId, title, pinned, projectId}`. - Give at least one field. A chat in the Trash is refused: restore it first. ## `chats.trash` Moves a chat to the Trash. It can be restored. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **chatId** (string, required) The chat, from `chats.list`. **Returns:** `{chatId, trashed: true}`. Trashing a chat already in the Trash succeeds. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `chats.restore` Brings a chat back from the Trash. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **chatId** (string, required) The chat, from `chats.list`. **Returns:** `{chatId, title, pinned, projectId}`. Restoring a chat that is not in the Trash returns the same answer. ## `documents.list` Lists the documents in a workspace. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **projectId** (string) Only documents filed under this project. **query** (string) Case-insensitive match on the document title. **sessionId** (string) Only the documents added to this session (as `sessions.documents` lists them). **limit** (integer) How many to return. From 1 to 200. Default `50`. **Returns:** `{documents: [{documentId, title, fileType, status, pinned, projectId, updatedAt}]}`. ```json {"tool": "documents.list", "args": {"projectId": "proj_456"}} ``` ## `documents.get` Reads one document's details and a short preview. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **documentId** (string, required) The document, from `documents.list` or `sessions.documents`. **Returns:** The list row plus `sizeBytes`, `sourceKind`, `indexProgress`, `preview` and `createdAt`. ## `documents.read` Reads a document's extracted text in pages. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **documentId** (string, required) The document, from `documents.list` or `sessions.documents`. **offset** (integer) `nextOffset` from the previous page, in characters. An offset past the end is refused. **maxChars** (integer) Page size in characters. From 1,000 to 200,000. Default `20000`. **Returns:** `{documentId, title, status, totalChars, offset, nextOffset, truncated, text}`. - Fails with a clear message when the document has no extracted text yet, or is no longer available. ```json {"tool": "documents.read", "args": {"documentId": "doc_8", "maxChars": 40000}} ``` ## `documents.update` Renames a document, pins it, or files it under a project. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **documentId** (string, required) The document, from `documents.list` or `sessions.documents`. **title** (string) The new title. Must not be empty. **pinned** (boolean) `true` pins, `false` unpins. **projectId** (string | null) The project, or `null` to take the document out of its project. The project must not be in the Trash. **Returns:** The document's list row. - Give at least one field. Adding, removing and re-indexing documents stay in the app. ## Related - [Operations reference](/mcp/operations) - [Ask TalkBar](/chats-and-notes/ask-talkbar) - [Documents in the app](/knowledge/documents) --- # Exports MCP and CLI operations to configure export destinations and automatic export rules, and to preview, queue, run, cancel, retry and resolve session exports. Canonical URL: https://docs.talkbar.app/mcp/operations/exports Export operations send session content (summary, transcript, notes, action items, markers and audio) to files, an Obsidian vault or Notion. All of them are on by default in MCP Access. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`exports.config`](#exportsconfig) | Read | `talkbar_read` | On | `exports` | | [`exports.sessions`](#exportssessions) | Read | `talkbar_read` | On | `exports` | | [`exports.preview`](#exportspreview) | Read | `talkbar_read` | On | `content` | | [`exports.enqueue`](#exportsenqueue) | Write | `talkbar_change` | On | `exports` | | [`exports.run`](#exportsrun) | Write | `talkbar_change` | On | `exports` | | [`exports.status`](#exportsstatus) | Read | `talkbar_read` | On | `exports` | | [`exports.runs`](#exportsruns) | Read | `talkbar_read` | On | `exports` | | [`exports.history`](#exportshistory) | Read | `talkbar_read` | On | `exports` | | [`exports.cancel`](#exportscancel) | Write | `talkbar_change` | On | `exports` | | [`exports.retry`](#exportsretry) | Write | `talkbar_change` | On | `exports` | | [`exports.resolve`](#exportsresolve) | Write | `talkbar_change` | On | `exports` | | [`exports.destination.save`](#exportsdestinationsave) | Write | `talkbar_change` | On | `exports` | | [`exports.destination.delete`](#exportsdestinationdelete) | Write | `talkbar_delete` | On | `exports` | | [`exports.rule.save`](#exportsrulesave) | Write | `talkbar_change` | On | `exports` | | [`exports.rule.delete`](#exportsruledelete) | Write | `talkbar_delete` | On | `exports` | ## How an export runs 1. Set up a destination with `exports.destination.save` (or in the app). 2. Check what will be written with `exports.preview`. 3. Queue a batch with `exports.enqueue`, then call `exports.run` until no delivery is left `scheduled`. Check progress with `exports.status`. 4. If a delivery needs attention because the destination was changed outside TalkBar, settle it with `exports.resolve`, or try again with `exports.retry`. A delivery is `scheduled`, `waitingForSummary`, `waitingForAudio`, `exporting`, `exported`, `partiallyExported`, `needsAttention` or `cancelled`; a batch takes its status from its deliveries. ## `exports.config` Reads the workspace's export destinations and automatic export rules. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `exports` **Arguments:** none besides `workspaceId`. **Returns:** `{destinations, rules}`. Destinations have `destinationId`, `name`, `format`, `location`, `enabled`, `layout` and `credentialRef`; rules have the fields `exports.rule.save` takes. ```json {"tool": "exports.config", "args": {}} ``` ## `exports.sessions` Pages the ids of the sessions that can be exported (complete and not in the Trash), optionally within a project or series. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `exports` **Arguments** **projectId** (string) Only sessions of this project. **seriesId** (string) Only sessions of this series. **after** (string) The last session id of the previous page. **limit** (integer) How many to return. From 1 to 100. Default `100`. **Returns:** An array of session ids, in id order. Pass the last one as `after` for the next page; an empty array means the end. ## `exports.preview` Shows what an export would contain and whether each session is ready, without exporting anything. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionIds** (string[], required) The sessions to export. 1 to 100. **destinationIds** (string[], required) The destinations to preview. 1 to 10. Each must exist and be enabled. **selection** (object) What to include from each session. Unknown keys are refused. - `summary` (default `true`), `transcript` (default `true`), `metadata` (default `true`), `notes`, `outcomes` (action items), `markers` (each default `false`). - `audio`: `none` (default), `original`, `mp4`, `mp3` or `wav`. - `summarySectionKeys`: only these summary sections. Empty means the whole summary. - `turnIds`: only these transcript turns (up to 10,000). - `ranges`: only transcript turns inside these time ranges, `[{startMs, endMs}]` in ms from the session start (up to 100). **Returns:** `{sessions, destinations, outputs}`. Each session shows the selected content, `ready` and, when it is not ready, `waitReason` (`sessionNotFinished`, `summaryMissing`, `summaryStale` or `audioPending`). Each output names the `location`, `files` and `archiveEntries` it would write. - Returns the selected summary and transcript text, so its policy group is `content`. ```json {"tool": "exports.preview", "args": {"sessionIds": ["ses_123"], "destinationIds": ["dest_vault"], "selection": {"summary": true, "transcript": false, "outcomes": true}}} ``` ## `exports.enqueue` Queues sessions for export to one or more destinations, as a batch. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `exports` **Arguments** **sessionIds** (string[], required) The sessions to export. 1 to 100. **destinationIds** (string[], required) The destinations. 1 to 10. Each must exist and be enabled. **selection** (object) What to include, as for `exports.preview`. **Returns:** The batch: `{batchId, workspaceId, status, automatic, createdAtMs, deliveries}`. Each delivery has `deliveryId`, `sessionId`, `sessionTitle`, `destinationId`, `status`, `location`, `error`, `conflict` and `updatedAtMs`. - A session that is still recording is refused with `session_recording`: queue it after it stops. - Queuing does not deliver anything by itself. Run it with `exports.run`, or cancel it with `exports.cancel`. ```json {"tool": "exports.enqueue", "args": {"sessionIds": ["ses_123", "ses_124"], "destinationIds": ["dest_vault"]}} ``` ## `exports.run` Runs a small part of one batch now: each call delivers at most one session to one destination. It never starts a background worker. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `exports` **Arguments** **batchId** (string, required) The export batch, from `exports.enqueue` or `exports.history`. **Returns:** The batch after the run (`{batchId, workspaceId, status, automatic, createdAtMs, deliveries}`. Each delivery has `deliveryId`, `sessionId`, `sessionTitle`, `destinationId`, `status`, `location`, `error`, `conflict` and `updatedAtMs`). - Call it again while the batch still has scheduled deliveries. - One export run at a time: a second call while one is running is answered `busy` with `retryAfterMs: 5000`. - Writes files or Notion pages to the destination. ```json {"tool": "exports.run", "args": {"batchId": "batch_5"}} ``` ## `exports.status` Reads the delivery status of one export batch. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `exports` **Arguments** **batchId** (string, required) The export batch, from `exports.enqueue` or `exports.history`. **Returns:** The batch: `{batchId, workspaceId, status, automatic, createdAtMs, deliveries}`. Each delivery has `deliveryId`, `sessionId`, `sessionTitle`, `destinationId`, `status`, `location`, `error`, `conflict` and `updatedAtMs`. ## `exports.runs` Lists the delivery attempts of one export batch. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `exports` **Arguments** **batchId** (string, required) The export batch, from `exports.enqueue` or `exports.history`. **Returns:** An array of attempts: `[{runId, deliveryId, status, startedAtMs, finishedAtMs, error}]`. ## `exports.history` Lists recent export batches, newest first. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `exports` **Arguments** **limit** (integer) How many to return. From 1 to 100. Default `30`. **Returns:** An array of batches, as `exports.status` returns them. ## `exports.cancel` Cancels an export batch. Deliveries that finished stay exported. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `exports` **Arguments** **batchId** (string, required) The export batch, from `exports.enqueue` or `exports.history`. **Returns:** The batch as it now stands. - Every delivery that is not `exported` becomes `cancelled`, including partly exported ones and ones that need attention. ## `exports.retry` Retries an export batch: partly exported deliveries and deliveries that need attention (other than conflicts) are queued again. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `exports` **Arguments** **batchId** (string, required) The export batch, from `exports.enqueue` or `exports.history`. **Returns:** The batch as it now stands. - Conflicts are settled with `exports.resolve` instead. A finished batch is unchanged. ## `exports.resolve` Settles an export conflict, where the file or page at the destination was changed outside TalkBar. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `exports` **Arguments** **deliveryId** (string, required) The delivery that needs attention, from the batch. **action** (string, required) `keepExternal` keeps the outside version, `saveCopy` writes TalkBar's version as a new copy, `replace` overwrites the outside version. **Returns:** The batch as it now stands. - Only a delivery that needs attention can be resolved. ```json {"tool": "exports.resolve", "args": {"deliveryId": "dlv_9", "action": "saveCopy"}} ``` ## `exports.destination.save` Creates or updates an export destination: a folder of files, an Obsidian vault, a folder for Notion import, or a connected Notion page. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `exports` **Arguments** **destinationId** (string, required) An id you choose. Saving with an existing id updates that destination. **name** (string, required) The destination name. Must not be empty. **format** (string, required) What to write: - `txt`, `markdown`, `html`, `json`, `srt`, `vtt`, `zip`: files in a folder. - `obsidian`: Markdown with properties, for an Obsidian vault. - `notionMarkdown`: Markdown files for Notion's import. - `notion`: pages created in a connected Notion workspace. **location** (string, required) For `notion`, the parent page (an id or a page URL). For every other format, an absolute folder path. **enabled** (boolean, required) Whether the destination can be used. **layout** (string) How files are arranged in the folder: `flat` (default), `project`, `series` or `projectSeries`. **credentialRef** (string | null) For a connected Notion destination, the stored connection: exactly `export::`, or `null`. Connecting Notion happens in the app; an assistant cannot store a token. **Returns:** The destination as saved. - Saving replaces the whole destination: leaving `credentialRef` out of a connected Notion destination disconnects it. - Administrator rules can limit which folders or destinations may be used. ```json {"tool": "exports.destination.save", "args": {"destinationId": "dest_vault", "name": "Obsidian vault", "format": "obsidian", "location": "PATH_TO_VAULT/Meetings", "enabled": true, "layout": "project"}} ``` ## `exports.destination.delete` Removes a destination that has no active deliveries. Files and pages already exported are kept. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **On** by default · policy group `exports` **Arguments** **destinationId** (string, required) The export destination, from `exports.config`. **Returns:** `{deleted: true, switchedOffRules}`. A rule of its own (`override`) left with no destination is switched to `disabled` and listed in `switchedOffRules`. - Refused with `failed` while a delivery to it is scheduled, waiting or exporting. - Also removes any stored Notion connection for the destination. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `exports.rule.save` Sets automatic export for the workspace, a project or a series. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `exports` **Arguments** **ruleId** (string, required) An id you choose. Saving again with the same id updates the rule. **scopeKind** (string, required) `workspace`, `project` or `series`. **scopeId** (string, required) The workspace, project or series id. For `workspace`, the workspace id itself. **mode** (string, required) `inherit` (use the rule above; not allowed for the workspace), `override` (use this rule) or `disabled` (no automatic export here). **destinationIds** (string[], required) The destinations to export to. **selection** (object, required) What to include, as for `exports.preview`. **timing** (object, required) When to export. One of: - `{"kind": "ready"}`: as soon as a session is ready. - `{"kind": "delay", "delayMs": …}`: a delay after it is ready, up to 31 days (2,678,400,000 ms). - `{"kind": "daily", "hour": …, "minute": …, "timezone": "…"}`: once a day at that time, in an IANA time zone. **reexportSummary** (boolean, required) Export again when the summary changes. **reexportTranscript** (boolean, required) Export again when the transcript changes. **enabledAtMs** (integer, required) Required, but TalkBar sets the time itself: now, or the earlier time when an `override` rule stays `override`. **Returns:** The rule as saved. - One rule per scope: another `ruleId` for a scope that already has a rule is refused with `failed`, naming the existing rule. ```json {"tool": "exports.rule.save", "args": {"ruleId": "rule_proj456", "scopeKind": "project", "scopeId": "proj_456", "mode": "override", "destinationIds": ["dest_vault"], "selection": {"summary": true, "transcript": true}, "timing": {"kind": "ready"}, "reexportSummary": true, "reexportTranscript": false, "enabledAtMs": 0}} ``` ## `exports.rule.delete` Removes an automatic export rule. Queued and delivered exports are kept. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **On** by default · policy group `exports` **Arguments** **ruleId** (string, required) The automatic export rule, from `exports.config`. **Returns:** `{deleted: true}`. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## Related - [Operations reference](/mcp/operations) - [Exports in the app](/sharing/exports) - [Export and share settings](/settings/export-and-share) - [Scheduler](/mcp/operations/scheduler) --- # Knowledge MCP and CLI operations for knowledge cards and the suggestions knowledge scans propose, to list, read, create, update, pin, file, archive and review them. Canonical URL: https://docs.talkbar.app/mcp/operations/knowledge Knowledge operations work with knowledge cards (called memory cards in the app, and `memoryId` in arguments) and with the suggestions knowledge scans propose. To manage the cards of one session, see the `sessions.cards.*` operations on [Sessions](/mcp/operations/sessions). Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`knowledge.list`](#knowledgelist) | Read | `talkbar_read` | On | `content` | | [`knowledge.get`](#knowledgeget) | Read | `talkbar_read` | On | `content` | | [`knowledge.create`](#knowledgecreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.update`](#knowledgeupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.pin`](#knowledgepin) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.assign`](#knowledgeassign) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.approve`](#knowledgeapprove) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.confirm`](#knowledgeconfirm) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.mark_outdated`](#knowledgemark_outdated) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.archive`](#knowledgearchive) | Write | `talkbar_delete` | Off | `contentChanges` | | [`knowledge.restore`](#knowledgerestore) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.suggestions.list`](#knowledgesuggestionslist) | Read | `talkbar_read` | On | `content` | | [`knowledge.suggestions.approve`](#knowledgesuggestionsapprove) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.suggestions.dismiss`](#knowledgesuggestionsdismiss) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.suggestions.snooze`](#knowledgesuggestionssnooze) | Write | `talkbar_change` | Off | `contentChanges` | | [`knowledge.suggestions.reopen`](#knowledgesuggestionsreopen) | Write | `talkbar_change` | Off | `contentChanges` | ## Card statuses A card is `approved`, `outdated` or `archived`. Only approved cards are used when TalkBar draws on your knowledge, and only approved cards stay pinned. | From | Operation | To | | --- | --- | --- | | approved | `knowledge.mark_outdated` | outdated | | approved or outdated | `knowledge.archive` | archived | | outdated or archived | `knowledge.approve` or `knowledge.restore` | approved | Any other change is refused with `failed`. Asking for the status a card already has changes nothing. ## `knowledge.list` Lists knowledge cards. Filter by status, type, project, General, pinned, session or text. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **statuses** (string[]) Only cards with these statuses: `approved`, `outdated`, `archived`. Default: approved cards only. **types** (string[]) Only cards of these types: `fact`, `preference`, `decision`, `commitment`, `risk`, `open_question`, `relationship_context`, `instruction`, `key_moment`, `contract_term`, `pricing_detail`, `technical_detail`. **projectId** (string) Only cards filed under this project. **generalOnly** (boolean) Only cards not filed under a project. **pinnedOnly** (boolean) Only pinned cards. **query** (string) Text to find in the cards. **sessionId** (string) Only the cards brought into this session, in the session's order (as `sessions.live_cards` shows them). **offset** (integer) `nextOffset` from the previous page. At least 0. **limit** (integer) How many to return. From 1 to 200. Default `50`. **Returns:** `{cards: [{memoryId, title, type, status, pinned, projectId, sessionOnly, updatedAt}], total, nextOffset}`. `sessionOnly: true` means the card stays in its session. ```json {"tool": "knowledge.list", "args": {"projectId": "proj_456", "types": ["decision", "commitment"]}} ``` ## `knowledge.get` Reads one knowledge card with its text, metadata and sources, quotes included. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`, plus `sources: [{sourceType, sourceId, atMs, quote, locator, status}]`. ```json {"tool": "knowledge.get", "args": {"memoryId": "mem_321"}} ``` ## `knowledge.create` Adds a knowledge card. Cards you add are approved right away. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **title** (string, required) The card title. Must not be empty. **body** (string) The card text. **type** (string) One of `fact`, `preference`, `decision`, `commitment`, `risk`, `open_question`, `relationship_context`, `instruction`, `key_moment`, `contract_term`, `pricing_detail`, `technical_detail`. Default `fact`. **projectId** (string) File the card under this project. Without it, the card goes to General. **pinned** (boolean) Pin the card. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`. ```json {"tool": "knowledge.create", "args": {"title": "Prefers email over calls", "type": "preference", "projectId": "proj_456"}} ``` ## `knowledge.update` Changes a knowledge card's title, body or type. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **title** (string) The new title. Must not be empty. **body** (string) The new text. **type** (string) One of `fact`, `preference`, `decision`, `commitment`, `risk`, `open_question`, `relationship_context`, `instruction`, `key_moment`, `contract_term`, `pricing_detail`, `technical_detail`. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`. - Give at least one field. ## `knowledge.pin` Pins or unpins a knowledge card. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **pinned** (boolean, required) `true` pins, `false` unpins. The pin belongs to the card: it shows pinned in every session and list that holds it. **Returns:** `{memoryId, pinned}`. - A card that leaves the approved status (outdated or archived) is unpinned, and approving or restoring it later does not pin it again. ## `knowledge.assign` Files knowledge cards under a project, or takes them out of their project. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryIds** (string[], required) The cards to file. Must not be empty. **projectId** (string | null, required) The project, or `null` to take the cards out of their project. Required. **Returns:** `{memoryIds, projectId, changed}`. ```json {"tool": "knowledge.assign", "args": {"memoryIds": ["mem_321", "mem_322"], "projectId": "proj_456"}} ``` ## `knowledge.approve` Sets a knowledge card back to approved. Approving a card that is already approved changes nothing. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`. - Cards have no "waiting for review" status: what knowledge scans propose are suggestions. Approve those with `knowledge.suggestions.approve`. ## `knowledge.confirm` Confirms a knowledge card is still true. It records the time in `lastConfirmedAtMs` and leaves the status unchanged. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`. ## `knowledge.mark_outdated` Marks a knowledge card as no longer true. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`. - An outdated card is unpinned. Approve or restore it to bring it back. ## `knowledge.archive` Archives a knowledge card. It can be restored. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`. - Archiving unpins the card. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `knowledge.restore` Brings an archived (or outdated) knowledge card back as approved. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **memoryId** (string, required) The knowledge card, from `knowledge.list`. **Returns:** The card: `{memoryId, title, body, type, status, pinned, priority, confidence, projectId, contactId, organizationId, sessionId, sessionOnly, createdBy, lastConfirmedAtMs, createdAt, updatedAt}`. ## `knowledge.suggestions.list` Lists the cards, people and companies that knowledge scans propose, with the quotes they come from. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **status** (string) One of `pending`, `approving`, `approved`, `dismissed`. Default `pending`. **kind** (string) Only suggestions for a `memory` (knowledge card), `contact` (person) or `organization` (company). **projectId** (string) Only suggestions for this project. **query** (string) Text to find in the suggestions. **limit** (integer) How many to return. From 1 to 100. Default `50`. **cursor** (string) `nextCursor` from the previous page. **Returns:** `{suggestions, hasMore, nextCursor}`. Each suggestion has `suggestionId`, `kind`, `action`, `status`, `proposal`, `evidence`, `targetId`, `confidence`, `projectId`, `sessionId`, `documentId`, `snoozedUntilMs`, `appliedCardId` and `createdAt`. ```json {"tool": "knowledge.suggestions.list", "args": {"kind": "memory", "limit": 20}} ``` ## `knowledge.suggestions.approve` Accepts a suggestion. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **suggestionId** (string, required) The suggestion, from `knowledge.suggestions.list`. **approveWithoutSource** (boolean) When the session or document the suggestion came from is no longer available, approve it anyway, no longer linked to its source. Without it, such a suggestion is refused. **Returns:** The suggestion as it now stands. ```json {"tool": "knowledge.suggestions.approve", "args": {"suggestionId": "sug_55"}} ``` ## `knowledge.suggestions.dismiss` Rejects a suggestion. Undo with `knowledge.suggestions.reopen`. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **suggestionId** (string, required) The suggestion, from `knowledge.suggestions.list`. **Returns:** The suggestion as it now stands. ## `knowledge.suggestions.snooze` Hides a suggestion until a later time. Undo with `knowledge.suggestions.reopen`. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **suggestionId** (string, required) The suggestion, from `knowledge.suggestions.list`. **untilMs** (integer, required) When to show it again, in epoch ms. Must be in the future. **Returns:** The suggestion as it now stands. ## `knowledge.suggestions.reopen` Puts a dismissed or snoozed suggestion back for review. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **suggestionId** (string, required) The suggestion, from `knowledge.suggestions.list`. **Returns:** The suggestion as it now stands. ## Related - [Operations reference](/mcp/operations) - [Sessions](/mcp/operations/sessions) (session cards) - [Knowledge cards in the app](/knowledge/knowledge-cards) - [Review and scans](/knowledge/review-and-scans) --- # People and companies MCP and CLI operations to list, read, create, update and archive people and companies, and to find the sessions a person spoke in. Canonical URL: https://docs.talkbar.app/mcp/operations/people-and-companies People operations (`contacts.*`) and company operations (`organizations.*`) work with the people and companies TalkBar knows. In `talkbar_find`, these are the `person` and `company` kinds. To name or link a speaker in a session, see the `sessions.speakers.*` operations on [Sessions](/mcp/operations/sessions). Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`contacts.list`](#contactslist) | Read | `talkbar_read` | On | `content` | | [`contacts.get`](#contactsget) | Read | `talkbar_read` | On | `content` | | [`contacts.sessions`](#contactssessions) | Read | `talkbar_read` | On | `content` | | [`contacts.create`](#contactscreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`contacts.update`](#contactsupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`contacts.archive`](#contactsarchive) | Write | `talkbar_delete` | Off | `contentChanges` | | [`contacts.unarchive`](#contactsunarchive) | Write | `talkbar_change` | Off | `contentChanges` | | [`organizations.list`](#organizationslist) | Read | `talkbar_read` | On | `content` | | [`organizations.get`](#organizationsget) | Read | `talkbar_read` | On | `content` | | [`organizations.create`](#organizationscreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`organizations.update`](#organizationsupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`organizations.archive`](#organizationsarchive) | Write | `talkbar_delete` | Off | `contentChanges` | | [`organizations.unarchive`](#organizationsunarchive) | Write | `talkbar_change` | Off | `contentChanges` | ## `contacts.list` Lists the people in a workspace, with how many sessions each spoke in and when the latest started. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **projectId** (string) Only people of this project. **query** (string) Text to find in names and emails. **includeArchived** (boolean) Also list archived people. Default `false`. **limit** (integer) How many to return. From 1 to 500. Default `100`. **Returns:** `{contacts: [{contactId, name, email, role, organizationId, archived, sessionCount, lastMetAtMs}]}`. - `sessionCount` and `lastMetAtMs` count the sessions `contacts.sessions` lists (the person spoke; sessions in the Trash left out). A person never heard has `0` and `null`. ```json {"tool": "contacts.list", "args": {"query": "dana"}} ``` ## `contacts.get` Reads one person's details. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **contactId** (string, required) The person, from `contacts.list`. **Returns:** `{contactId, name, email, phone, role, organizationId, relationshipTag, sentiment, notes, confirmed, lastContactAtMs, archived, createdAt, updatedAt}`. ## `contacts.sessions` Lists the sessions a person spoke in, newest first, with the name they had in each, their talk time and their share of all talk. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **contactId** (string, required) The person, from `contacts.list`. **limit** (integer) How many to return. From 1 to 200. Default `100`. **offset** (integer) `nextOffset` from the previous page. **Returns:** `{contactId, sessions: [{sessionId, title, startedAtMs, endedAtMs, speaker, talkTimeMs, share, excludedFromAi, private}], hasMore, nextOffset}`. `share` is 0 to 1 of everyone's talk time. - Pass `speaker` as the `speaker` filter of `sessions.transcript` to read what the person said. ```json {"tool": "contacts.sessions", "args": {"contactId": "ct_77", "limit": 10}} ``` ## `contacts.create` Adds a person. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **name** (string, required) The person's name. Must not be empty. **email** (string) Email address. It must have text before and after a single `@` and no spaces; the domain is not checked. **phone** (string) Phone number. **role** (string) Role or job title. **relationshipTag** (string) A short tag for how you know them. **notes** (string) Plain-text notes. **Returns:** The person, as `contacts.get` returns it. ```json {"tool": "contacts.create", "args": {"name": "Dana Lee", "email": "dana@example.com", "role": "CFO"}} ``` ## `contacts.update` Changes a person's name, email, phone, role, relationship tag or notes. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **contactId** (string, required) The person, from `contacts.list`. **name** (string) The new name. Must not be empty. **email** (string | null) Email address, with the same check as `contacts.create`. `null` or an empty string clears it. **phone** (string | null) Phone number. `null` clears it. **role** (string | null) Role or job title. `null` clears it. **relationshipTag** (string | null) A short tag for how you know them. `null` clears it. **notes** (string | null) Plain-text notes; they replace any formatted notes. `null` clears them. **Returns:** The person, as `contacts.get` returns it. - Give at least one field. ## `contacts.archive` Archives a person. Their history stays, and they stay editable. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **contactId** (string, required) The person, from `contacts.list`. **Returns:** The person's list row (`contactId`, `name`, `email`, `role`, `organizationId`, `archived`). - Undo with `contacts.unarchive`. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `contacts.unarchive` Brings an archived person back. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **contactId** (string, required) The person, from `contacts.list`. **Returns:** The person's list row, as `contacts.archive` returns it. ## `organizations.list` Lists the companies in a workspace. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **projectId** (string) Only companies of this project. **query** (string) Text to find in names and websites. **includeArchived** (boolean) Also list archived companies. Default `false`. **limit** (integer) How many to return. From 1 to 500. Default `100`. **Returns:** `{organizations: [{organizationId, name, relationship, website, pinned, archived}]}`. ## `organizations.get` Reads one company's details, archived companies included. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **organizationId** (string, required) The company, from `organizations.list`. **Returns:** The list row plus `notes`, `createdAt` and `updatedAt`. ## `organizations.create` Adds a company. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **name** (string, required) The company name. Must not be empty. **relationship** (string) One of `client`, `vendor`, `partner`, `prospect`, `internal`, `investor`, `advisor`, `candidate_company`, `other`. Default `other`. **website** (string) Free text, as in the app (`northwind.example` is fine). Blank means none. `javascript:`, `vbscript:` and `data:` links are refused. **notes** (string) Plain-text notes. **Returns:** The company, as `organizations.get` returns it. ```json {"tool": "organizations.create", "args": {"name": "Northwind", "relationship": "client", "website": "northwind.example"}} ``` ## `organizations.update` Changes a company's name, relationship, website or notes. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **organizationId** (string, required) The company, from `organizations.list`. **name** (string) The new name. Must not be empty. **relationship** (string) One of `client`, `vendor`, `partner`, `prospect`, `internal`, `investor`, `advisor`, `candidate_company`, `other`. **website** (string | null) Same rules as `organizations.create`. `null` clears it. **notes** (string | null) Plain-text notes. `null` clears them. **Returns:** The company, as `organizations.get` returns it. - Give at least one field. ## `organizations.archive` Archives a company. Its history stays. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **organizationId** (string, required) The company, from `organizations.list`. **Returns:** The company's list row. - Undo with `organizations.unarchive`. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `organizations.unarchive` Brings an archived company back. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **organizationId** (string, required) The company, from `organizations.list`. **Returns:** The company's list row. ## Related - [Operations reference](/mcp/operations) - [Sessions](/mcp/operations/sessions) - [People and companies in the app](/knowledge/people-and-companies) --- # Projects and notes MCP and CLI operations to list, read, create, update, file, pin, trash and restore projects and notes. Canonical URL: https://docs.talkbar.app/mcp/operations/projects-and-notes Project operations read and manage the projects that group your sessions, notes and cards. Note operations read and write notes as Markdown, including a session's own note. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`projects.list`](#projectslist) | Read | `talkbar_read` | On | `metadata` | | [`projects.get`](#projectsget) | Read | `talkbar_read` | On | `content` | | [`projects.trash.list`](#projectstrashlist) | Read | `talkbar_read` | On | `content` | | [`projects.create`](#projectscreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`projects.update`](#projectsupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`projects.pin`](#projectspin) | Write | `talkbar_change` | Off | `contentChanges` | | [`projects.trash`](#projectstrash) | Write | `talkbar_delete` | Off | `contentChanges` | | [`projects.restore`](#projectsrestore) | Write | `talkbar_change` | Off | `contentChanges` | | [`notes.list`](#noteslist) | Read | `talkbar_read` | On | `content` | | [`notes.get`](#notesget) | Read | `talkbar_read` | On | `content` | | [`notes.trash.list`](#notestrashlist) | Read | `talkbar_read` | On | `content` | | [`notes.create`](#notescreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`notes.update`](#notesupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`notes.append`](#notesappend) | Write | `talkbar_change` | Off | `contentChanges` | | [`notes.move`](#notesmove) | Write | `talkbar_change` | Off | `contentChanges` | | [`notes.pin`](#notespin) | Write | `talkbar_change` | Off | `contentChanges` | | [`notes.trash`](#notestrash) | Write | `talkbar_delete` | Off | `contentChanges` | | [`notes.restore`](#notesrestore) | Write | `talkbar_change` | Off | `contentChanges` | ## `projects.list` Pages the projects in a workspace with session, note and document counts and the latest session start time. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **limit** (integer) How many to return. From 1 to 100. Default `100`. **offset** (integer) `nextOffset` from the previous page. Default `0`. **Returns:** `{items: [{projectId, name, description, sessionCount, noteCount, documentCount, lastSessionAtMs}], totalCount, nextOffset}`. ```json {"tool": "projects.list", "args": {}} ``` ## `projects.get` Reads one project overview with its latest sessions (up to 20) and notes (up to 10). **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **projectId** (string, required) A project, from `projects.list`. **Returns:** The `projects.list` fields plus `sessions` (rows as in `sessions.list`) and `notes` (`{noteId, title, snippet, updatedAt}`). - A project in the Trash is `not_found`. ```json {"tool": "projects.get", "args": {"projectId": "proj_456"}} ``` ## `projects.trash.list` Lists the projects in the Trash. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **limit** (integer) How many to return. From 1 to 200. Default `50`. **Returns:** `{projects: [{projectId, name, trashedAt}]}`. ## `projects.create` Creates a project, within your plan's project limit. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **name** (string, required) The project name. Must not be empty. **description** (string) A plain-text description. **kind** (string) The kind of project. One of `client`, `engagement`, `recurring`, `internal`, `personal`, `research`, `product`, `sales`, `hiring`, `education`, `event`, `support`. Default `client`. **color** (string) The project color. **Returns:** The project: `{projectId, name, status, kind, pinned, updatedAt}`. - At your plan's project limit the call is refused with `plan_limit` (`limit: "projects"`), counted in the workspace the call acts on. `plan.get` shows the limit. ```json {"tool": "projects.create", "args": {"name": "Northwind onboarding", "kind": "client"}} ``` ## `projects.update` Renames a project or changes its description, kind or color. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **projectId** (string, required) A project, from `projects.list`. **name** (string) The new name. Must not be empty. **description** (string | null) A plain-text description; it replaces any formatted description. `null` clears it. **kind** (string) One of `client`, `engagement`, `recurring`, `internal`, `personal`, `research`, `product`, `sales`, `hiring`, `education`, `event`, `support`. **color** (string | null) The project color. `null` clears it. **Returns:** The project, as `projects.create` returns it. - Give at least one field. ## `projects.pin` Pins or unpins a project. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **projectId** (string, required) A project, from `projects.list`. **pinned** (boolean, required) `true` pins, `false` unpins. **Returns:** `{projectId, pinned}`. ## `projects.trash` Moves a project to the Trash. It can be restored. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **projectId** (string, required) A project, from `projects.list`. **Returns:** `{projectId, trashed: true}`. Trashing a project already in the Trash succeeds and keeps the first trash date. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `projects.restore` Brings a project back from the Trash, within your plan's project limit. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **projectId** (string, required) A project, from `projects.list`. **Returns:** The project, as `projects.create` returns it. Restoring a project that is not in the Trash changes nothing. - At the project limit it is refused with `plan_limit` (`limit: "projects"`). ## `notes.list` Pages the notes in a workspace, most recently updated first, optionally limited to a project, topic, session or a title and body search. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **projectId** (string) Only notes filed under this project. **search** (string) Text to find in note titles and bodies. **topicId** (string) Only notes assigned this topic (from `topics.list`). **sessionId** (string) Only the notes on this session: its own note, the notes added to its page and the notes filed under it. **limit** (integer) How many to return. From 1 to 100. Default `40`. **cursor** (string) The `nextCursor` from the previous page. Must not be empty. **Returns:** `{items, nextCursor, hasMore, totalCount}`. Each item has `noteId`, `title`, `snippet`, `pinned`, `createdAt`, `updatedAt`, `sessionId`, `sessions`, `topics` and `projects`; a search adds `matchSnippet`. - In each row, `sessionId` is set only on a session's own note; `sessions` lists the sessions a note is filed under. ```json {"tool": "notes.list", "args": {"search": "onboarding", "limit": 10}} ``` ## `notes.get` Reads one note: its title, Markdown body (in pages) and links. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **noteId** (string, required) The note, from `notes.list` or `sessions.notes`. **maxChars** (integer) Page size in characters. From 1,000 to 200,000. Default `20000`. **offset** (integer) `nextOffset` from the previous read. An offset past the end is refused. **Returns:** `{noteId, workspaceId, title, markdown, truncated, nextOffset, pinned, createdAt, updatedAt, links}`. `updatedAt` is what `notes.update` takes as `expectedUpdatedAt`. - A note in the Trash is `not_found`. ```json {"tool": "notes.get", "args": {"noteId": "note_789"}} ``` ## `notes.trash.list` Lists the notes in the Trash. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **limit** (integer) How many to return. From 1 to 200. Default `50`. **Returns:** `{notes: [{noteId, title, trashedAt}]}`. ## `notes.create` Creates a note from Markdown, optionally filed under a project and sessions. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **title** (string) The note title. May be empty, as in the app. **markdown** (string) The note body, in Markdown. (The argument is `markdown`; `body`, `content` or `text` are refused.) **projectId** (string) File the note under this project. **sessionIds** (string[]) File the note under these sessions. A session named twice is filed once. **pinned** (boolean) Pin the note. **Returns:** `{noteId, title, pinned, sessionId, updatedAt, projectId, sessionIds}`. `projectId` and `sessionIds` say where the note is filed. - The project and sessions must exist and not be in the Trash. ```json {"tool": "notes.create", "args": {"title": "Follow-up plan", "markdown": "## Next steps\n- Send the proposal by Friday", "projectId": "proj_456"}} ``` ## `notes.update` Renames a note and/or replaces its body with Markdown. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **noteId** (string, required) The note, from `notes.list` or `sessions.notes`. **title** (string) The new title. An empty title clears it. **markdown** (string) The new body, in Markdown. Replaces the whole body. **force** (boolean) Replace a body that holds content Markdown cannot represent, such as embedded cards. Without it, such a note is refused. **expectedUpdatedAt** (integer) The note's `updatedAt` your edit started from. If the note changed since, in TalkBar or through another call, the edit is refused with `conflict` and nothing is written. **Returns:** `{noteId, title, pinned, sessionId, updatedAt}`; on a session's own note, also `sessionStatus` (and a `warning` when the session was interrupted or TalkBar is not running). - Give a title, markdown or both. A title-only edit keeps the body and its embedded links. - A `conflict` answer carries the note's current `updatedAt`: read the note again, merge, and retry. - A note in the Trash is refused: restore it first. ```json {"tool": "notes.update", "args": {"noteId": "note_789", "markdown": "# Plan\nUpdated after the call.", "expectedUpdatedAt": 1761990000000}} ``` ## `notes.append` Adds Markdown to the end of a note. No conflict check is needed, since it adds to what is there. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **noteId** (string, required) The note, from `notes.list` or `sessions.notes`. **markdown** (string, required) The Markdown to add. Must not be empty. **Returns:** As `notes.update`, including `sessionStatus` on a session's own note. - To write into a live session's note, find its `noteId` with `sessions.notes` (`role: "session"`). ```json {"tool": "notes.append", "args": {"noteId": "note_789", "markdown": "- Dana will send the contract draft."}} ``` ## `notes.move` Sets a note's project and/or the sessions it is filed under. Other links stay. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **noteId** (string, required) The note, from `notes.list` or `sessions.notes`. **projectId** (string | null) The project, or `null` to take the note out of its project. **sessionIds** (string[]) The sessions to file it under. Replaces the note's current session list. **Returns:** `{noteId, projectId, sessionIds}`: where the note is filed now. - Give `projectId`, `sessionIds` or both. ## `notes.pin` Pins or unpins a note. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **noteId** (string, required) The note, from `notes.list` or `sessions.notes`. **pinned** (boolean, required) `true` pins, `false` unpins. **Returns:** `{noteId, pinned}`. ## `notes.trash` Moves a note to the Trash. It can be restored. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **noteId** (string, required) The note, from `notes.list` or `sessions.notes`. **Returns:** `{noteId, trashed: true}`. Trashing a note already in the Trash succeeds. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `notes.restore` Brings a note back from the Trash. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **noteId** (string, required) The note, from `notes.list` or `sessions.notes`. **Returns:** `{noteId, restored: true}`. Restoring a note that is not in the Trash returns the same answer. ## Related - [Operations reference](/mcp/operations) - [Sessions](/mcp/operations/sessions) - [Topics and markers](/mcp/operations/topics-and-markers) - [Projects in the app](/knowledge/projects) - [Notes in the app](/chats-and-notes/notes) --- # Scheduler MCP and CLI operations to inspect TalkBar's scheduled jobs and to cancel or retry one. Canonical URL: https://docs.talkbar.app/mcp/operations/scheduler TalkBar runs timed work, such as meeting reminders, automatic starts and exports, as scheduled jobs. These operations let an assistant see that queue for a workspace, and cancel or retry a single job. They are all on by default in MCP Access. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`scheduler.status`](#schedulerstatus) | Read | `talkbar_read` | On | `scheduler` | | [`scheduler.jobs.list`](#schedulerjobslist) | Read | `talkbar_read` | On | `scheduler` | | [`scheduler.job.get`](#schedulerjobget) | Read | `talkbar_read` | On | `scheduler` | | [`scheduler.job.cancel`](#schedulerjobcancel) | Write | `talkbar_change` | On | `scheduler` | | [`scheduler.job.retry`](#schedulerjobretry) | Write | `talkbar_change` | On | `scheduler` | ## Job statuses A job is `pending`, `leased`, `running`, `succeeded`, `skipped`, `failed` or `cancelled`. ## `scheduler.status` Reads how many scheduled jobs a workspace has in each state, and when the next one is due. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `scheduler` **Arguments:** none besides `workspaceId`. **Returns:** `{pending, leased, running, succeeded, skipped, failed, cancelled, nextDueAtMs}`. ```json {"tool": "scheduler.status", "args": {}} ``` ## `scheduler.jobs.list` Lists a workspace's recent scheduled jobs, newest first. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `scheduler` **Arguments** **limit** (integer) How many to return. From 1 to 500. Default `100`. **Returns:** An array of jobs. The job: `jobId`, `jobKind`, `scopeType`, `scopeId`, `targetType`, `targetId`, `queueName`, `priority`, `runAtMs`, `status`, `attemptCount`, `maxAttempts`, `lastError`, `createdAtMs`, `updatedAtMs`, `startedAtMs`, `completedAtMs`, `cancelledAtMs` and a few routing fields. ## `scheduler.job.get` Reads one scheduled job and its run history. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `scheduler` **Arguments** **jobId** (string, required) The scheduled job, from `scheduler.jobs.list`. **runLimit** (integer) Most runs to return. From 1 to 500. Default `50`. **Returns:** `{job, runs}`. Each run has `runId`, `jobId`, `attemptNumber`, `status`, `startedAtMs`, `finishedAtMs`, `error` and `outputJson`. ```json {"tool": "scheduler.job.get", "args": {"jobId": "job_31"}} ``` ## `scheduler.job.cancel` Cancels one pending, leased or running job. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduler` **Arguments** **jobId** (string, required) The scheduled job, from `scheduler.jobs.list`. **Returns:** The job as it now stands. - A job that already finished is refused with `failed`. Cancelling a job does not delete the meeting, reminder or export that created it. ## `scheduler.job.retry` Puts one failed job back in the queue. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **On** by default · policy group `scheduler` **Arguments** **jobId** (string, required) The scheduled job, from `scheduler.jobs.list`. **runAtMs** (integer) When to run it, epoch ms. Default: now. A past time means now. **Returns:** The job as it now stands, `pending`, with its last error cleared. - Only a failed job can be retried; anything else is refused with `failed`. ## Related - [Operations reference](/mcp/operations) - [Calendar and series](/mcp/operations/calendar-and-series) - [Exports](/mcp/operations/exports) --- # Sessions MCP and CLI operations to list, read, file, pin, trash and restore sessions, read transcripts and timelines, name speakers and manage session cards. Canonical URL: https://docs.talkbar.app/mcp/operations/sessions Session operations read what the session page shows (summary, transcript, timeline, figures, notes, documents and cards) and make the changes you can make there: rename, file under a project, pin, name speakers, add cards, trash and restore. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`sessions.list`](#sessionslist) | Read | `talkbar_read` | On | `metadata` | | [`sessions.get`](#sessionsget) | Read | `talkbar_read` | On | `content` | | [`sessions.recording`](#sessionsrecording) | Read | `talkbar_read` | On | `metadata` | | [`sessions.stats`](#sessionsstats) | Read | `talkbar_read` | On | `metadata` | | [`sessions.transcript`](#sessionstranscript) | Read | `talkbar_read` | On | `content` | | [`sessions.timeline`](#sessionstimeline) | Read | `talkbar_read` | On | `content` | | [`sessions.notes`](#sessionsnotes) | Read | `talkbar_read` | On | `content` | | [`sessions.documents`](#sessionsdocuments) | Read | `talkbar_read` | On | `content` | | [`sessions.live_cards`](#sessionslive_cards) | Read | `talkbar_read` | On | `content` | | [`sessions.trash.list`](#sessionstrashlist) | Read | `talkbar_read` | On | `content` | | [`sessions.rename`](#sessionsrename) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.move`](#sessionsmove) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.pin`](#sessionspin) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.speakers.rename`](#sessionsspeakersrename) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.speakers.link`](#sessionsspeakerslink) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.speakers.unlink`](#sessionsspeakersunlink) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.cards.add`](#sessionscardsadd) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.cards.attach`](#sessionscardsattach) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.cards.detach`](#sessionscardsdetach) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.trash`](#sessionstrash) | Write | `talkbar_delete` | Off | `contentChanges` | | [`sessions.restore`](#sessionsrestore) | Write | `talkbar_change` | Off | `contentChanges` | ## Working with the live session An assistant can work with the session you are recording, and what it adds shows on the recording screen right away: 1. Call `sessions.recording` to find it, and check `stale`. 2. Read with `sessions.transcript` using `cursor: "0:"` and `format: "json"`, then keep passing the returned `nextCursor`. `sessions.timeline` gives the points written so far, and `sessions.stats` gives provisional speakers. 3. Add markers (`markers.create`), action items (`action_items.create`) and knowledge cards (`sessions.cards.add`, `sessions.cards.attach`), or append to the session's note (`notes.append`). While recording, the transcript, timeline points and speakers are read-only for assistants (speaker edits answer `session_recording`). Recording itself is controlled only in the app, and the summary and AI keywords come after recording stops. ## `sessions.list` Pages session metadata in a workspace, newest start first, with filters for project, series, status, start time, topic and title. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **projectId** (string) Only sessions filed under this project. **seriesId** (string) Only sessions in this series (from `series.list`). **status** (string) Only sessions in this state. `recording` answers whether a session is recording now. One of `recording`, `open`, `interrupted`, `complete`. **startedAfterMs** (integer) Only sessions that started at or after this time (epoch ms, inclusive). **startedBeforeMs** (integer) Only sessions that started before this time (epoch ms, exclusive). **search** (string) Case-insensitive match on part of the session title. **topicId** (string) Only sessions assigned this topic (from `topics.list`). **limit** (integer) How many to return. From 1 to 100. Default `40`. **cursor** (string) The `nextCursor` from the previous page. Must not be empty. **Returns:** `{items, nextCursor, hasMore, totalCount}`. Each item has `sessionId`, `title`, `status`, `startedAtMs`, `endedAtMs`, `projectId`, `seriesId`, `participantCount`, `pinned`, `source` and `private`. - Lists sessions that are not in the Trash; use `sessions.trash.list` for those. - Pass `nextCursor` back as `cursor` for the next page. ```json {"tool": "sessions.list", "args": {"projectId": "proj_123", "status": "complete", "limit": 20}} ``` ## `sessions.get` Reads one session: its metadata, final summary text and sections, action items and decisions. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** The `sessions.list` fields plus `speakerCount`, `workspaceId`, `sessionType`, `createdAt`, `updatedAt`, `revision`, `summary` (`{text, sections, generatedBy}`, where `generatedBy` names the model and provider and says whether the summary was edited), `actionItems` and `decisions`. - `participantCount` counts everyone on the session, including people who never spoke; `speakerCount` counts those who talked. - `revision` changes whenever anything on the session page changes, so an assistant can poll it cheaply and re-read only when it moves. - While the session records: `recording: true`, `summaryPending: true` and `summary: null`. The summary is written after recording stops. - Use `sessions.transcript` for the transcript. A session in the Trash is `not_found`. ```json {"tool": "sessions.get", "args": {"sessionId": "ses_123"}} ``` ## `sessions.recording` Returns the session recording right now, or `null` when nothing is recording. Call it first when working with a live session, then use its `sessionId`. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments:** none besides `workspaceId`. **Returns:** `{recording: null}` or `{recording: {sessionId, title, startedAtMs, elapsedMs, revision, appRunning, stale}}`. - `elapsedMs` is wall-clock time since the start, pauses included (only the app knows about pauses). - `appRunning` says whether TalkBar is running for this data folder (`null` when it cannot tell). `stale: true` means TalkBar is not running, so the session only looks like it is recording until TalkBar next starts and marks it interrupted. - Never guess "the newest session" for the live one: use this operation. ```json {"tool": "sessions.recording", "args": {}} ``` ## `sessions.stats` Reads a session's figures: how long it recorded, its breaks, turns, characters, each speaker's talk time, and which model wrote its summary for every saved length. No transcript or summary text. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** `sessionId`, `status`, `sessionType`, `private`, `startedAtMs`, `endedAtMs`, `elapsedMs`, `recordedMs`, `recordingRuns`, `breaks`, `turns`, `transcriptChars`, `speakerCount`, `talkTimeMs`, `speakers` and `summary`. Each speaker has `speakerId`, `contactId` (the linked person, else `null`), `name`, `isUser`, `excludedFromAi`, `talkTimeMs` and `share`. `summary` describes the selected length and model, and lists every saved length. - `speakerId` is what the `sessions.speakers.*` writes take. - While the session records, speakers come from the live transcript: `speakerId: null`, plus `turns` and `provisional: true`. ```json {"tool": "sessions.stats", "args": {"sessionId": "ses_123"}} ``` ## `sessions.transcript` Reads a session's transcript as the session page shows it, with speaker names and times, in pages of whole turns. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **speaker** (string) Only turns whose speaker name contains this text (case-insensitive). Use the `speaker` value `contacts.sessions` returns to read one person's turns. **turnOffset** (integer) The turn to start at: `nextTurnOffset` from the previous page. Cannot be combined with `cursor`. **maxChars** (integer) Page size in characters. From 1,000 to 200,000. Default `20000`. **format** (string) `text` (default) returns `[mm:ss] Name: text` lines; `json` returns turn objects with ids. **cursor** (string) Follow a transcript as it changes. Start with `"0:"`, then pass each answer's `nextCursor` to get only the turns added or changed since. **Returns:** `sessionId`, `title`, `startedAtMs`, `private`, `truncated`, `excludedFromAiSpeakers`, then `transcript` (text) or `turns` (json). Paged reads add `totalTurns`, `turnOffset` and `nextTurnOffset`; cursor reads add `nextCursor` instead. Json turns carry `turnId`, `chunkId`, `startMs`, `endMs`, `speaker`, `isUser`, `excludedFromAi`, `text` and `translatedText`. - Pages hold whole turns. A `turnOffset` past the end is refused. - `turnId` and `chunkId` are what `markers.create` and `action_items.create` take to point at a moment. - While the session records, turns can be `provisional: true` and the answer carries `recording: true`. - Speakers excluded from AI are marked, not hidden. Removed turns are not reported by a cursor read; when `revision` changes, read again in full. ```json {"tool": "sessions.transcript", "args": {"sessionId": "ses_123", "format": "json", "maxChars": 50000}} ``` ## `sessions.timeline` Reads a session's timeline with times, as the session page shows it. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** `{sessionId, title, private, points: [{pointId, at, atMs, text, translatedText, edited}]}`. `at` is `mm:ss` (`h:mm:ss` past an hour, `--:--` when a point has no time). - `pointId` is what `markers.create` and `action_items.create` take to point at a timeline entry. ```json {"tool": "sessions.timeline", "args": {"sessionId": "ses_123"}} ``` ## `sessions.notes` Lists the session's own note and the notes added to it. Read one in full with `notes.get`. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** `{sessionId, private, notes: [{noteId, title, role, preview, updatedAt}]}`. `role` is `session` for the session's own note and `added` for notes added to it; `preview` is the first 160 characters. ```json {"tool": "sessions.notes", "args": {"sessionId": "ses_123"}} ``` ## `sessions.documents` Lists the documents added to a session. Read one with `documents.read`. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** `{sessionId, private, documents: [{documentId, title, fileType, status, pinned, projectId, updatedAt}]}`. ## `sessions.live_cards` Lists the knowledge cards and earlier action items brought into a session, and the moments the conversation came back to each. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** `{sessionId, private, cards, broughtInActionItems, capturedActionItems}`. Cards have `memoryId`, `title`, `body`, `type`, `status` and `cameUp`. `cameUp` is `null` or `{count, first, last, moments: [{at, atMs, heard, matchedTerms}]}`, where `heard` is the words heard at that moment. Action items use the `action_items.get` shape; brought-in items also carry `statusWhenBroughtIn` and `cameUp`. ## `sessions.trash.list` Lists the sessions in the Trash. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **limit** (integer) How many to return. From 1 to 200. Default `50`. **Returns:** `{sessions: [{sessionId, title, trashedAt}]}`. ## `sessions.rename` Changes a session's title. Works while the session records. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **title** (string, required) The new title. Must not be empty; surrounding spaces are trimmed. **Returns:** `{sessionId, title}` plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). ```json {"tool": "sessions.rename", "args": {"sessionId": "ses_123", "title": "Q4 roadmap review"}} ``` ## `sessions.move` Files a session under a project, or takes it out of its project. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **projectId** (string | null, required) The project to file it under, or `null` to take it out of its project. Required: send `null` explicitly to remove. **moveKnowledge** (boolean) Move the session's knowledge cards along with it. Default `true`. **Returns:** `{sessionId, projectId, previousProjectId}` plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). - The target project must exist and not be in the Trash. ```json {"tool": "sessions.move", "args": {"sessionId": "ses_123", "projectId": "proj_456"}} ``` ## `sessions.pin` Pins or unpins a session. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **pinned** (boolean, required) `true` pins, `false` unpins. **Returns:** `{sessionId, pinned}` plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). Reads show the state as `pinned`, and `revision` changes. ## `sessions.speakers.rename` Names a speaker in a session that is not recording, as the speaker menu in the app does. The speaker is linked to the person with that name, who is created if there is none. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session. Find ids with `sessions.list` or `talkbar_find`; the live session's id comes from `sessions.recording`. **speakerId** (string, required) `speakerId` from `sessions.stats`. **name** (string, required) The speaker's name. 1 to 40 characters after trimming. **Returns:** `{sessionId, speakerId, name, contactId}`. - A person TalkBar created for this speaker alone (not yet confirmed, linked to nothing else) is renamed instead of creating another. - When several people have the name, the call fails and lists them, so you can link one with `sessions.speakers.link`. - A name another speaker in the session already has is refused: combine the two speakers in the app instead. - A recording session is refused with `session_recording`; an unknown speaker is `not_found`. What was said and voice data are not changed. ```json {"tool": "sessions.speakers.rename", "args": {"sessionId": "ses_123", "speakerId": "spk_2", "name": "Dana Lee"}} ``` ## `sessions.speakers.link` Links a speaker in a session that is not recording to a person already in TalkBar. The speaker takes the person's name. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session. Find ids with `sessions.list` or `talkbar_find`; the live session's id comes from `sessions.recording`. **speakerId** (string, required) `speakerId` from `sessions.stats`. **contactId** (string, required) A person from `contacts.list`. **Returns:** `{sessionId, speakerId, name, contactId}`. - Never creates a person: an unknown or archived person is `not_found`. - A recording session is refused with `session_recording`. ## `sessions.speakers.unlink` Removes a speaker's name and person link in a session that is not recording, as **Remove name** does in the app. The speaker goes back to Speaker 1, Speaker 2 and so on, numbered by when they first speak. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session. Find ids with `sessions.list` or `talkbar_find`; the live session's id comes from `sessions.recording`. **speakerId** (string, required) `speakerId` from `sessions.stats`. **Returns:** `{sessionId, speakerId, name, contactId}`. - A recording session is refused with `session_recording`. ## `sessions.cards.add` Creates a knowledge card in a session, also while it is recording. The card shows on the recording screen right away. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **title** (string, required) The card title. Must not be empty. **body** (string) The card text. **type** (string) The card type. One of `fact`, `preference`, `decision`, `commitment`, `risk`, `open_question`, `relationship_context`, `instruction`, `key_moment`, `contract_term`, `pricing_detail`, `technical_detail`. Default `fact`. **sessionOnly** (boolean) Keep the card in this session only. Otherwise it is filed the way the app files a card added during a session: under the session's project when it has one (unless the session's memory setting keeps cards in the session), else in this session only. **Returns:** The card (`memoryId`, `title`, `type`, `status`, `pinned`, `projectId`, `sessionOnly`, `updatedAt`) with `sessionId` and `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). - A session holds up to 24 cards; adding a 25th is refused with `limit_reached`. ```json {"tool": "sessions.cards.add", "args": {"sessionId": "ses_123", "title": "Budget capped at $40k", "type": "decision"}} ``` ## `sessions.cards.attach` Brings an existing knowledge card into a session, also while it is recording. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **memoryId** (string, required) The card, from `knowledge.list`. **Returns:** `{memoryId, sessionId, attached: true, alreadyAttached}` plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). - A session holds up to 24 cards (`limit_reached` past that). A card from another workspace is `not_found`. ## `sessions.cards.detach` Takes a knowledge card out of a session. The card itself is kept, so this runs through `talkbar_change`. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **memoryId** (string, required) The card, from `sessions.live_cards` or `knowledge.list`. **Returns:** `{memoryId, sessionId, attached: false}` plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). ## `sessions.trash` Moves a finished session to the Trash. It can be restored. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session. Find ids with `sessions.list` or `talkbar_find`; the live session's id comes from `sessions.recording`. **Returns:** `{sessionId, trashed: true}`. - A session that is still recording is refused with `session_recording`. - Trashing a session already in the Trash succeeds and keeps the first trash date. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ```json {"tool": "sessions.trash", "args": {"sessionId": "ses_123"}} ``` ## `sessions.restore` Brings a session back from the Trash. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session. Find ids with `sessions.list` or `talkbar_find`; the live session's id comes from `sessions.recording`. **Returns:** `{sessionId, restored: true}`. Restoring a session that is not in the Trash returns the same answer. - Counts against your plan's session limit: at the limit it is refused with `plan_limit` (`limit: "sessions"`). `plan.get` shows the limit. ## Related - [Operations reference](/mcp/operations) - [Topics and markers](/mcp/operations/topics-and-markers) (session keywords and markers) - [Action items](/mcp/operations/action-items) - [Knowledge](/mcp/operations/knowledge) - [Session details in the app](/sessions/session-details) --- # Topics and markers MCP and CLI operations for topics that label sessions and notes, session keywords, and markers on moments in a session. Canonical URL: https://docs.talkbar.app/mcp/operations/topics-and-markers Topics label sessions and notes; keywords are the words TalkBar (or you) attach to a session; markers flag a moment in a session with an optional note. Every operation also takes an optional `workspaceId`. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`topics.list`](#topicslist) | Read | `talkbar_read` | On | `content` | | [`topics.create`](#topicscreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`topics.rename`](#topicsrename) | Write | `talkbar_change` | Off | `contentChanges` | | [`topics.delete`](#topicsdelete) | Write | `talkbar_delete` | Off | `contentChanges` | | [`topics.assign`](#topicsassign) | Write | `talkbar_change` | Off | `contentChanges` | | [`topics.unassign`](#topicsunassign) | Write | `talkbar_change` | Off | `contentChanges` | | [`sessions.keywords.get`](#sessionskeywordsget) | Read | `talkbar_read` | On | `content` | | [`markers.list`](#markerslist) | Read | `talkbar_read` | On | `content` | | [`markers.create`](#markerscreate) | Write | `talkbar_change` | Off | `contentChanges` | | [`markers.update`](#markersupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`markers.delete`](#markersdelete) | Write | `talkbar_delete` | Off | `contentChanges` | ## `topics.list` Lists the topics used to label sessions and notes. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments:** none besides `workspaceId`. **Returns:** `{topics: [{topicId, name, color}]}`, sorted by name. ```json {"tool": "topics.list", "args": {}} ``` ## `topics.create` Adds a topic. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **name** (string, required) The topic name. 1 to 80 characters. **color** (string) One of `slate`, `sky`, `stone`, `teal`, `indigo`, `green`, `yellow`, `blue`, `purple`, `rose`, `lime`, `emerald`, `amber`, `cyan`, `fuchsia`, `pink`, or a `#RGB` / `#RRGGBB` hex color. Without it, the color is chosen from the name, so the same name always gets the same color. **Returns:** `{topicId, name, color}`. - A name that already exists is refused with `failed`. An unsupported color is refused with `failed` ("Unsupported topic color"). ```json {"tool": "topics.create", "args": {"name": "Hiring", "color": "teal"}} ``` ## `topics.rename` Changes a topic's name or color. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **topicId** (string, required) The topic, from `topics.list`. **name** (string) The new name. 1 to 80 characters. **color** (string) The new color, as for `topics.create`. **Returns:** `{topicId, name, color}`. - Give `name`, `color` or both. ## `topics.delete` Deletes a topic and removes it from every session and note. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **topicId** (string, required) The topic, from `topics.list`. **Returns:** `{topicId, deleted: true}`. - Topics have no Trash: this deletes the topic as the app does. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## `topics.assign` Adds a topic to one session or note. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **topicId** (string, required) The topic, from `topics.list`. **sessionId** (string) The session to label. Give this or `noteId`, not both. **noteId** (string) The note to label. Give this or `sessionId`, not both. **Returns:** `{sessionId, noteId, topics}`: the item's topics after the change. ```json {"tool": "topics.assign", "args": {"topicId": "top_9", "sessionId": "ses_123"}} ``` ## `topics.unassign` Removes a topic from one session or note. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **topicId** (string, required) The topic, from `topics.list`. **sessionId** (string) The session. Give this or `noteId`, not both. **noteId** (string) The note. Give this or `sessionId`, not both. **Returns:** `{sessionId, noteId, topics}`: the item's topics after the change. ## `sessions.keywords.get` Reads a session's keywords. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** `{sessionId, keywords: [string]}`, plus `pending: true` while the session records. - TalkBar writes its AI keywords with the final summary, after recording stops; until then only keywords you added are listed. ```json {"tool": "sessions.keywords.get", "args": {"sessionId": "ses_123"}} ``` ## `markers.list` Lists a session's markers: note, time, color and the words quoted at that moment. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **Returns:** `{sessionId, markers}`. Each marker is `{markerId, sessionId, kind, body, quote, atMs, turnId, chunkId, pointId, color, updatedAt}`. ```json {"tool": "markers.list", "args": {"sessionId": "ses_123"}} ``` ## `markers.create` Adds a marker to a session, also while it is recording: at a transcript turn or chunk, a timeline point, a moment or quoted words, with an optional note and color. It shows on the session right away. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **sessionId** (string, required) The session to use. For a session that is recording now, get its id from `sessions.recording`. **turnId** (string) A transcript turn (`sessions.transcript` with `format: "json"`). Give at least one of `turnId`, `chunkId`, `pointId`, `atMs` or `quote`. **chunkId** (string) A live transcript chunk (`sessions.transcript` with `format: "json"`). The marker goes at the chunk's first turn. Give at least one of `turnId`, `chunkId`, `pointId`, `atMs` or `quote`. **pointId** (string) A timeline point (`sessions.timeline`). Cannot be combined with `turnId` or `chunkId`. Give at least one of `turnId`, `chunkId`, `pointId`, `atMs` or `quote`. **atMs** (integer) A moment, in ms from the session start. With a turn, chunk or point it must fall inside it; while recording it cannot be later than now. Give at least one of `turnId`, `chunkId`, `pointId`, `atMs` or `quote`. **quote** (string) The words the marker is about. On its own, it finds the turn holding those words; when several turns hold them, add `turnId` or `atMs` to pick one. Give at least one of `turnId`, `chunkId`, `pointId`, `atMs` or `quote`. **body** (string) The marker's note. Up to 2,000 characters. **color** (string) The marker color. 1 to 40 characters; default `amber`. **Returns:** The marker (`{markerId, sessionId, kind, body, quote, atMs, turnId, chunkId, pointId, color, updatedAt}`) plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). - An id the session does not have, or an `atMs` outside the place named, is refused with `invalid_arguments`. - The marker keeps its moment as well as the ids, so the app still places it after the transcript is enhanced. ```json {"tool": "markers.create", "args": {"sessionId": "ses_123", "quote": "we can ship in March", "body": "Ship date commitment", "color": "rose"}} ``` ## `markers.update` Changes a marker's note or color. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **markerId** (string, required) The marker, from `markers.list`. **body** (string) The new note. **color** (string) The new color. **Returns:** The marker plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). - Give `body`, `color` or both. ## `markers.delete` Deletes a marker. **Write** · runs with [`talkbar_delete`](/mcp/tools#talkbar_delete) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **markerId** (string, required) The marker, from `markers.list`. **sessionId** (string) Optional check: the marker's own session. If it names another session, nothing is deleted and the answer is `not_found`. **Returns:** `{markerId, sessionId, deleted: true}` plus `sessionStatus` (and a `warning` when the session was interrupted, or is recording while TalkBar is not running). `sessionId` is the marker's own session. - Markers have no Trash: this deletes as the app does. - Runs with `talkbar_delete`: [confirmed with you](/mcp/access-and-permissions#confirming-deletes) when your AI app can ask; apps that cannot ask are refused unless **Allow deletes without confirmation** is on. ## Related - [Operations reference](/mcp/operations) - [Sessions](/mcp/operations/sessions) - [Topics and keywords in the app](/knowledge/topics-and-keywords) --- # Workspace and profile MCP and CLI operations for workspaces, workspace search and statistics, your profile and your plan. Canonical URL: https://docs.talkbar.app/mcp/operations/workspace-and-profile These operations tell an assistant which workspace it is working in, search it, count what it holds, and read your profile and plan. Every operation here except `workspace.list` also takes an optional `workspaceId`; without it, the workspace open in the app is used. See [How to read this reference](/mcp/operations#how-to-read-this-reference) for the conventions. | Operation | Kind | Tool | On | Group | | --- | --- | --- | --- | --- | | [`workspace.list`](#workspacelist) | Read | `talkbar_read` | On | `metadata` | | [`workspace.search`](#workspacesearch) | Read | `talkbar_read` | On | `content` | | [`workspace.stats`](#workspacestats) | Read | `talkbar_read` | On | `metadata` | | [`workspace.rename`](#workspacerename) | Write | `talkbar_change` | Off | `contentChanges` | | [`profile.get`](#profileget) | Read | `talkbar_read` | On | `content` | | [`profile.update`](#profileupdate) | Write | `talkbar_change` | Off | `contentChanges` | | [`plan.get`](#planget) | Read | `talkbar_read` | On | `metadata` | ## `workspace.list` Lists your workspaces and marks the one open in the app. Operations called without `workspaceId` use that open workspace. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments:** none. **Returns:** `{workspaces: [{workspaceId, name, active}]}`. `active: true` marks the workspace open in the app. - A good first call: it tells an assistant which workspace every other call will use by default. ```json {"tool": "workspace.list", "args": {}} ``` ## `workspace.search` Searches a workspace by name and text across sessions, notes, documents, chats, action items, projects, series, people, companies and knowledge cards, best matches first. The [`talkbar_find`](/mcp/tools#talkbar_find) tool runs this same search. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments** **query** (string, required) What to look for. Must not be empty. Matching ignores case and accents. **projectId** (string) Search only within this project. **kinds** (string[]) Which kinds of item to search. Empty or left out means every kind. Values: `session`, `note`, `document`, `chat`, `action_item`, `project`, `series`, `person`, `company`, `memory` (a knowledge card). **limit** (integer) Most matches to return. From 1 to 100. Default `20`. **match** (string) `any` (default) takes a natural-language request and matches items holding any remaining word; `all` requires every word. **includeArchived** (boolean) Also match archived series, people, companies and knowledge cards; they come back marked `archived`. Default `false`. Items in the Trash are never searched. **Returns:** `{matches, contentSearch}`. Each match has `kind`, `id`, `title`, `snippet`, `href` (an app link), `score`, `projectId`, `matchedIn`, `atMs` (a session's start, otherwise the last update), `detail`, `context`, `itemCount`, `archived` and, for a match inside indexed transcript or document text, `content`. `contentSearch` says whether indexed content was searched: `on`, `keywordOnly` (no embedding model installed), `off` or `failed` (name and text matches are still returned). - Snippets can include transcript text. - It searches item names and their own text (final session summaries, note bodies, chat messages, action item details, card bodies), plus indexed content when available. ```json {"tool": "workspace.search", "args": {"query": "pricing decision for Northwind", "kinds": ["session", "note"], "limit": 10}} ``` ## `workspace.stats` Counts sessions by status, notes, documents, projects and approved knowledge cards in a workspace. No content text is returned. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments** **projectId** (string) Count only this project. Applies to sessions, notes, documents and knowledge cards; the project count ignores it. **startedAfterMs** (integer) Count only sessions that started at or after this time (epoch ms, inclusive). Applies to sessions only. **startedBeforeMs** (integer) Count only sessions that started before this time (epoch ms, exclusive). Applies to sessions only. **Returns:** `{sessions: {total, byStatus, firstStartedAtMs, lastStartedAtMs}, notes: {total}, documents: {total}, projects: {total}, knowledge: {approvedTotal}}`. ```json {"tool": "workspace.stats", "args": {"startedAfterMs": 1761955200000}} ``` ## `workspace.rename` Renames a workspace: the open one, or the one `workspaceId` names. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **name** (string, required) The new name. Must not be empty; surrounding spaces are trimmed. **Returns:** `{workspaceId, name}`. - Creating, switching and trashing workspaces stay in the app. ```json {"tool": "workspace.rename", "args": {"name": "Client work"}} ``` ## `profile.get` Reads your name, email and job title from the profile the workspace uses. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `content` **Arguments:** none besides `workspaceId`. **Returns:** `{profileId, workspaceId, name, email, jobTitle, isDefault}`. ```json {"tool": "profile.get", "args": {}} ``` ## `profile.update` Changes your name, email or job title in the profile the workspace uses. **Write** · runs with [`talkbar_change`](/mcp/tools#talkbar_change) · MCP switch **Off** by default · policy group `contentChanges` **Arguments** **name** (string | null) Your name. `null` or an empty string clears it. **email** (string | null) Your email. It must have text before and after a single `@` and no spaces. `null` or an empty string clears it. **jobTitle** (string | null) Your job title. `null` or an empty string clears it. **Returns:** The profile, as `profile.get` returns it. - Give at least one field. Fields you leave out stay as they are; your avatar is kept. - The profile shows in the app and on pages you share. ```json {"tool": "profile.update", "args": {"jobTitle": "Head of Product"}} ``` ## `plan.get` Reads your TalkBar plan: its limits and how much of each this workspace and data folder use, the license state, and the plans above yours with what each adds. **Read** · runs with [`talkbar_read`](/mcp/tools#talkbar_read) · MCP switch **On** by default · policy group `metadata` **Arguments:** none besides `workspaceId`. **Returns:** `plan` (`{id, name}`, the plan in effect), `licensedPlan`, `previewTrialActive`, `previewTrialExpiresAt`, `environment`, `license` (`plan`, `status`, `paid`, `updatesUntil`, `onlineServicesUntil`, `renewalOpen`), `limits`, `features`, `upgrades` (`[{id, name, adds, limits}]`, empty on the top plan) and `upgradeUrl` (`null` when there is no plan above). - `limits` holds `projects` and `sessions` (per workspace), `workspaces`, `profiles` and `shareLinks` (per data folder) and `devices` (per license), each as `{max, used, per}`; `max: null` means unlimited. Other limits, such as `recordingMinutes`, have no `used`. - During an active Preview trial, `plan` is the trial plan and `licensedPlan` keeps the plan of your license. - Never returns a license key, email, holder name or payment details, and cannot change the plan. When a write is refused with `plan_limit`, this is where an assistant sees why. See [Errors and limits](/mcp/errors-and-limits). ```json {"tool": "plan.get", "args": {}} ``` ## Related - [Operations reference](/mcp/operations) - [The five MCP tools](/mcp/tools) - [Errors and limits](/mcp/errors-and-limits) - [Plans and license](/data/plans-and-license)