How Wix scaled AI-native work to 5,000 employees with Willow
Read More
Enterprise Connectors
Dialogbrain logo. Dialogbrain MCP server connector.

Dialogbrain MCP Server

Unified inbox MCP for WhatsApp, Telegram, Email, voice — read/send messages, search, AI agents.

ToolsTools
179
Last updatedLast Updated
CategoryCategory
All
✓Enterprise-grade security
✓SSO & authentication ready
✓Full governance & audit logs

What is the Dialogbrain MCP Server?

The Dialogbrain MCP server gives AI agents structured, permission-aware access to Dialogbrain through the Model Context Protocol. With 179 pre-built actions, agents can read, create, and update Dialogbrain data on behalf of authorized users.

Willow ships the Dialogbrain MCP server as part of an enterprise control plane. Every call runs behind SSO (Okta, Azure AD), enforces RBAC and least-privilege at runtime, writes to a full audit trail, and integrates with Splunk and Loki for SIEM visibility. Connect from Claude Desktop, Claude Code, Cursor, ChatGPT, VS Code, n8n, or any custom agent. Install once, distribute org-wide, and see exactly how Dialogbrain is being used by every AI agent in your stack.

Tools

contacts_find

👤 Search for contacts in your address book by name or username. When to use: - User asks 'find contact X' or 'who is Y?' - User wants to know someone's username or ID - Before sending a message to verify contact exists - To get contact's channel reference for messaging Examples: ❓ User: 'find contact named [name]' → contacts_search(query='[name]', limit=5) ❓ User: 'who is [full name]?' → contacts_search(query='[full name]', limit=1) ❓ User: 'search for @username' → contacts_search(query='username', limit=10) Returns: name, username, channel, channel_ref, similarity_score, match_type. Plus: - entity_id: local DB key — pass to contacts.profile. Null for live-discovered contacts (skip contacts.profile for those). - telegram_user_id (when channel='telegram'): the Telegram user ID — pass to calls.make / messages.send. NOT entity_id.

contacts_discover

Search for a contact on a live channel (Telegram, WhatsApp, etc.) before adding them. Use this to look up a person by username or phone number before calling contacts.sync. This is the right tool when asked to add or find a specific person by @username or phone (use contacts.sync afterwards to actually add them) — not group_discovery.

contacts_sync

Add a discovered contact and open a conversation thread. Returns thread_id for the new conversation. Call contacts.discover first to verify the contact exists.

contacts_profile

👤 Get full profile for a contact: all channel identities, notes, role, capabilities, birthday. When to use: - After contacts.find to get complete info about a specific person - To see all channels a contact is reachable on - To read notes, role, or capabilities for a contact Requires contact_id (entity_id) from contacts.find.

contacts_update

✏️ Update a contact's profile: name, notes, role, capabilities, birthday, preferred channel. When to use: - User wants to add notes about a contact - User wants to set/update role or capabilities for a contact - User wants to rename a contact or update birthday Requires contact_id (entity_id) from contacts.find. At least one optional field must be provided.

contacts_add_channel

🔗 Link a new channel identity (email, phone, LinkedIn, etc.) to an existing contact. When to use: - User learns a contact's email or phone and wants to save it - User wants to link a LinkedIn/Instagram profile to an existing contact - Adding a second channel for an existing person Requires contact_id (entity_id) from contacts.find.

group_search

Search for public groups or channels by topic on Telegram (or other channels). Returns matching groups with title, member count, and whether messages can be previewed. Finds public groups/channels by topic — NOT individual people. To find or add a specific person by @username, use contacts.discover / contacts.find instead. When to use: - Finding groups related to a topic or niche - Building a list of groups for outreach or monitoring After searching, use group.scan to evaluate quality before joining.

group_add

Add a specific group to your discovery list by @username or invite link (t.me/...). Groups and channels only — this does NOT add an individual person/contact. To add a person by @username (e.g. a customer or lead), use contacts.discover then contacts.sync instead. When to use: - You already know the group's @username or invite link - Adding a known group without searching Returns: group metadata including id, title, member_count.

group_list

List groups you've found and joined in this workspace. Lifecycle values: - discovered: found but not yet evaluated - bookmarked: saved for later - monitored: joined and actively syncing messages - dismissed: hidden By default, dismissed groups are excluded. Returns: id, title, member_count, lifecycle, scan_status, overall_score.

group_preview_messages

Read recent public messages from a group without joining it. Only works for groups where can_preview_history=true. Use this to manually evaluate message quality before deciding to join. For an automated quality score, use group.scan instead. Returns: list of recent messages with sender, text, date, is_reply.

group_scan

Scan a group to evaluate its quality before joining. Fetches recent messages, analyzes activity, spam, and engagement, then returns a quality score and plain-English verdict. When to use: - After finding groups with group.search - Before deciding which groups to join Returns: overall_score (0-1), is_disqualified, disqualify_reasons, individual scores, and a verdict string.

group_join

Join a group and start syncing its messages to your inbox. The group must be in your discovery list (use group.search or group.add first). What this does: - Joins the group on Telegram (or other channel) - Creates a thread in your inbox for syncing messages - Optionally enables AI auto-reply drafts Returns: success, thread_id, auto_reply_enabled.

group_create

Create a new group on a channel (Telegram or WhatsApp). Returns the new group's chat ID and invite link. What this does: - Creates a new group with the specified title - Returns chat_id, invite_link, and channel_ref for further operations - Optionally registers the group in your inbox for monitoring Returns: success, chat_id, channel_ref, title, thread_id.

group_add_member

Add a member to an existing group on Telegram or WhatsApp. What this does: - Adds the specified member to the group - Resolves the member by username, phone number, or JID - Reports if the member is already in the group Returns: success, chat_id, member, already_member.

group_promote_admin

Promote a member to admin in an existing group on Telegram or WhatsApp. What this does: - Gives the specified member admin status in the group - On Telegram, this grants visibility of all group messages (even if not a bot) - Defaults to minimal/empty rights; specify custom rights if needed Returns: success, chat_id, member.

files_ingest

Save and index a file into the knowledge base. Use this when the user asks to save, store, or remember a document. The file will be processed (OCR if needed) and indexed for future search.

files_read

Read **text content** of an attached file. Works for: .txt, .md, .json, code files, and PDFs (after files.ingest extracts text). DO NOT call on binary files — for IMAGES use `files.get_base64`, for AUDIO/VIDEO it cannot be transcribed via this tool, and for non-PDF DOCUMENTS run `files.ingest` first, THEN files.read. Calling on a binary mime-type returns an error — saves you a turn to read the routing hint before deciding.

files_upload

Upload a file to DialogBrain and get a file_id for use in messages_send. When to use: - User wants to send a file/image to a contact - Before calling messages_send with an attachment Returns: file_id (integer) to pass to messages_send attachments parameter.

images_generate

Generates a PNG image from a text prompt using Gemini 2.5 Flash Image. Returns a file_id consumable by messages.send(attachments=[...]) and other file-aware tools. Supports up to 12 reference image file_ids for subject-consistent edits and composition (use file IDs from the [ATTACHMENTS] block, files.search, or search.files). Latency: ~8-10s per image. Output: 1024×1024 PNG.

videos_generate

Generate a short video (5-10s) from a text prompt using BytePlus Seedance. Optionally accepts up to 12 image file IDs from the user's attached files (visible in the [ATTACHMENTS] block) as `reference_file_ids` for style and composition. Returns immediately with a job_id; the video is delivered back via continuation when the job completes (~30-90s for fast model, ~2-5min for pro). Reference images are temporarily re-hosted on a third-party CDN (imgbb) for the duration of generation and deleted on completion — don't submit confidential references. Gated behind a workspace opt-in flag.

images_search

Searches images in this workspace by visual content using vector embeddings (Voyage multimodal-3). Pass a text description; returns ranked file_ids with cosine scores and presigned download URLs. Up to 50 results.

vision_query

Look at the screen currently being shared in a meeting and answer a question about it. Returns a natural-language answer based on the visual content. Use ONLY when the user explicitly asks about the screen/slide/document being shown.

youtube_list_videos

List videos on the connected YouTube channel. Returns id, title, published_at, view_count. Paginate via page_token.

youtube_list_comments

List comment threads on a YouTube video. Pass video_id (e.g. 'dQw4w9WgXcQ') or channel_ref ('youtube:video:<id>'). Returns top-level comments with inline replies.

youtube_post_comment_reply

Post a comment on a YouTube video, or reply to an existing comment. Pass video_id for a top-level comment, OR parent_comment_id to reply. AI-disclosure suffix appended automatically when configured.

youtube_delete_comment

Permanently delete a YouTube comment by id (or 'youtube:comment:<id>'). Cannot be undone. Costs 50 quota units.

youtube_delete_video

Permanently delete a YouTube video by id (or 'youtube:video:<id>'). Cannot be undone. Costs 50 quota units. Caller must own the channel.

youtube_update_video

Update title, description, privacy, or tags on a YouTube video. Costs 1600 quota units. Only fields provided are changed.

youtube_moderate_comment

Apply a moderation status to a YouTube comment. Allowed status values: heldForReview, published, rejected, spam. Costs 50 quota units.

youtube_upload_video

Upload a workspace-owned video file (file_id) to the connected YouTube channel. Returns video_id + thread_id. Costs 1600 quota units. Default privacy is 'private' — pass privacy='public' to publish.

youtube_video_query

Ask Gemini about a YouTube video. Pass a video URL and any prompt — verbatim transcript with timestamps, summary, targeted Q&A about content or visuals, translation, etc. Works on any public/unlisted video.

instagram_publish_media

Publish a photo (IMAGE) or video (REELS) from workspace files to a connected Instagram Business/Creator account. Returns media_id + permalink. Instagram allows ~25 publishes per day.

instagram_update_media

Update the caption of a published Instagram photo or Reel. Only caption is editable after publish (Instagram limitation).

instagram_list_media

List photos and Reels on the connected Instagram Business/Creator account. Returns id, caption, media_type, permalink, thumbnail_url, timestamp.

files_info

Get metadata and download URLs for files by their IDs. When to use: - After messages_read_history returns attachment_file_ids - To get a presigned download URL to read a received file Returns: filename, mime_type, byte_size, download_url (1-hour presigned URL).

files_get_base64

Download one or more files server-side and return their content as base64-encoded strings. Use this to inspect images, PDFs, or any binary file attached to messages when you cannot access presigned S3 URLs directly. Supports up to 5 files per call, max 15 MB each. For large files batch in groups of 1-2 to avoid oversized responses.

messages_read_history

Read messages from a conversation thread. Use text_contains to find specific messages by content. Returns the most recent messages, including sender info and timestamps. Voice calls: each row carries a `meta` object with allowlisted keys (`event_type` ∈ 'call_started'|'call_ended'|null, `source` ∈ 'voice_transcript'|null, `call_id`, `speaker_display_name`, `duration_seconds`, `outcome`, `direction`) plus per-message `channel`. To find calls without scanning every row, use `calls.list_history` instead. Usage: 1. Get thread_id from threads.list first, OR 2. Use contact_name to auto-resolve thread_id Examples: - User: 'show me messages from chat with [contact]' → read_history(contact_name='[contact]', limit=10) - User: 'last 5 messages from thread 571' → read_history(thread_id=571, limit=5)

channels_connect_telegram_bot

🤖 Connect a Telegram Bot (Bot API) channel from its bot token. When to use: - After a bot was created via @BotFather and you have its token. - The token alone is sufficient — no Telegram user account is needed. Validates the token, creates the channel account, and registers the webhook so the bot starts receiving messages immediately.

threads_update

✏️ Update a conversation thread: rename it, add notes/description, or move to a folder. When to use: - User wants to rename a chat or group - User wants to add notes/context about a conversation - User wants to organize threads into folders For DM threads, renaming also updates the linked contact's display name by default. Requires thread_id from threads.list.

folders_create

📁 Create a new inbox folder to organize threads. When to use: - User wants to create a folder to group related conversations - User wants to organize threads by topic, project, or contact type After creating a folder, use threads.update with folder_id to move threads into it.

folders_delete

🗑️ Delete an inbox folder. Threads inside become unfiled (not deleted). When to use: - User wants to remove a folder they no longer need - User wants to clean up their inbox organization Threads inside the folder are NOT deleted — they simply move back to the inbox.

ai_tags_list

List all personal AI tags. AI tags are automatic message filters: the system runs a lightweight classifier on every incoming message and applies matching tags to threads. This lets AI agents skip expensive full analysis on most messages — they only act on threads that match relevant tags, dramatically cutting LLM costs. When to use: - Check which auto-classification filters exist before creating one - Get tag IDs for add_to_thread / remove_from_thread - See how many threads each tag currently matches Returns all tags with thread counts (non-archived, included threads only).

ai_tags_create

Create a new AI tag (automatic message filter). AI tags are lightweight classifiers that run on every incoming message. When a message matches the tag's description/criteria, the thread is automatically labelled — so AI agents can cheaply pre-filter threads instead of running full LLM analysis on everything. Good descriptions are the key: they tell the classifier exactly when to apply this tag. When to use: - User wants to auto-classify incoming messages (e.g. bug reports, sales leads, support requests) - User wants to reduce AI agent costs by pre-filtering threads by topic or intent Tips for the description field: - Be specific: 'Messages reporting errors, crashes, or unexpected behavior in the product' - Include examples of what qualifies and what doesn't Limit: 20 active personal tags / 50 active team tags.

ai_tags_update

Update an existing personal AI tag's name, description, icon, color, or active state. When to use: - User wants to rename a tag - User wants to change a tag's icon, color, or description - User wants to enable or disable a tag Provide only the fields you want to change. At least one field is required.

ai_tags_delete

Delete a personal AI tag. All thread associations are removed automatically. When to use: - User wants to permanently remove a tag they no longer need This cannot be undone. Threads are NOT deleted — they just lose this tag.

ai_tags_add_to_thread

Apply one or more AI tags to a thread (manually). When to use: - User wants to label a conversation with one or more tags - User asks to categorize or tag a thread Provide the thread_id (integer) and an array of tag_ids to apply. If a tag is already applied it will be updated to is_manual=true.

ai_tags_remove_from_thread

Remove a specific AI tag from a thread. When to use: - User wants to un-label or remove a specific tag from a conversation - User wants to correct an incorrectly applied tag Provide both thread_id and tag_id.

ai_filters_list

List all AI filters for the current workspace. AI filters are semantic intent-based message filters that use embeddings (vector representations) to detect whether an incoming message matches a specific intent or topic. Unlike keyword filters, they understand meaning: 'I need help with my order' and 'my package hasn't arrived' both match a 'shipping support' filter even without shared keywords. Each filter stores a reference embedding of its description. When a message arrives, its embedding is compared via cosine similarity against the filter's reference vector. If the similarity exceeds the threshold, the filter matches. When to use: - Check which semantic filters already exist before creating a new one - Get filter IDs for use in trigger conditions - Review thresholds and active status of existing filters Returns all filters with id, name, description, threshold, and is_active.

ai_filters_create

Create a new AI filter for semantic intent-based message matching. AI filters use vector embeddings (via Voyage AI) to detect whether an incoming message matches a specific intent or topic. The filter's description is embedded as a reference vector at creation time. When a message arrives, its embedding is compared against this reference using cosine similarity. The description field is the most important part — it becomes the reference embedding that all incoming messages are compared against. Write it as a clear statement of what kind of messages should match: - 'Customer asking about pricing, subscription plans, or billing' - 'User reporting a bug, crash, or unexpected behavior in the product' - 'Inbound sales lead expressing interest in purchasing or trialing' The threshold controls sensitivity: 0.5 is a balanced default, lower values (0.3) cast a wider net, higher values (0.8) require closer matches. Note: This tool calls the Voyage AI embedding API to generate the reference vector.

ai_filters_update

Update an existing AI filter's name, description, threshold, or active state. When to use: - User wants to rename a filter - User wants to refine the filter description to improve match accuracy - User wants to adjust the similarity threshold (higher = stricter matching) - User wants to enable or disable a filter without deleting it Provide only the fields you want to change. At least one field is required. Note: If the description is changed, this tool calls the Voyage AI embedding API to re-generate the reference vector with the new description text.

ai_filters_delete

Permanently delete an AI filter. When to use: - User wants to remove a filter they no longer need This action cannot be undone. Any triggers that reference this filter by ID will no longer match it — review and update those triggers after deletion.

ai_filters_test

Test a message against an AI filter to check whether it would match. This tool embeds the provided message using Voyage AI and computes the cosine similarity between the message vector and the filter's stored reference vector. It returns the similarity score, whether the message would match (similarity >= threshold), and the filter's threshold value. Use this to: - Verify a filter works as intended before using it in a trigger - Tune the threshold by testing borderline messages - Debug why a message did or did not match a filter in production Returns: {similarity: float, matched: bool, threshold: float} Note: This tool calls the Voyage AI embedding API to embed the test message.

messages_send

Send a message to a thread, channel, or contact. Supports Telegram, Email, LinkedIn, and other connected channels. For LinkedIn posts (comment_thread kind), this posts a comment on the post. Can automatically resolve recipients and channels when not specified. Can send files/images/documents as attachments — pass `attachments=[file_id, ...]` with integer file IDs obtained from collections.list_files, search.files, or files.search. `text` is optional when attachments are provided.

messages_send_email

Compose and send an email — with subject, CC/BCC, and attachments. Use for email; for chat messages (Telegram/WhatsApp/livechat) use messages.send instead.

messages_delete

Delete a message from a thread. Supports Telegram, WhatsApp, and other connected channels. Note: Some channels have time limits on message deletion.

messages_forward

Forward a message from one thread to another. Supports native Telegram forwarding (preserves original sender attribution) and text-based forwarding for cross-channel scenarios.

knowledge_query

Answer questions using knowledge base (uploaded documents, handbooks, files). Use for QUESTIONS that need an answer synthesized from documents or messages. Returns an evidence pack with source citations, KG entities, and extracted numbers. Modes: - 'auto' (default): Smart routing — works for most questions - 'rag': Semantic search across documents & messages - 'entity': Entity-centric queries (e.g., 'Tell me about [entity]') - 'relationship': Two-entity queries (e.g., 'How is [entity A] related to [entity B]?') Examples: - 'What did we discuss about the budget?' → knowledge.query - 'Tell me about [entity]' → knowledge.query mode=entity - 'How is [A] related to [B]?' → knowledge.query mode=relationship NOT for finding/listing files, threads, or links — use search.files / search.threads / search.links for that.

kg_find_entity

Find an entity by name in the Knowledge Graph. USE WHEN user mentions a person, project, company by name and you need: - To resolve a name to entity_id for subsequent queries - 'Кто работает над X?' → find X first - 'Расскажи про Y' → find Y first RETURNS entity_id for use in kg.get_relationships or kg.explore. ALWAYS use this as the FIRST step in KG query chains.

kg_get_relationships

Get relationships for a specific entity from Knowledge Graph. USE WHEN: - 'Кто работает над X?' - filter by works_on - 'С кем общался Y?' - filter by discussed_with - 'Кто из компании Z?' - filter by member_of - 'Что связано с W?' - no filter, get all REQUIRES: entity_id from previous kg.find_entity step. Use: {{step_N.entity_id}} where N is the find_entity step number.

calendar_create_event

Create a new event in Google Calendar. Specify the title, start time, end time, and optionally invite attendees. Use ISO 8601 format for dates (e.g., 2024-12-15T14:00:00).

calendar_list_events

List events from Google Calendar. Shows upcoming events by default. Can filter by date range and search query.

calendar_update_event

Update an existing event in Google Calendar. Can modify title, time, location, description, and attendees. Only specified fields will be updated.

calendar_delete_event

Delete an event from Google Calendar. This action cannot be undone. Use with caution.

calendar_check_availability

Check when you have free time in Google Calendar. Shows busy periods and free slots in a given time range. Useful for finding meeting times or checking schedule conflicts.

web_search

Search the web for current information, news, facts, prices, or events. Use this when the user asks about something that requires up-to-date information from the internet, or when internal knowledge base doesn't have the answer. Examples: recent news, stock prices, weather, product information, current events.

web_fetch

Fetches a single URL and returns its content. Use this when you have a specific URL in mind — for example, after web.search returns a link you want to read, or when the user pastes a URL. Modes (extract): - 'auto' (default): picks the right mode based on response content type. - 'markdown': for HTML pages; returns cleaned markdown plus the page <title>. - 'text': for JSON/XML/plaintext APIs; returns the raw decoded body. - 'file': for images, PDFs, audio, video, archives, or any binary — ingests the bytes into the user's file storage and returns a file_id you can pass to messages.send (to send as an attachment), agents.add_file (to add to agent knowledge), or files.read. Use web.fetch (not files.upload) when you need the file_id immediately for the next tool call — files.upload(source_url=…) is async and won't have the file ready in the same turn. Use web.search (not web.fetch) when you don't have a specific URL yet and need to find one.

web__local_search

Multi-source web research with citations. Returns a synthesized answer with numbered [^1] markers and a citations array of {url, title, snippet, index}. Use for evidence-backed synthesis (competitive analysis, regulatory summary, whitepaper section). For quick fact lookups use web.search instead.

documents_create

Render a document (PDF / HTML / PPTX / DOCX) and save it to the workspace. This tool has two input pipelines — pass **exactly one** of `content_html` or `content_markdown`. # Pipeline A — `content_html` (canonical for decks, proposals, designed pages) You author full HTML+CSS. A baked-in design-system preamble ships first (`<style>` with Inter/Manrope as data-URI fonts, CSS-variable palette tokens, 8px spacing scale, and pre-styled layout helpers); your markup and any of your own `<style>` blocks land after the preamble so you can override anything. Chromium renders the assembled document into a static PDF — JavaScript is disabled and DNS is blackholed, so external font / image / script fetches will fail by configuration. Required when this pipeline is used: - `title` — human-readable, used for PDF metadata and the saved filename. - `content_html` — the `<body>` and any custom `<style>` blocks. The renderer wraps this in `<html>…</html>` and injects the preamble + a canonical `<meta charset>` + `<title>`. Do NOT emit `<script>`, `<iframe>`, `<object>`, `<embed>`, `<meta>`, `<link>`, `<base>`, `<form>`, or event handlers — the sanitizer strips them. - `output_type` — `"pdf"` or `"html"`. (`"pptx"` and `"docx"` require `content_markdown` since they need structured markdown intermediates.) Optional: - `page_preset` — `"slide_16_9"` (default for any deck), `"a4"` (default for flowing documents — used if omitted), `"letter"`, or `"none"` (you declare your own `@page` rule). - `design_tokens` — flat dict overriding the preamble's CSS variables. Whitelisted keys: `brand_primary`, `accent`, `surface_dark` (hex color), `font_display`, `font_body` (font name from ['Inter', 'Manrope', 'monospace', 'sans-serif', 'serif', 'system-ui', 'ui-monospace', 'ui-sans-serif', 'ui-serif']). - `language` — BCP-47 tag (default `"en"`). Drives `<html lang>`. ## Slide structure (`page_preset="slide_16_9"`) Each slide is `<section class="slide …">…</section>`. The base `.slide` class is what sizes it to the viewport and forces the page break — do not drop it. Composable variants (apply alongside `.slide`): - `.slide-cover` — gradient hero, big display title. - `.slide-split` — two equal columns, image + narrative. - `.slide-stats` — three-up KPI cards (use `<div class="stat">` with `.stat-value` + `.stat-label` inside). - `.slide-quote` — centered pull quote + `<cite>` attribution. Layout helpers (work in any preset): `.grid-2`, `.grid-3`, `.split`, `.stack`, `.cluster`, `.callout`, `.muted`, `.kbd`. ## Speaker notes `<aside class="notes">…text…</aside>` inside a `<section class="slide">`. The sanitizer strips them from the rendered PDF and returns them as `slide_notes[]` (parallel to slide order). Orphan notes outside any slide are dropped with a warning. ## Images Only these `src` schemes resolve: - `file:NNN` — workspace `file_id`. - `data:image/...;base64,...` — inline. - `https://<host>` where `<host>` ∈ `DOCUMENTS_MEDIA_URL_ALLOWLIST`. Other URLs are dropped and replaced with an HTML comment placeholder. # Pipeline B — `content_markdown` (invoice / contract only) Required: - `title`, `content_markdown`, `output_type`. Optional: - `theme` — `"invoice"` or `"contract"`. Triggers the corresponding exemplar styling and (for invoices) the arithmetic validator that fail-closes on missing or mismatched totals. - `language` — BCP-47 (default `"en"`). # Delivery contract (CRITICAL) After this tool returns `file_id`, deliver the file with `messages.send(attachments=[file_id], text="<short caption>")`. Embedding the file_id in a markdown link, `sandbox:` URL, or `/api/files/<id>/download` text will render as plain text on the recipient's channel — the `attachments` parameter is the only way the file actually attaches. # Exemplars INVOICE (English): # Invoice INV-{YYYYMMDD-HHMMSS} **From:** {Issuer Legal Name}, {Address}, {Tax ID} **To:** {Customer Name}, {Customer Address}, {Customer Tax ID} **Issue date:** {YYYY-MM-DD} **Due date:** {YYYY-MM-DD} | Description | Qty | Unit price | Total | |---|---:|---:|---:| | {Service 1} | 1 | 1500.00 | 1500.00 | | {Service 2} | 2 | 500.00 | 1000.00 | **Subtotal:** USD 2500.00 **Tax (20%):** USD 500.00 **Total:** USD 3000.00 **Payment:** {bank details OR crypto wallet — never both} INVOICE (Russian): # Счёт-фактура № INV-{YYYYMMDD-HHMMSS} **От:** {Юридическое название организации}, {Адрес}, ИНН {Tax ID} **Кому:** {Название клиента}, {Адрес клиента}, ИНН {Tax ID} **Дата:** {YYYY-MM-DD} **Срок оплаты:** {YYYY-MM-DD} | Описание | Кол-во | Цена | Сумма | |---|---:|---:|---:| | {Услуга 1} | 1 | 1500.00 | 1500.00 | | {Услуга 2} | 2 | 500.00 | 1000.00 | **Подытог:** USD 2500.00 **НДС (20%):** USD 500.00 **Итого:** USD 3000.00 **Реквизиты:** {банковские реквизиты ИЛИ криптокошелёк — не оба сразу} CONTRACT (English): # Service Agreement **Between:** {Provider Legal Name}, {Address} ("Provider") **And:** {Client Legal Name}, {Address} ("Client") **Effective date:** {YYYY-MM-DD} ## 1. Scope of services {Concise description of what Provider agrees to deliver.} ## 2. Term This Agreement begins on the Effective date and continues until {termination condition or end date}. ## 3. Compensation Client pays Provider {amount and currency} according to {payment schedule}. ## 4. Confidentiality Both parties agree to keep proprietary information of the other party confidential during and after the term of this Agreement. ## 5. Termination Either party may terminate with {N} days' written notice. ## 6. Governing law {Jurisdiction}. --- **Provider:** ____________________ **Client:** ____________________ {Provider signatory name} {Client signatory name} CONTRACT (Russian): # Договор оказания услуг **Между:** {Юридическое название Исполнителя}, {Адрес} ("Исполнитель") **И:** {Юридическое название Заказчика}, {Адрес} ("Заказчик") **Дата вступления в силу:** {YYYY-MM-DD} ## 1. Предмет договора {Краткое описание услуг, которые Исполнитель обязуется оказать.} ## 2. Срок действия Договор вступает в силу с указанной даты и действует до {условие прекращения или дата окончания}. ## 3. Стоимость и порядок оплаты Заказчик оплачивает услуги Исполнителя в размере {сумма и валюта} в порядке {график платежей}. ## 4. Конфиденциальность Стороны обязуются сохранять конфиденциальность сведений, полученных в ходе исполнения настоящего Договора, в течение срока его действия и после его прекращения. ## 5. Расторжение Любая из сторон вправе расторгнуть Договор, направив письменное уведомление не менее чем за {N} дней. ## 6. Применимое право {Юрисдикция}. --- **Исполнитель:** ____________________ **Заказчик:** ____________________ {ФИО подписанта Исполнителя} {ФИО подписанта Заказчика}

agents_list

List all AI agents configured in the workspace. Returns agents with their basic info, trigger count, and knowledge collection count. Each agent's `description` field tells you when that agent is useful. If you're a router-style agent deciding whether to delegate via `agent.handoff`, read descriptions and pick the best fit. Use this to: - See all configured AI agents - Filter by status (active/paused/archived) - Get agent IDs for further operations

agents_get

Get detailed information about a specific AI agent. Returns full agent config including: - Execution configuration - Tool configuration - Knowledge configuration - Escalation configuration - Triggers list - Knowledge collections - Custom AI instructions (prompt_text) - Auto-reply rules override (auto_reply_rules)

agents_create

Create a new AI agent in the workspace. Execution modes: - ai_assisted (default, recommended): Two-phase AI — fast pre-classifier (Haiku) for keyword filtering and simple replies, then full AI with tools for complex messages. Best for: auto-replies, group monitoring, keyword-based filtering. - agentic: Autonomous multi-step agent with planning and tool execution. Best for: complex scheduled tasks, multi-step automation. - rule_based: Simple pattern matching without AI. For keyword filtering: use ai_assisted mode + set keywords in trigger conditions (free, deterministic) and/or auto_reply_rules (smart, LLM-based) via agents.update.

agents_update

Update an existing AI agent's configuration. All parameters are optional — only provided fields will be updated. Use this to: - Enable or disable an agent - Change agent name or description - Assign or detach a prompt - Change default send mode - Replace knowledge collections - Update agent status - Change agent priority for trigger matching (lower number = higher priority) - Override which tools the agent can/can't call on triggered runs - Override which context sections (situation, communication style, job state, conversation history, thread summary) the agent receives - Opt into boilerplate prompt sections (safety guidelines, data confidentiality, factual accuracy) — all default OFF

agents_delete

Permanently delete an AI agent. WARNING: This cannot be undone. The agent and all its triggers will be removed.

agents_ask

Send a message to an AI agent and get its response. The agent runs with its configured prompt, tools, and knowledge. Use this to test agents or have them process a task. Returns: {status: 'replied'|'silent', response_text, messages[], full_reply, model_used, tokens_*, send_mode, execution_mode}. `messages[]` carries each messages.send invocation the agent made (text, subject, reply_to_message_id, timestamp, message_id, attachments=[{file_id,name,mime}]). `full_reply` concatenates text only — attachment-only sends show up in `messages` but not `full_reply`. `status='silent'` iff both response_text is empty AND messages is empty. Execution may take 10-60s depending on agent complexity.

agents_trigger_create

Create a new trigger for an AI agent. Triggers determine when the agent activates. Trigger types: - incoming_message: Activates on new incoming messages - schedule: Activates on a schedule - webhook: Activates on webhook events - event: Activates on system events

agents_trigger_update

Update an existing AI agent trigger. All parameters are optional — only provided fields will be updated.

agents_trigger_delete

Delete a trigger from an AI agent. WARNING: This cannot be undone.

agents_list_drafts

List pending agent drafts awaiting approval. Shows drafts that have been generated by AI agents but not yet sent. Each draft includes: - Thread/conversation info - Trigger message (what prompted the reply) - Generated response text - Creation time and expiration Use this when user asks: - 'Show pending agent drafts' - 'What messages are waiting for approval?' - 'List drafts to approve'

agents_approve_draft

Approve a pending agent draft and send the message. The draft will be sent to the conversation it was generated for. You can optionally edit the text before sending. Use this when user says: - 'Approve this draft' - 'Send this reply' - 'Approve and send' - 'Looks good, send it' IMPORTANT: This will send a message to a real person.

agents_reject_draft

Reject a pending agent draft without sending. The draft will be marked as rejected and won't be sent. Use this when the generated response isn't appropriate. Use this when user says: - 'Reject this draft' - 'Don't send this' - 'Cancel this reply' - 'Delete this draft' - 'This response is wrong'

agents_list_files

List files directly attached to this agent (agent-specific files, not shared collections). Returns file_id, title, status, and chunk_count for each file. chunk_count shows how many indexed chunks were created — 0 means the file is still processing. Use agents.add_file to attach a new file, or agents.remove_file to detach one.

agents_add_file

Attach a file to this agent's private knowledge (agent-specific files, not shared with other agents). Workflow: 1. Upload the file with files_upload (pass source_url for remote files) 2. Index it with files_ingest (pass the file_id) 3. Call this tool with agent_id + file_id Returns chunk_count — shows 0 while still processing. Call agents.list_files later to see the final chunk count once indexing completes.

agents_remove_file

Remove a file from this agent's private knowledge. The file itself is not deleted — it's just detached from this agent. Use agents.list_files to find the file_id to remove.

agents_task_complete

Report that a Claude Code agent task has been completed. Call this when you finish processing an agent_task from DialogBrain.

agent_handoff

Delegate a multi-step task (research, composing messages, booking, scheduling) to the full agentic planner. Use when a user ask needs more than a direct answer. The specialist runs synchronously — its response is already shown to the user in real-time. Summarize the OUTCOME in past tense (e.g. 'The Media Creator generated your video' or 'The Document Composer failed because...'). Do NOT say 'I will delegate' — the delegation already happened. If status is `timeout` or `error`, explain what went wrong and offer to retry.

agent_silence

End this turn without sending any message. Use when the thread is owned by a human operator after job.escalate, when the guest is self-resolving, when the message is a duplicate, or for observation-only turns. Calling this tool is the ONLY correct way to stay silent — narrated silence text (e.g. '*(Staying silent…)*', 'Internal:…') would be delivered to the guest verbatim.

agents_traces_list

List recent execution traces for an agent — the same data as /admin/requests, scoped to one agent and readable by an LLM. Use this when an agent call timed out, drafted the wrong response, or you want to know which tool/LLM call burned the latency. Pair with `agents.trace_get` for full detail on a specific trace. Filters: `status`, `success`, `source` (single value or comma-separated: `agent,voice`), `date_from`/`date_to` (ISO-8601), pagination via `limit`/`offset`. Returns `returned_count`, `dropped_on_page` (should be 0 — positive means the backend agent_id predicate let something through), and `has_more`. Edge case: a raw page of all-dedup-dropped rows yields `returned_count=0, has_more=true`; re-call with `offset += limit`.

agents_trace_get

Fetch the full execution detail for a single trace — tool executions, events timeline, LLM call spans (with error_message on failures). Use after `agents.traces_list` identifies a specific trace of interest (failed run, slow run, unexpected outcome). By default LLM `system_prompt` and `prompt_messages` are stripped — set `include_llm_bodies=true` to fetch them when diagnosing prompt engineering issues (emits a WARNING audit log). Set `full=true` to disable all field truncation. `completion_text` on failed LLM calls is always returned (capped at 8 KB).

agents_traces_stats

Aggregated trace statistics for one agent over the last N days — total runs, success rate, avg duration, error breakdown, top tools used, runs-per-day histogram. Use this when you want a bird's-eye view of an agent's health before diving into individual traces with `agents.traces_list` / `agents.trace_get`. Scoped to the target agent (exact match, no substring bleed). `days` is capped at 30 — matches the ClickHouse request_traces TTL.

agents_activity

See what you — or another agent in your workspace — actually did over a time window: messages sent, documents created, calls made, plus a summary (run counts, per-day, top tools). Use this to answer 'what did I do today / yesterday / last week / in the last hour?' or 'what did <agent> do?' with real data instead of guessing. Omit `agent` for your own activity, or pass another workspace agent's name, slug, or id. Pass `since`/`until` as ISO datetimes (e.g. '2026-06-03T09:00:00') for sub-day windows like the last hour, or plain dates ('2026-06-03') for whole days — compute them from the current date/time you were given. Defaults to the last 24h. Traces are retained 30 days. Times are interpreted as UTC — if the current time you were given is in another timezone, convert to UTC before passing since/until.

agents_prompt_history

List past versions of an agent's `prompt_text`. Every edit to the agent's prompt is snapshotted to an append-only table — use this tool to browse history, find a prior known-good version, and copy it into `agents.prompt_restore`.

agents_prompt_restore

Restore a past version of an agent's `prompt_text` by version_number. Creates a new version pointing at the restored content — history is preserved. Use `agents.prompt_history` first to find the version_number you want.

agents_simulate_inbound

Replay an inbound message on a thread through the real trigger pipeline and return what would have happened. The router auto-picks the winning enabled agent + trigger by priority/specificity (same logic as production). By default send_mode='draft' so no real message is sent; pass send_mode='auto' on a test account to let the matched agent actually deliver (drafts get overwritten by the next draft, so 'auto' is the only way to verify Telegram/email delivery end-to-end). Use to verify routing for a thread: which agent answers, which trigger wins, or — when nothing matches — the structured skip reason. Pass blockchain_tx_data instead of message_text to simulate a blockchain:transfer event on the thread. Returns: {matched: true, matched_agent: {id, name, execution_mode}, matched_trigger: {id, trigger_type, conditions, specificity_score}, routing_reason, response_text, messages[], execution_mode, send_mode, model_used, tokens_input, tokens_output, latency_ms, rag_queries_made, rag_results_used} on a hit, or {matched: false, skip_reason, simulator_warnings} on a miss.

agents_update_from_template

Update a forked agent's instructions (prompt) to the latest version of the system template it was created from. Use when the platform has improved a template and the user wants their forked agent to pick up the new prompt. This OVERWRITES the agent's prompt_text with the template's current prompt — any customizations to the prompt are replaced (recoverable via prompt history). Tool/model/execution settings are NOT changed. Only works on agents forked from a template (not from-scratch agents or templates themselves).

collections_list

List all knowledge collections in the workspace. Collections are named groups of files used for RAG search. Auto-created collections (per-agent, per-prompt) are hidden by default.

collections_create

Create a named knowledge collection. Collections group files for RAG search. After creating, add files with collections.add_file and assign to agents with collections.assign_agent.

collections_delete

Delete a knowledge collection. If the collection is assigned to agents, prompts, or channels, pass force=true to delete anyway. CASCADE removes all assignments automatically.

collections_add_file

Add a file to a knowledge collection. The file must be uploaded and indexed first (files_upload + files_ingest). If the file was previously removed, it is re-enabled.

collections_remove_file

Remove a file from a knowledge collection. The file itself is not deleted — only the collection membership is removed.

collections_list_files

List all files in a knowledge collection with their indexing status and chunk counts. Each returned file has a `file_id` (integer) that can be passed to messages.send as `attachments=[file_id]` to send the file to a contact, or to files.read to read its text content.

collections_assign_agent

Assign a knowledge collection to an AI agent. Once assigned, the agent's knowledge.query will automatically scope RAG search to files in its assigned collections.

collections_unassign_agent

Remove a knowledge collection from an AI agent. The collection and its files are not deleted — only the agent assignment is removed.

prompts_list

List all prompt templates in this workspace. Returns id + name + description + category so you know which prompt_id to use in prompts.get or prompts.update.

prompts_get

Get full content of a prompt template: system instructions (prompt_text) and auto-reply rules. Run prompts.list first to find the prompt_id.

prompts_update

Update a prompt template's name, system instructions, or auto-reply rules. Changes affect every agent using this template, unless the agent has its own override (set via agents.update → prompt_text). All parameters except prompt_id are optional — only provided fields are updated.

prompts_prompt_history

List past versions of a prompt template's `prompt_text`. Every edit is snapshotted to an append-only table — use this to browse history and find a version_number for `prompts.prompt_restore`.

prompts_prompt_restore

Restore a past version of a prompt template by version_number. Creates a new version pointing at the restored content — history is preserved. Fans out to every agent using this template without a per-agent override; the response includes `affected_agents` as a receipt of the fan-out.

widgets_list

List all livechat widgets. Returns widgets with their configuration, embed code, and status. Use this when user wants to see their widgets or chat widgets.

widgets_create

Create a new livechat widget for your website. The widget will be created with default settings. You can customize theme, auto-reply mode, and more. Use this when user wants to add a chat widget to their site.

widgets_update

Update an existing livechat widget configuration. You can change name, theme, auto-reply mode, and other settings. Only provided fields will be updated. Use this when user wants to modify their chat widget settings.

widgets_delete

Delete a livechat widget permanently. This will remove the widget and its embed code will stop working. Existing chat history will be preserved. Use this when user wants to remove a chat widget.

widgets_get_embed_code

Get the embed code snippet for a livechat widget. Returns HTML/JavaScript code to add to your website. The code should be placed before the closing </body> tag. Use this when user wants to install the chat widget on their site.

widgets_get

Get full configuration of a single livechat widget. Returns all settings including theme, identification, actions, and more. Use this when user wants to see or verify a specific widget's settings.

linkedin_search

Search LinkedIn for people, companies, jobs, or posts. Supports filtering by keywords, location, industry, network distance, and more. Use linkedin.search_filters first to resolve filter keywords to LinkedIn parameter IDs.

linkedin_search_filters

Get LinkedIn search filter parameter IDs. LinkedIn uses internal IDs instead of text for search filters (location, industry, etc.). Call this before linkedin.search to resolve filter keywords to their LinkedIn parameter IDs.

linkedin_get_profile

Get a LinkedIn user profile by ID, public identifier (vanity name), or profile URL. Returns name, headline, location, and other profile information.

linkedin_get_company

Get a LinkedIn company profile by company ID or vanity name. Returns company name, description, industry, size, and other details.

linkedin_update_profile

Update the authenticated user's own LinkedIn profile. Supports adding/editing experience entries (role, company, skills, dates). Also supports updating location. Headline, summary, education are NOT supported by the API.

linkedin_invite

Send a connection invitation to a LinkedIn user. Optionally include a personalized message (max 300 characters). Rate limited: LinkedIn allows 80-100 invitations per day, max 200 per week.

linkedin_list_connections

List your LinkedIn connections, sorted by most recently added.

linkedin_list_invitations_sent

List your pending sent connection invitations on LinkedIn.

linkedin_list_reactions

List all reactions (likes, celebrates, etc.) on a specific LinkedIn post.

linkedin_add_comment

Add a comment to a LinkedIn post. Use post_id from search results or thread data.

linkedin_raw_request

Send an arbitrary LinkedIn API request via Unipile's magic route. Only GET and POST methods are allowed. WARNING: This bypasses structured rate limiting and can perform destructive actions. Use this only when no other LinkedIn tool covers the needed functionality.

search_messages

Search message content across all chats — semantic + keyword. Use to find what was said: quotes, topics, info exchanged. For chats/threads themselves use search.threads; for files use search.files; for links use search.links.

search_threads

Find or list chat threads/conversations — by topic, participant, unread/unanswered status, or recency. Omit `query` to list threads by filter. For message content use search.messages; for files use search.files. `since` filters by recency and pairs with only_unread / only_unanswered.

search_files

Search files and attachments across the workspace — by content, filename, document type, or origin. For message content use search.messages; for links use search.links.

search_links

Search links/URLs shared across the workspace — by type, owner, or associated contact. For files use search.files; for message content use search.messages.

workspace_list

List every workspace the caller is a member of, with `is_current` marking the workspace this MCP key is currently routed to. Pair with `workspace.switch` to change the active workspace without reconnecting.

workspace_current

Return the workspace this MCP API key is currently routed to, with the caller's role inside it. Use this to confirm context before/after `workspace.switch`.

workspace_switch

Re-point the active MCP API key to a different workspace. Pass exactly one of `workspace_id` or `slug` (find them via `workspace.list`). Takes effect on the very next tool call — no MCP reconnect, no new API key. Sequential checkpoint: do not parallelize tool calls across a switch — calls already in flight when the switch commits will run against the previous workspace.

job_read_context

Read the current job context. Returns the full state of your active job including assignments, escalations, and any data you previously stored.

job_update_context

Update the job context by merging new data. Existing keys are preserved unless explicitly overwritten. Use this to record progress, update assignment statuses, or store intermediate results.

job_complete

Mark the job as completed. This sanitizes PII from the context and records a completion summary. Use when all tasks in the job are done.

job_escalate

Escalate the job to a human. Use when you cannot resolve an issue, someone is not responding, or a situation requires human judgment.

notes_save

Save a fact or note into the agent's memory. Use scope to choose visibility: 'workspace' = visible to every agent in this workspace (use for shared facts, project conventions); 'agent' = private to this agent (use for personal working notes); 'thread' = scoped to one conversation (use for thread-specific reminders); 'person' = scoped to one contact (use for per-contact context). If a note with the same key+scope exists it will be updated. Do NOT use this tool for behavioral rules or corrections — use feedback.save for those.

notes_recall

Recall notes from your notebook. By default returns only your own notes (all scopes, newest first). Pass filter_agent_id=<int> to read another agent's notebook, or filter_agent_id="all" (or "*") to read across every agent in the workspace. Pass scope to narrow to global/thread/person. Each result includes agent_id and agent_name of the author.

notes_search

Full-text search in your notebook. By default searches only your own notes. Pass filter_agent_id=<int> to search another agent's notebook, or "all" (or "*") for workspace-wide. Or list all notes for a person/thread by scope_ref_id.

notes_delete

Delete a note by ID from the target notebook. Same identity rules as notes.save — agents can only delete from their own notebook.

feedback_save

Save a behavioral rule, preference, or correction that should guide future agent behavior. Use this when the user gives explicit guidance like 'always reply in Russian', 'don't suggest meetings before 11am', or 'invoice link goes via email, not chat'. Structure the rule as: the rule itself, why it matters (if stated), and how to apply it. Scope: 'workspace' for org-wide rules, 'agent' for per-agent overrides, 'person' for per-contact preferences. Prefer feedback.save over notes.save for anything that's instructive rather than informational.

tasks_create

Create a new task in your to-do list.

tasks_update

Update an existing task. Set status='done' to complete it, 'cancelled' to cancel. Use summary for completion notes.

tasks_list

List your tasks, or another agent's tasks (read-only) using from_agent_id. Use filters to narrow results.

tasks_delete

Delete a task from your to-do list by its ID.

reminder_set

Schedule a reminder. One-time reminders fire at a specific datetime. Recurring reminders fire on a schedule (daily, weekly, every N days, or every N minutes). Optionally scope to a thread or target another agent.

reminder_list

List your active reminders (both one-time and recurring).

reminder_cancel

Cancel an active reminder by its trigger ID.

system_sleep

Pause execution for a given number of seconds (max 30). Use when you need to wait for an external process to complete before retrying — e.g. message sync, backfill, or API propagation. Total sleep per run is capped at 60 seconds.

calls_make

Place an outbound AUDIO/VOICE phone call via Twilio (PSTN) or Telegram (MTProto 1:1 call). Use this any time the user asks to 'call', 'ring', 'phone', 'dial', or have a spoken conversation. Do NOT use messages.send when the user asks to call someone — a call is real-time voice, not a text message. You conduct the conversation as the voice agent using the provided greeting and instructions.

calls_send_to_meet

Dispatch a workspace AI agent into an active Google Meet call. The agent joins as a participant — it can hear the conversation, respond via TTS, see the shared screen (when vision is enabled on the agent), and answer questions about what's on screen. Use when the operator wants to delegate live meeting attendance to an agent (notes, Q&A, summarization, real-time support). The Meet URL must be in canonical 3-4-3 form, e.g. https://meet.google.com/abc-defg-hij. Lookup-redirect URLs are not supported — operator must use the share-link form.

present_tab

Share the agent's browser tab on the live call so everyone sees it as a real screen-share. Pass the page_id you got from browser.open. Only usable while the agent is in an active voice call. The shared tab stays the active share until you call present_tab with a different page_id, close the tab via browser.close, or the call ends.

calls_send_to_telegram_call

Dispatch a workspace AI agent into a live Telegram GROUP voice chat OR an encrypted call-link conference. FOUR ways to target the call: (1) chat_id — the group's numeric id, e.g. -1001234567890 (use for a private group with no @username); (2) target=@username or a t.me/<group> link; (3) omit both target and chat_id to use the CURRENT thread (when it's a Telegram group); (4) target=t.me/call/<slug> encrypted group-call link. start_if_none=true spawns a new voice chat if the group has none active. The agent joins via the workspace's Telegram account — hears the call, replies via TTS, and sees shared screens (when vision is enabled). NOTE: joining a regular in-group voice chat does NOT need a slug link — pass chat_id directly.

calls_list_active

List active voice calls in this workspace. Use before calls.make on a Telegram account (only one MTProto call per account at a time) to check whether the line is free.

calls_get_transcript

Get the structured transcript and final state of a voice call by call_id. Returns per-turn rows in chronological order, call status (active/completed/failed/abandoned), duration, and an `outcome` field telling whether the recipient picked up (answered/no_answer/busy/declined/failed/unknown). `answered_at` is non-null once the recipient picked up. Returns active turns if the call is still in progress.

calls_list_history

Search historical voice calls in this workspace by participant name, contact_id, thread, channel, source, and/or date range. Returns one row per call (NOT per turn) with call_id, duration_seconds, outcome, direction, started_at, source, channel_label, and parent_thread_id (the originating chat thread for Telegram-group / Twilio-outbound / Meet calls). Pair with calls.get_transcript(call_id) for the full per-turn transcript. Use this instead of messages.read_history for cross-thread call queries — group calls and Meet sessions live on per-call sub-threads, not on the parent chat thread.

calls_wait

Block until a voice call ends (status changes from 'active') or timeout elapses. Returns ended=true with final state when the call has ended; ended=false on timeout (re-issue to keep waiting). The returned state includes `outcome` so callers can branch on pickup vs. no-answer (answered/no_answer/busy/declined/failed/unknown). Default timeout 90s; cap 110s — bounded by nginx proxy_read_timeout 120s on /mcp.

calls_hangup

Hang up an active voice call by call_id. Use after calls.make when the agent decides to terminate before the callee does, or to abort a stuck call. Idempotent: returns success if the call is already terminal.

browser_open

Open a URL in a remote browser. Saved login cookies are auto-attached when the URL domain matches a claimed browser identity. Pass identity_name to override auto-matching or force a specific identity.

browser_snapshot

Return a YAML aria_snapshot of the page DOM. Each interactive node is tagged with `[ref=eN]` (e.g. `[ref=e7]`). Pass that exact token as the `ref` arg to browser.click / browser.fill / browser.type / browser.press_key. Do NOT pass the role name ('combobox', 'button') as ref — only the eN token. Truncated at 32KB.

browser_click

Click an element. `ref` is either an aria-ref token from browser.snapshot ('e7') OR a CSS selector ('button.submit'). Prefer the aria-ref token.

browser_fill

Fill an input or textarea with the given value. `ref` is either an aria-ref token from browser.snapshot ('e7') OR a CSS selector ('input[name=email]'). Prefer the aria-ref token — it's stable and matches exactly what snapshot returned.

browser_wait_for

Wait for a selector to appear OR a navigation URL to match a glob pattern. Provide `ref` (selector) OR `url_pattern` (glob).

browser_attach_identity

Switch the page's identity by loading saved cookies + storage. Use only when switching identity mid-page; for first navigation, pass `identity_name` to browser.open instead.

browser_close

Close a page opened by browser.open.

browser_hover

Hover the mouse over an element (reveals tooltips + hover menus). `ref` is a CSS selector.

browser_select_option

Pick option(s) in a native <select> dropdown. Pass `value` (matches the option's value attr) OR `label` (matches its visible text). Lists allowed for multi-select.

browser_press_key

Press a keyboard key (e.g., 'Enter', 'Tab', 'Escape', 'ArrowDown') or a single character. Optional `ref` focuses an element first — aria-ref token from browser.snapshot ('e7') or a CSS selector.

browser_navigate_back

Navigate back in the page's history (browser back button). Returns the new URL + title.

browser_take_screenshot

Capture a PNG screenshot of the page or a specific element. Returns base64-encoded image bytes AND a file_id (persisted in DialogBrain files storage). Pass file_id straight to messages.send(attachment_file_ids=[file_id]) — do NOT call files.upload again. Use sparingly — favor browser.snapshot for structured DOM understanding.

browser_tabs

Manage tabs within the same BrowserContext as `page_id`. `action` ∈ {list, switch, close, new}. For list, returns all open tab metadata; for new, returns the new tab's page_id.

browser_evaluate

Run JavaScript in the page context and return the result. Use for state not in the a11y tree, captcha iframe inspection, DOM events. Expression is either a plain JS value ('document.title') or a zero-arg IIFE ('(() => { … })()'). Inline any runtime values into the expression itself. Result is JSON-serialized; non-serializable values become strings. 256KB cap on output.

browser_drag

Drag one element onto another. `source_ref` is the element to grab; `target_ref` is where to drop. Both are CSS selectors. Used for slider captchas, kanban, drag-and-drop uploads.

browser_type

Type text into an element with per-keystroke delay (organic). Each character dispatches keydown/keypress/keyup, unlike browser.fill which replaces .value instantly. Use when the page listens to keystroke events or for typing-speed fingerprint checks. `ref` is an aria-ref token from browser.snapshot ('e7') or a CSS selector. `delay_ms` defaults to 50.

browser_fill_form

Fill multiple form fields in one call. `fields` is a list of {ref, value} dicts. ref is a CSS selector; value is a string (text) or boolean (checkbox). Saves N round-trips vs calling browser.fill repeatedly.

browser_resize

Resize the page viewport. Useful when a site serves different HTML based on viewport width (mobile vs desktop) or when an anti-bot scores risk by viewport dimensions.

browser_file_upload

Attach files to an <input type=file>. Pass either `local_paths` (absolute host paths) or `data` (list of {name, mime, base64} blobs written to /tmp). 25MB cap per file.

browser_handle_dialog

Respond to a pending JS dialog (alert/confirm/prompt). Pass accept=true for OK or false for Cancel. For prompt() dialogs also pass prompt_text. Dialogs are queued at page-open time; returns {pending: false} if none is waiting.

browser_console_messages

Return console.log/warn/error events captured since the last drain. Filter by level ('log'|'info'|'warning'|'error'|'debug') and/or pattern (regex). Buffer caps at 500 entries; oldest are dropped first. Set clear=false to peek without draining.

browser_network_requests

List HTTP requests the page made since open or last drain. Optional filters: method (GET/POST/...), url_pattern (regex), status_min (e.g. 400 for errors). Captures up to 200 most recent requests per page.

Customize tools

Customize Tools

Edit descriptions, modify arguments, select tools, or add new ones

ReviewEdit descriptions
ConfigureChange arguments
ApproveSelect tools
Create NewAdd tool

Set Up Your Dialogbrain MCP Server in Minutes

Add the following configuration to your MCP client. Authentication is handled via OAuth. Compatible with Claude Desktop, Claude Code, Cursor, ChatGPT, VS Code, n8n, and any MCP-compatible agent.

Claude Desktop

claude_desktop_config.json
{
  "mcpServers": {
    "willow-dialogbrain": {
      "type": "http",
      "url": "https://<org>.mcp-s.com/mcp/mcp/dialogbrain"
    }
  }
}

Cursor

.cursor/mcp.json
{
  "mcpServers": {
    "willow-dialogbrain": {
      "type": "http",
      "url": "https://<org>.mcp-s.com/mcp/mcp/dialogbrain"
    }
  }
}

Claude Code

CLI
claude mcp add willow-dialogbrain --transport http https://<org>.mcp-s.com/mcp/mcp/dialogbrain

n8n

HTTP Request Node
{
  "url": "https://<org>.mcp-s.com/mcp/mcp/dialogbrain",
  "method": "POST"
}

Or click "Install with Willow" above to set up automatically with SSO and RBAC preconfigured.

Enterprise Governance for Dialogbrain

Willow adds the layer Dialogbrain and every other SaaS doesn't ship out of the box: every call runs behind SSO (Okta, Azure AD), enforces RBAC and least-privilege at runtime, writes to full audit logs, and detects shadow AI usage across your stack. One MCP gateway. Any agent. Every tool.

Dialogbrain MCP Server FAQ

What is the Dialogbrain MCP server?

The Dialogbrain MCP server is a Model Context Protocol implementation that lets AI agents like Claude, Cursor, and ChatGPT read and write Dialogbrain data through a standardized interface. Willow hosts and governs this server so enterprises can roll it out without a security review backlog.

How is Willow's Dialogbrain MCP server different from the official one?

The official Dialogbrain MCP server is scoped to a single user's account and does not include enterprise governance. Willow's version adds SSO, RBAC, audit logging, shadow AI detection, and centralized control over which actions agents can take across the entire org.

Which AI clients work with the Dialogbrain MCP server?

Claude Desktop, Claude Code, Cursor, ChatGPT, VS Code with MCP support, n8n, and any custom agent built with OpenAI Agents SDK, LangChain, Vercel AI SDK, or Anthropic SDK.

Is the Dialogbrain MCP server secure? How does Willow handle authentication?

Every call runs behind your existing SSO (Okta, Azure AD). Per-user OAuth scopes the agent to exactly what that user can do in Dialogbrain, nothing more. No credentials reach the LLM. Every action writes to an audit trail.

Can I limit which Dialogbrain actions agents can take?

Yes. Willow lets you scope agents to specific actions, specific projects, or specific environments. Toggle actions on or off in the dashboard, or enforce policy via infrastructure-as-code through GitHub.

How do I detect shadow Dialogbrain MCP servers in my org?

Willow's browser extension and discovery service surface unmanaged MCP servers, skills, and AI agents across the org. If a developer installed an unapproved Dialogbrain MCP locally, you'll see it.

What does the Dialogbrain MCP server cost?

Pricing depends on org size and deployment model (SaaS, dedicated cloud, self-host). See withwillow.ai/pricing or contact sales for a quote.

How do I install the Dialogbrain MCP server with Willow?

Install via the Willow Connect Panel in one click, or paste the JSON snippet above into your Claude Desktop, Cursor, or Claude Code config. SSO and RBAC inherit from your existing Willow setup.

Compare Willow MCP Gateway

See how Willow stacks up against other MCP platforms on governance, security, and enterprise readiness.

Your agents are already in the wild.

Give them a Basecamp. Go from AI chaos to AI work, in minutes.