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

# MCP connector for Claude, Cursor, and AI apps

> Connect Claude, Cursor, or any MCP client to your Dench workspace: sign in with OAuth, pick a workspace and permissions, and use CRM, task, inbox, and campaign tools.

Dench is the AI revenue engine and CRM. The Dench MCP connector brings your
workspace into the AI apps you already use. Claude, Cursor, or any MCP client
can then do what the [Dench CLI](/docs/cli/overview) does: read and update your
CRM, views, analytics, comments, tasks, meetings, and files, read your inbox,
campaigns, and memory, search the web and Dench's people and company data,
and run actions in the apps you connected to Dench.

<Note>
  Server URL: `https://mcp.dench.com/mcp`. You sign in with OAuth, choose one
  workspace, and approve the permissions the app gets. Connected-app actions
  that aren't read-only wait for your approval in Dench before they run.
</Note>

## Connect

<Tabs>
  <Tab title="Claude">
    <Steps>
      <Step title="Add the connector">
        If Dench is listed in Claude's connector directory, open it and click
        **Connect**. Otherwise, open **Settings → Connectors**, choose
        **Add custom connector**, and enter:

        ```text theme={null}
        https://mcp.dench.com/mcp
        ```

        On Team and Enterprise plans, an owner may need to add the connector
        for the organization first.
      </Step>

      <Step title="Sign in and approve">
        Claude opens Dench in your browser. Sign in, choose a workspace and
        permissions, and click **Approve**. See
        [Sign in and choose a workspace](#sign-in-and-choose-a-workspace).
      </Step>

      <Step title="Use it">
        Turn Dench on for a chat, then ask something like "What are my open
        tasks in Dench?"
      </Step>
    </Steps>

    For Claude Code, add the server, then run `/mcp` and choose `dench` to
    sign in:

    ```bash theme={null}
    claude mcp add --transport http dench https://mcp.dench.com/mcp
    ```
  </Tab>

  <Tab title="Cursor">
    Add Dench to `~/.cursor/mcp.json` for all projects, or to
    `.cursor/mcp.json` in one project:

    ```json theme={null}
    {
      "mcpServers": {
        "dench": {
          "url": "https://mcp.dench.com/mcp"
        }
      }
    }
    ```

    Cursor's MCP settings then show that `dench` needs sign-in. Start it
    there, and Cursor opens Dench in your browser to approve the connection.
  </Tab>

  <Tab title="Other clients">
    Any client that supports remote MCP servers over Streamable HTTP with
    OAuth can connect. Most take a JSON config like this:

    ```json theme={null}
    {
      "mcpServers": {
        "dench": {
          "type": "http",
          "url": "https://mcp.dench.com/mcp"
        }
      }
    }
    ```

    Key names vary by client (some use `servers` or `serverUrl`), so check
    your client's docs. If your client only runs local (stdio) servers,
    bridge to Dench with `mcp-remote`:

    ```json theme={null}
    {
      "mcpServers": {
        "dench": {
          "command": "npx",
          "args": ["-y", "mcp-remote", "https://mcp.dench.com/mcp"]
        }
      }
    }
    ```
  </Tab>
</Tabs>

<Info>
  Clients sign in with the OAuth authorization-code flow and PKCE (S256).
  Dench supports dynamic client registration and client ID metadata
  documents, and publishes discovery metadata at
  `https://mcp.dench.com/.well-known/oauth-protected-resource/mcp`. The server
  only accepts access tokens issued through this flow. Dench API keys and
  `dench signin` sessions don't work here; use them with the
  [CLI](/docs/cli/overview) or [API](/docs/api/overview).
</Info>

## Sign in and choose a workspace

When you connect, your AI app opens Dench in your browser.

<Steps>
  <Step title="Sign in to Dench">
    Click **Continue with Google**, or enter your email and type the 6-digit
    code Dench sends you. If you're already signed in, you skip this step.
  </Step>

  <Step title="Choose a workspace">
    Pick one workspace from the list of every workspace you belong to. The
    one you're currently in is selected. The app works only in that
    workspace and acts as you.
  </Step>

  <Step title="Choose permissions and approve">
    Review the app's name and where it redirects. Apps that Dench hasn't
    verified are marked **unverified**. Tick the permissions you want to
    grant, then click **Approve**. You return to your AI app, connected.
  </Step>
</Steps>

To use another workspace or change permissions, disconnect and connect
again.

## Permissions

The consent screen lists four permissions. The app only sees the tools for
the permissions you approve, and Dench checks them again on every call.

| Permission | On the consent screen | What it allows |
| - | - | - |
| **Read your workspace** | Always included | Workspace context and rules, CRM records, views, analytics, history, comments, and tasks, meetings, members, notifications, files, saved lists, Dench chats, routines, memory, inbox and campaign reads, and approvals. |
| **Create and update workspace data** | Optional | Create and edit CRM records, objects, fields, views, statuses, and analytics, add notes and comments, manage tasks, meetings, files, saved lists, and routines, start Dench chats, save memories, edit workspace rules and agent context, and request approvals. |
| **Act in your connected apps** | Optional | Connect apps and find and run actions, as you, in the apps you connected to Dench, such as sending an email or posting to Slack. Also web search and Dench's people, company, and job data, which use credits. |
| **Manage and send outreach** | Optional, always starts unticked | Create and edit campaigns, email campaigns, sequences, and drafts, add recipients, launch and resume campaigns, and send email. See [Outreach permission](#outreach-permission). |

For a read-only connection, untick **Create and update workspace data** and
**Act in your connected apps**.

## Tools

The connector offers the same actions as the [Dench CLI](/docs/cli/overview):
both run the same Dench operations, and a check in Dench's build fails when
a CLI command has no MCP tool and no recorded reason for leaving it out.
With the first three permissions it offers 235 tools; the
[outreach permission](#outreach-permission) adds 60 more. In the
**Permission** column, Read, Write, and Connected apps stand for
**Read your workspace**, **Create and update workspace data**, and
**Act in your connected apps**.

No tool can approve or reject a request. Signing in, billing, saved setups
and secrets, and approving or rejecting stay with the CLI and the app.
Deletes have their own tools ([Deletes](#deletes)), which AI apps mark as
destructive.

### CRM records

| Tool | Permission | What it does |
| - | - | - |
| `list_records` | Read | List an object's records, newest first: a bounded preview of up to 200 that local cursors page. |
| `search_records` | Read | Search records by text, optionally within one object, best match first: an exact or phrase title match ranks above matches elsewhere, and records matching only some words of the query are left out when others match them all. |
| `query_records` | Read | Filter an object's records by field (`$eq`, `$gte`, `$in`, `$contains`, `$and`, `$or`, and more) and choose which fields to return. Results page in index order; sorting isn't supported. Each call keeps reading until it has `limit` matches or reaches the end. `assigned_to` scopes it to one person's records. |
| `find_records` | Read | Run a sorted query over an object: filters, selected fields, sort (e.g. "-Score,Name"; - is descending) and up to 200 rows. `query` narrows it to records whose text holds every word of the query. |
| `get_record` | Read | Read one record, optionally with its current Brief. |
| `get_record_field` | Read | Read one field of one record in full (long text and file values included). |
| `aggregate_records` | Read | Count an object's records by the values of one field, optionally totalling a number field per bucket (e.g. Amount by Stage). |
| `generate_report` | Read | Build a chart-ready report: records grouped by one field with a count, sum, average, minimum or maximum. |
| `create_record` | Write | Create a record with field values that match the object's fields. |
| `create_records` | Write | Create up to 200 records in one object in a single call. |
| `update_record` | Write | Update fields on a record. `null` clears a field. |
| `update_records` | Write | Update up to 200 records of one object in a single call; each update names a record and the fields to change. |
| `batch_records` | Write | Apply up to 200 record creates and updates across objects together. |
| `set_record_field` | Write | Set one field of one record, or with append: true add to it (text is appended, list values are added) instead of replacing it. |
| `set_record_fields` | Write | Set up to 200 individual fields across any records in one call. |
| `enrich_field` | Write | Fill an enrichment field (e.g. a work email or company size) from Dench's data providers: for one record with entry\_id, or for every record of the object (missing\_only skips records that already have a value). |
| `list_detections` | Read | List what Dench decided about people and companies it saw in email and LinkedIn: records created, skipped, or failed. |

Field names in record data must match the object's fields (`list_fields`);
Dench also accepts common aliases in any case, such as `name` for a task's
title field and `Owner` for its `Assignee`, exactly as the CLI does.
`query_records` pages through a whole object in index order; `find_records`
sorts and returns up to 200 rows; `list_records` previews the newest 200
and says `truncated: true` when there are older records.
`assigned_to` (`me`, `unassigned`, or a member) scopes a read to one
person's records without changing any view. Tools that take an
`object_name` also accept it as `object` (for example `"people"`,
`"company"`, or a label such as `"Contacts"`), tools that take a record's
`entry_id` also accept it as `record_id`, and campaign tools accept
`sequence_id` for `sequenceId`.

`list_records`, `query_records`, and `get_record` leave empty fields out of
each record, so a field you don't see has no value. An id that isn't a
record of that object, including a malformed one, answers `not_found`.

### Objects, fields, and statuses

| Tool | Permission | What it does |
| - | - | - |
| `list_objects` | Read | List the workspace's CRM objects, such as people, companies, and custom objects. `full: true` returns each object's whole definition. |
| `get_object` | Read | Read one object's settings: description, icon, default view, who can see its records, record count, and saved views. |
| `create_object` | Write | Create an object (a table) and up to 30 fields in one call. The object and its fields are created together or not at all. |
| `update_object` | Write | Change an object's description, icon, default view, or who can see its records. Changing who can see records needs your approval. |
| `rename_object` | Write | Rename a CRM object. |
| `archive_object` | Write | Archive a CRM object (hide it from the sidebar, keeping every record) or restore it with archived: false. |
| `set_object_visibility` | Write | Change who can see an object's records: workspace (every member), owner\_only, or owner\_plus\_members (the owner plus members listed on the record). |
| `list_fields` | Read | List an object's fields and their constraints. `full: true` adds enrichment, calculation, and index settings. |
| `create_field` | Write | Add a field to an object: text, rich text, number, true/false, date, email, phone, URL, select, multi-select, tags, workspace member, file, or a relation to another object. |
| `update_field` | Write | Rename a field, change its description or whether it's required, or add options to a select field. |
| `update_field_options` | Write | Change a select field's options: rename one (records holding it move to the new name), recolor one, or put them in a new order (an exact permutation). |
| `reorder_fields` | Write | Set the column order of an object's fields. |
| `list_statuses` | Read | List an object's status options with colors and order. |
| `set_statuses` | Write | Add or update an object's statuses by name (color, order, which one is the default). |
| `list_crm_templates` | Read | List CRM templates (ready-made objects, fields and views, e.g. sales or recruiting) and which are installed. |
| `install_crm_template` | Write | Install a CRM template: adds its objects, fields, views and sample records to the workspace. |
| `list_crm_automations` | Read | List the workspace's built-in CRM automations (what each does when a record changes) and whether each is on. |
| `set_crm_automation_enabled` | Write | Turn one CRM automation on or off. |

For example, ask "Create a Content table in Dench with Name, Type, Channel,
and Status selects, a Publish date, a Link, and Notes." The app calls
`create_object` with one entry per field:

```json theme={null}
{
  "name": "content",
  "fields": [
    { "name": "Name", "type": "text" },
    { "name": "Type", "type": "select", "options": ["Blog post", "Video", "Podcast"] },
    { "name": "Channel", "type": "select", "options": ["Website", "LinkedIn", "YouTube"] },
    { "name": "Status", "type": "select", "options": ["Idea", "Drafting", "Published"] },
    { "name": "Publish date", "type": "date" },
    { "name": "Link", "type": "url" },
    { "name": "Notes", "type": "text" }
  ]
}
```

* Every object already has a rich-text **Notes** field, so a requested Notes
  text field is reported as existing rather than created twice.
* Dench creates the object and its fields together. If any field is
  rejected, such as a relation to an object that doesn't exist, nothing is
  created and the error names the field, so the app can fix it and call
  again.
* `update_field` only adds select options; `update_field_options` renames,
  recolors, or reorders them. No tool removes an option, a field, or an
  object.
* Changing who can see an object's records is for workspace admins.
  Narrowing an object to its owners hides every record without an owner from
  everyone. `set_object_visibility` waits for your approval in Dench before
  it narrows, and `update_object` waits for it before any visibility change.

### Views and sidebar

| Tool | Permission | What it does |
| - | - | - |
| `list_views` | Read | List an object's saved views (filters, sort, columns). |
| `get_view` | Read | Read one saved view's definition. |
| `list_view_records` | Read | Read the records a saved view shows, with its filters and sort applied, one numbered page at a time (25 rows unless `page_size` or `limit` says otherwise). |
| `create_view` | Write | Save a view on an object: name, view type, filters, sort, columns and settings. |
| `update_view` | Write | Replace a saved view's definition (filters, sort, columns, settings). |
| `rename_view` | Write | Rename a saved view. |
| `archive_view` | Write | Archive a saved view (hide it from the view list) or restore it with archived: false. |
| `get_sidebar` | Read | Read your sidebar: objects and pages in order, groups, and pins, with the nav ids update\_sidebar takes. |
| `update_sidebar` | Write | Arrange your sidebar: move an item (position top, bottom, or a 1-based row), create or rename a group, put an item in a group (group\_id null takes it out), or pin an item to the top level. |

### Analytics

| Tool | Permission | What it does |
| - | - | - |
| `get_analytics` | Read | Read an object's dashboard: its panels, field roles (amount, stage, close date, owner) and layout. |
| `compute_analytics` | Read | Compute dashboard numbers: saved panels by panel\_ids, or ad-hoc panels (type, metric, groupBy, dateField, ...), over a period, with extra filters and a personal assigned\_to scope. |
| `save_analytics_panel` | Write | Add a dashboard panel, or replace the one with this panel\_id, e.g. a stat of open pipeline or a bar chart of deals by stage. |
| `update_analytics_panel` | Write | Change one dashboard panel: a patch of its settings, hidden to hide or show it, or span to resize it (2, 3, 4 or 6 columns; null resets). |
| `reorder_analytics_panels` | Write | Set the order of a dashboard's panels. |
| `set_analytics_roles` | Write | Tell the dashboard which fields mean what: amount, stage, won/lost/converted values, close date, owner, location, recurrence, stage probabilities. |
| `set_analytics_collapsed` | Write | Collapse the dashboard strip above an object's table, or expand it with collapsed: false. |
| `set_view_analytics_scope` | Write | Give a saved view its own dashboard (own) or show the object's shared one (shared). |

### Record details, comments, and notes

| Tool | Permission | What it does |
| - | - | - |
| `list_record_activity` | Read | Read a record's activity timeline, newest or oldest first, filtered by kind or time. `count_only: true` counts it instead. |
| `list_record_history` | Read | List the field changes made to a record, newest first, with who made each. |
| `get_record_details` | Read | Read one part of what Dench knows about a record: brief (the AI summary), dossier (researched background), context (what the agent sees and why), privacy (whether your messages with it are hidden), email\_sync (email history import status), or watch (whether you follow it). |
| `regenerate_record_summary` | Write | Have Dench rewrite a record's brief (the AI summary of its activity) or dossier (researched background) now. |
| `set_record_privacy` | Write | Hide (hidden: true) or show your own emails and messages with this record to the workspace. |
| `sync_record_email_history` | Write | Import past email with this record's addresses from connected mailboxes. |
| `watch_record` | Write | Follow a record to be notified of its comments and changes, or stop with watching: false. |
| `list_record_notes` | Read | List the titled notes on a record. |
| `add_note` | Write | Add a titled Markdown note to a record. |
| `list_record_comments` | Read | List the comment threads on a record, newest first, each with a preview of its replies. |
| `list_comment_replies` | Read | List every reply in one comment thread. |
| `get_comment` | Read | Read one comment with its reactions. |
| `add_comment` | Write | Comment on a record, or reply in a thread with reply\_to. |
| `update_comment` | Write | Edit the text of a comment you wrote. |
| `react_to_comment` | Write | Add an emoji reaction to a comment; reacting again with the same emoji removes it. |
| `list_documents` | Read | List workspace documents and the records they are linked to. |
| `create_document` | Write | Create a document page backed by a workspace file (write the file first with write\_file), optionally nested under another document or linked to a record. |
| `link_document` | Write | Link a workspace file as a document on a record or object. |
| `list_record_actions` | Read | List the action buttons available on a record, with the action\_id and field\_id run\_record\_action takes. |
| `run_record_action` | Write | Press an action button on up to 50 records. |

### Tasks and subtasks

| Tool | Permission | What it does |
| - | - | - |
| `list_tasks` | Read | List open tasks assigned to you, up to 50. |
| `list_record_tasks` | Read | List the tasks linked to a CRM record, open and done. |
| `create_task` | Write | Create a task linked to a record, with an optional assignee, due date, and priority. |
| `complete_task` | Write | Mark a task complete. |
| `reopen_task` | Write | Reopen a completed task. |
| `set_task_priority` | Write | Set or clear a task's priority. |
| `create_subtask` | Write | Add a subtask to a task, with an optional assignee and due date. |
| `list_subtasks` | Read | List a task's subtasks. |
| `set_task_parent` | Write | Make a task a subtask of another task, or a top-level task again with parent\_entry\_id null. |
| `get_task_repeat` | Read | Read how a task repeats: its rule, what triggers the next one, when it ends, and the next due dates. |
| `set_task_repeat` | Write | Make a task repeat (daily, weekly, monthly, yearly, or an RRULE), or turn a repeat off, skip the next occurrence, pause it, or resume it. |
| `list_task_series` | Read | List repeating task series (filter by status), or with series\_id the tasks one series has created. |

### Meetings

A meeting is private to its owner and invitees until it is shared with the
workspace. Create and update the meeting record itself with the record
tools.

| Tool | Permission | What it does |
| - | - | - |
| `list_meetings` | Read | List the meetings you can read, newest first, with status and participants. |
| `get_meeting_transcript` | Read | Read a meeting's transcript in order (speaker, time, text), one page at a time. |
| `get_meeting_details` | Read | Read a meeting's action\_items, participants (the roster with linked CRM people), or sharing (who can read it). |
| `add_meeting_transcript` | Write | Append up to 500 transcript segments (text, with optional speaker and times) to a meeting. |
| `add_meeting_action_items` | Write | Add action items to a meeting; replace: true swaps out the existing list instead. |
| `set_meeting_action_item_done` | Write | Mark a meeting action item done, or not done. |
| `set_meeting_participants` | Write | Add people (name, email, host) to a meeting's roster, linking them to CRM people; replace: true swaps out the existing roster. |
| `set_meeting_sharing` | Write | Share a meeting (record, transcript, action items, roster) with every workspace member, or make it private to its owner and invitees again with shared: false. |

### Members, notifications, and settings

| Tool | Permission | What it does |
| - | - | - |
| `list_members` | Read | List the workspace's members with their user ids, names, emails and roles. |
| `get_member` | Read | Read a member's profile: name, role, tagline, time zone. |
| `list_member_activity` | Read | List what a member has done recently: comments they wrote and record changes they made. |
| `list_member_tasks` | Read | List a member's open tasks, soonest due first. |
| `get_member_presence` | Read | Who is online and what they are looking at; pass user\_ids to ask about particular members. |
| `get_my_profile` | Read | Read the connected user's own profile in this workspace: name, tagline, time zone, avatar, presence and open-task count. |
| `update_my_profile` | Write | Change the connected user's name, tagline or time zone (IANA, e.g. America/New\_York; null clears it). |
| `list_notifications` | Read | List the connected user's notifications: inbox (default), unread, archived or all — mentions, assignments, replies and record activity they follow. |
| `count_unread_notifications` | Read | How many unread notifications the connected user has. |
| `mark_notifications_read` | Write | Mark one notification read (unread: true marks it unread again), or every inbox notification read with all: true. |
| `archive_notification` | Write | Move a notification out of the inbox into the archive. |
| `get_notification_preferences` | Read | Read the connected user's notification settings: in-app and email, per kind, digest window and daily email cap. |
| `update_notification_preferences` | Write | Change notification settings; only the keys sent change. |
| `get_sync_settings` | Read | Read the workspace's Sync switches: what Dench does on its own with email, calendar, Slack and LinkedIn (accounts from email, LinkedIn contacts, Slack Connect, calendar contacts, dossiers, tasks from email, lead auto-qualify, summaries and Brief). |
| `update_sync_settings` | Write | Turn Sync switches on or off (workspace admins only). |

### Files and saved lists

| Tool | Permission | What it does |
| - | - | - |
| `list_files` | Read | List the files and folders under a workspace folder. |
| `read_file` | Read | Read a text file from the workspace, with the contentHash write\_file takes to avoid overwriting someone else's change. |
| `get_file_download_url` | Read | Get a short-lived download link for a workspace file (any type, e.g. an image or PDF). |
| `write_file` | Write | Create or replace a text file (UTF-8, up to 400 KB). |
| `upload_files` | Write | Write up to 20 files at once, each as text or base64 bytes (for images, PDFs and other binary files). |
| `move_file` | Write | Move or rename a workspace file or folder. |
| `create_folder` | Write | Create a folder in the workspace files. |
| `list_saved_lists` | Read | List the saved lists of people, companies and jobs from Find; search filters by title. |
| `get_saved_list` | Read | Read a saved list: title, kind, filters and row counts. An id that names no saved list answers `not_found`. |
| `list_saved_list_rows` | Read | Read a saved list's rows, filtered by contact enrichment state, one page at a time. |
| `save_list` | Write | Save people, companies or jobs (whole records from find\_people / find\_companies / find\_jobs) as a list. |
| `update_saved_list` | Write | Rename a saved list or replace its filters or rows. An id that names no saved list answers `not_found`. |
| `import_saved_list` | Write | Add a saved list's rows to the CRM as lead, company or job\_posting records (all rows, chosen row\_indexes, or by enrichment state), optionally with a status and a pinned view. |
| `enrich_saved_list` | Write | Buy contact details (work email, phone, personal email) for up to 100 rows of a saved list. |
| `list_prospect_reviews` | Read | List the fit assessments recorded for a saved list's rows against the workspace's ideal customer. |
| `assess_prospect` | Write | Record a fit assessment for one row of a saved list: likely\_fit, unlikely\_fit or unknown, a 0-100 relevance score, and the reason. |

### Dench chats, routines, and apps

`start_chat` hands a task to Dench's own agent; it never skips Dench's
approvals. Chats and routine runs use AI credits.

| Tool | Permission | What it does |
| - | - | - |
| `list_chats` | Read | List the connected user's Dench chat threads, newest first; title\_query filters by title. |
| `search_chats` | Read | Full-text search across the connected user's past Dench chats. |
| `read_chat` | Read | Read the messages of one Dench chat thread as you saw them, without the assistant's internal reasoning or tool calls. |
| `start_chat` | Write | Hand a task to Dench's own agent in a new chat. |
| `send_chat_message` | Write | Send a follow-up message in a Dench chat; the agent continues in the background. |
| `rename_chats` | Write | Retitle up to 50 Dench chat threads. |
| `set_chat_model` | Write | Set the model Dench chats use: the workspace default, or with thread\_id one chat's override. |
| `list_routines` | Read | List routines: Dench agent prompts that run on a schedule, a webhook, or a CRM change. Each comes back as a summary unless `full: true`. |
| `get_routine` | Read | Read one routine: prompt, schedule, trigger and status. An id that names no routine answers `not_found`. |
| `list_routine_runs` | Read | List recent runs of one routine (job\_id), or of every routine in the workspace. |
| `create_routine` | Write | Create a routine that runs a Dench agent prompt every interval, on a cron schedule, or once at a set time. With `enabled: false` it starts paused, with no next run, until `set_routine_enabled` turns it on. |
| `update_routine` | Write | Change a routine's name, prompt, schedule, description or overlap policy. An id that names no routine answers `not_found`. |
| `set_routine_enabled` | Write | Turn a routine on or off. |
| `run_routine` | Write | Run a routine once now, outside its schedule. An id that names no routine answers `not_found`. |
| `list_artifacts` | Read | List what Dench agents produced in this workspace (reports, lists, files) and suggested follow-up work. |
| `list_apps` | Read | List the Dench apps installed in this workspace. |
| `list_app_gallery` | Read | List the apps available to install, with the listing ids install\_app takes. |
| `install_app` | Write | Install an app from the gallery into this workspace. |
| `set_app_enabled` | Write | Turn an installed app on or off. |
| `pin_app` | Write | Pin an installed app to the sidebar, or unpin it. |

### Workspace context, rules, and memory

| Tool | Permission | What it does |
| - | - | - |
| `get_workspace_context` | Read | Get a compact orientation to the workspace. |
| `get_workspace_rules` | Read | Read the workspace's standing rules. |
| `set_workspace_rules` | Write | Replace the workspace's standing rules. |
| `get_context_sections` | Read | Read the workspace's agent profile: identity, organisation, user, memory, rules and tools notes (all, or the sections named). |
| `update_context_section` | Write | Replace one section of the agent profile: identity (who the agent is), organisation (the company), user (the connected user) or tools (notes on how to use tools). |
| `search_memory` | Read | Search the memories visible to you. |
| `save_memory` | Write | Save a durable fact, preference, decision, or other memory, for you or for the whole workspace. |

### Approval requests

| Tool | Permission | What it does |
| - | - | - |
| `list_approvals` | Read | List the workspace's approval requests, optionally by status (pending, approved, rejected, or canceled). |
| `get_approval` | Read | Read one approval request. |
| `request_approval` | Write | Ask a person to approve something, with a title, reason, and risk level (low, medium, or high). |

### Connected apps

| Tool | Permission | What it does |
| - | - | - |
| `list_connected_apps` | Connected apps | List the apps connected to your Dench workspace. |
| `search_actions` | Connected apps | Find the actions those apps offer, optionally within one app. |
| `run_action` | Connected apps | Run an action by its slug. Read-only actions run directly; everything else needs your approval. See [Approval flow](#approval-flow). |
| `connect_app` | Connected apps | Start connecting an external app (e.g. github, gmail, hubspot, linkedin) to the workspace. |
| `disconnect_app` | Connected apps | Disconnect a connected app account (connection\_id from list\_connected\_apps). |
| `list_connection_labels` | Connected apps | List the names given to connected app accounts (e.g. Work Gmail, Personal Gmail). |
| `set_connection_label` | Connected apps | Name a connected app account so it can be told apart from others of the same app; an empty name clears it. |

`connect_app` returns a link: you open it and sign in to the app before the
connection exists. `disconnect_app` waits for your approval in Dench.

### Web, people, and company data

These reach outside Dench and use credits, like the same CLI commands. They
change nothing in your workspace; save results with `save_list` or the
record tools.

| Tool | Permission | What it does |
| - | - | - |
| `web_search` | Connected apps | Search the web. |
| `web_fetch` | Connected apps | Read the text of up to 10 web pages, optionally with a summary focused on a question. |
| `web_answer` | Connected apps | Answer a question from a live web search, with citations; output\_schema shapes the answer as JSON. |
| `web_lookup` | Connected apps | Read structured data from a website. |
| `find_people` | Connected apps | Search Dench's people data by title, seniority, company, location, industry and more (accepted values: [https://dench.com/references/find-filter-options.json](https://dench.com/references/find-filter-options.json)). |
| `find_companies` | Connected apps | Search Dench's company data by domain, name, industry, location, headcount and keywords. |
| `find_jobs` | Connected apps | Search open job postings by title, location, company and posting date. |
| `preview_find` | Connected apps | Count how many people, companies or jobs a Find search would return, with a sample, before paying for the full search. |
| `enrich_person` | Connected apps | Look up one person's full profile by LinkedIn URL, LinkedIn id or email. |
| `enrich_company` | Connected apps | Look up one company's full profile by website, LinkedIn URL or LinkedIn id. |
| `lookup_profiles` | Connected apps | Look up to 100 people (by LinkedIn URL or email) or companies (by domain or LinkedIn URL) at once, in input order. |
| `find_contact_details` | Connected apps | Buy work emails and phone numbers for people (each contact by linkedinUrl, or name plus company). |
| `list_company_related` | Connected apps | List a company's employees, founders, funding rounds, investors, acquisitions or investments, by domain or LinkedIn URL. |
| `campaigns_audience_search` | Connected apps | Search for people to add to a campaign (titles, locations, industries, ...; not-filters leave values out). |

### Campaigns

These tools only read. With the first three permissions, an AI app can't
create, edit, launch, pause, or resume a campaign.

| Tool | Permission | What it does |
| - | - | - |
| `campaigns_list` | Read | List up to 200 campaigns, optionally including archived ones, with how many archived ones were left out. |
| `campaigns_get` | Read | Read a campaign and its steps. |
| `campaigns_analytics` | Read | Read a campaign's analytics. |
| `campaigns_events` | Read | Page through a campaign's events. |
| `campaigns_live` | Read | Read a campaign's current sender and activity status. |
| `campaigns_launch_preview` | Read | Check whether a campaign is ready to launch. It doesn't launch anything. |
| `campaigns_accounts_linkedin` | Read | List the LinkedIn sender accounts available to campaigns. |
| `campaigns_accounts_email` | Read | List the email mailboxes the user may send campaigns from (their own plus teammates' shared ones), with ids for sender pools. |
| `campaigns_pipeline` | Read | Count a campaign's people by lead status (contacted, replied, interested, ...). |
| `campaigns_queue` | Read | Read who a campaign contacts today, on which step. |
| `campaigns_preview` | Read | Show the exact message one person gets at a step, with their personalization filled in. |
| `campaigns_sources` | Read | Read a signal campaign's lead sources: settings (targeting, signals, cadence, approval mode), signals (what each signal found), overview (counts), or pending (people waiting for the user's review). |
| `campaigns_personalization_get` | Read | Read a campaign's AI-written personalization lines and how many people have them. |
| `campaigns_for_record` | Read | List the campaigns a CRM record is enrolled in, and where. |
| `campaigns_people_timeline` | Read | Read one person's campaign timeline: every step sent, scheduled or skipped, and replies. |
| `campaigns_builder_read` | Read | Read the New campaign builder: profile (the company it targets for), drafts (saved builder drafts), draft (one draft with its people), or setup (where a draft left off). |

### Email and LinkedIn

These tools only read. With the first three permissions, an AI app can't
send email through them.

| Tool | Permission | What it does |
| - | - | - |
| `list_email_threads` | Read | Page through synced email threads. |
| `list_email_messages` | Read | Page through synced email messages. |
| `list_linkedin_messages` | Read | Page through LinkedIn messages. |
| `email_inbox_search` | Read | Search the user's connected mailboxes by free text, sender, recipient, subject, date and direction, newest first. |
| `email_inbox_thread` | Read | Read one email thread from a connected mailbox, in order. |
| `email_inbox_message` | Read | Read one message from a connected mailbox as text or HTML. |
| `email_messages_list` | Read | Preview up to 100 recently sent emails with delivery status and open and click counts, optionally by status. |
| `email_message_get` | Read | Read one email with its delivery status and open and click counts, by message id, inbox handle, or `email_message` record id. |
| `email_sequences_list` | Read | List up to 200 email sequences, optionally including archived ones. |
| `email_sequence_get` | Read | Read one email sequence. |
| `email_sequence_enrollments_list` | Read | List a sequence's enrolled people and where each one is. |
| `email_identities_list` | Read | List the workspace's email sending identities, optionally by domain. |
| `email_identity_status` | Read | Check a sending identity's verification: with identityId, refresh its status (dns: true also returns the DNS records to add); with identity (domain or address), ask the provider directly. |
| `email_draft_senders` | Read | List the mailboxes the user can write drafts from. |
| `email_draft_get` | Read | Read a draft, with the revision email\_draft\_update and email\_draft\_send take. |
| `email_draft_signature` | Read | Load the sending mailbox's signature for a draft. |
| `email_template_preview` | Read | Render a template with sample values for its placeholders. |
| `email_campaigns_list` | Read | List bulk email campaigns, newest first, filtered by status. |
| `email_campaign_get` | Read | Read a bulk email campaign with its delivery counts. |
| `email_campaign_recipients_list` | Read | List a bulk email campaign's recipients and their delivery status. |
| `email_campaign_preview` | Read | Render a bulk email campaign for a sample of its recipients. |

If no inbox or LinkedIn account is connected yet, the inbox tools return an
empty page with a note instead of an error.

### Deletes

Each delete runs the same operation as the CLI's delete command and is marked
destructive, so AI apps can ask before calling it. Archive, pause or disable
instead when the data should come back.

| Tool | Permission | What it does |
| - | - | - |
| `delete_record` | Write | Permanently delete one CRM record. |
| `delete_records` | Write | Permanently delete up to 200 records of one CRM object. |
| `delete_task` | Write | Delete a task. Its subtasks are deleted too unless subtasks is keep, which makes them top-level tasks. |
| `delete_comment` | Write | Delete a comment or note; one with replies is kept as a tombstone so the thread stays readable. |
| `undo_detections` | Write | Admin: delete the records Dench's ingestion created since a time (from email, LinkedIn, or auto-created tasks). Only rows nobody has touched are deleted, and they are never re-created; `dry_run` lists what would go. |
| `delete_object` | Write | Permanently delete a CRM object with its fields, views and every record. `archive_object` hides it instead. |
| `delete_field` | Write | Permanently delete a field and the values every record holds in it. |
| `delete_field_option` | Write | Remove one option from a select field; records holding it are left empty. |
| `delete_view` | Write | Delete a saved view by name. `archive_view` hides it instead. |
| `delete_analytics_panel` | Write | Delete one analytics panel from an object or a view. |
| `delete_sidebar_group` | Write | Dissolve a sidebar group; its items return to the top level where the group was. |
| `delete_record_action` | Write | Delete an action button from its field, and optionally the field once it holds no buttons. |
| `remove_crm_template_sample_data` | Write | Delete the sample records a CRM template installed; its objects, views and automations stay. |
| `delete_meeting_action_item` | Write | Delete one action item from a meeting. |
| `clear_meeting_transcript` | Write | Delete a batch of a meeting's transcript segments; call again until done before adding a new transcript. |
| `delete_document` | Write | Delete a document page by the id `create_document` returned. Its workspace file stays and nested pages move up to its parent. An id that names no document answers `not_found`. |
| `delete_file` | Write | Delete a workspace file, or a folder with everything in it. |
| `delete_saved_list` | Write | Delete a saved list with its exported files and any watch linked to it. |
| `delete_chats` | Write | Delete up to 25 chat threads. Threads a routine started are skipped unless `include_automated` is true. |
| `delete_routine` | Write | Delete a routine and its schedule or webhook. `set_routine_enabled` pauses it instead. |
| `uninstall_app` | Write | Uninstall an app from the workspace. `set_app_enabled` turns it off instead. |
| `delete_app_webhook` | Write | Delete an app's webhook and every event it stored. |

The outreach permission adds four more: `campaigns_builder_discard`,
`campaigns_people_remove`, `email_identity_delete` and
`email_sequence_step_remove` (see [Outreach permission](#outreach-permission)).

### Search and fetch

For AI apps that use the standard `search` and `fetch` tools for company
knowledge.

| Tool | Permission | What it does |
| - | - | - |
| `search` | Read | Search CRM records and return each with a title, text, and a link to open it in Dench. |
| `fetch` | Read | Fetch the full record for an `id` that `search` returned. |

## Approval flow

Sending and other sensitive actions don't run until a person approves them
in Dench. This applies to `run_action` for any connected-app action that
isn't read-only, `run_record_action`, `disconnect_app`, changing who can see
an object's records with `update_object`, narrowing an object with
`set_object_visibility`, and the sending and launching tools under the
[outreach permission](#outreach-permission).

<Steps>
  <Step title="The app asks">
    The first call runs nothing. It returns `approval_required` with an
    `approvalId` and a link to approvals in Dench.
  </Step>

  <Step title="You decide in Dench">
    Open [Approvals](https://www.dench.com/approvals) in Dench, review which
    app asked and what it wants to do, and approve or reject it.
  </Step>

  <Step title="The app calls again">
    After you approve, the app repeats the call with the same arguments and
    the `approval_id`. The action runs once.
  </Step>
</Steps>

<Columns cols={2}>
  <Card title="Runs directly" icon="bolt">
    Connected-app actions whose slug contains `FETCH`, `GET`, `LIST`,
    `SEARCH`, `READ`, or `FIND`, and no write verb.
  </Card>

  <Card title="Needs approval" icon="shield-halved">
    Every other connected-app action, including anything that sends,
    creates, updates, or deletes, or that Dench can't classify.
  </Card>
</Columns>

* Each approval covers one call with those exact arguments, from the
  connection that asked. If the arguments change or the call fails, the app
  needs a new approval.
* AI apps can't approve their own requests. There is no tool that decides
  an approval.
* These approvals always apply to AI apps connected over MCP, even though
  the workspace runs Dench's own agents with **Full access**.

## Outreach permission

**Manage and send outreach** is off unless you tick it on the consent
screen. It always starts unticked, even when the app asks for it. With it,
the app gets 60 more tools. Their arguments keep the API's own names, such
as `sequenceId` and `emailMailboxAccountIds`.

| Tool | What it does | Approval |
| - | - | - |
| `campaigns_create` | Create a campaign draft. | Not needed |
| `campaigns_update` | Update a campaign's settings. | Not needed |
| `campaigns_steps_replace` | Replace a campaign's full list of steps. | Not needed |
| `campaigns_people_add_from_crm` | Add CRM records to a campaign. | Required |
| `campaigns_people_add` | Add one person to a campaign. | Required |
| `campaigns_launch` | Launch a campaign, using the fingerprint from `campaigns_launch_preview`. | Required |
| `campaigns_pause` | Pause a running campaign. | Not needed |
| `campaigns_resume` | Resume a paused campaign. | Required |
| `email_send` | Send an email from a connected identity. | Required |
| `campaigns_draft_create` | Create a plain campaign draft with its sender pools. | Not needed |
| `campaigns_people_add_from_search` | Run an audience search and add the people found to a campaign. | Required |
| `campaigns_people_add_batch` | Add up to 50 people (email and/or LinkedIn URL, name, personalization) to a campaign, creating CRM records for new ones. | Required |
| `campaigns_sources_update` | Change a campaign's lead sources: targeting, signals and their terms, cadence, find-more-matching, status (active/paused) and approval mode (auto adds found people without review). | To activate sources or auto-approve |
| `campaigns_sources_preview` | Preview the people one signal (with its terms) would find for a campaign, without adding anyone. | Not needed |
| `campaigns_sources_run` | Search a campaign's sources now instead of waiting for its cadence. | Required |
| `campaigns_duplicate` | Copy a campaign's steps, schedule and senders into a new draft with no people (e.g. for the next 300 people of a search). | Not needed |
| `campaigns_steps_update` | Change the text and waits of a launched campaign's steps in place (each step by stepId with its expectedUpdatedAt); step types and order are kept. | Unless the campaign is paused |
| `campaigns_personalization_set` | Define up to 5 AI-written lines a campaign's steps use as placeholders, or remove them. | Not needed |
| `campaigns_personalization_write` | Have AI write the personalization lines for a campaign's people: the missing ones, or all. | Not needed |
| `campaigns_personalization_edit` | Set one person's personalization line by hand. | Not needed |
| `campaigns_personalization_rewrite` | Have AI rewrite one person's personalization lines (or just one key). | Not needed |
| `campaigns_archive` | Archive a campaign; it stops and leaves the campaign list. | Not needed |
| `campaigns_people_stop` | Stop contacting one person in a campaign. | Not needed |
| `campaigns_people_remove` | Remove a person who was never contacted from a draft campaign (delete). | Not needed |
| `campaigns_people_resume` | Resume a paused or stopped person in a campaign; outreach to them restarts. | Required |
| `campaigns_people_resume_all` | Resume every paused person in a campaign; outreach to them restarts. | Required |
| `campaigns_people_update` | Correct one person in a campaign: their email, their LinkedIn URL, or one merge field. | Not needed |
| `campaigns_people_sync` | Refresh a campaign's people from their CRM records (emails, LinkedIn URLs, merge fields). | Not needed |
| `campaigns_builder_save` | Save a signal or lookalike campaign draft: targeting, signals and their terms, source and step. | Not needed |
| `campaigns_builder_discard` | Delete a builder draft that never became a campaign. | Not needed |
| `campaigns_builder_assist` | Builder helpers: find people like a best customer, suggest LinkedIn voices to watch, draft targeting from a description, or estimate audience size and weekly volume. | Not needed |
| `campaigns_builder_build` | Find the first people for a builder draft from its targeting and signals. | Not needed |
| `campaigns_builder_sequence` | Have AI write a builder draft's sequence and openers from a brief (goal, what you help with, tone, channels). | Not needed |
| `campaigns_builder_outreach` | Save a builder draft's outreach: AI or manual mode, brief, steps, senders and approval mode. | Not needed |
| `campaigns_builder_opener` | Change the opening line written for one person in a builder draft. | Not needed |
| `campaigns_builder_create` | Turn a builder draft into a campaign. | Unless created paused |
| `email_identity_create` | Add a sending identity: a whole domain (type domain) or one address (type email). | Not needed |
| `email_identity_verify` | Start verifying a sending identity: with identityId, send the verification for a saved identity; with type and identity (a domain or address), request verification directly. | Not needed |
| `email_identity_set_enabled` | Stop sending from an identity (enabled: false) or restore it. | Not needed |
| `email_identity_delete` | Permanently delete a sender, or every sender on a domain; adding it back needs verification from scratch. | Not needed |
| `email_draft_create` | Write a draft in one of the user's connected mailboxes (to, cc, bcc, subject, body). | Not needed |
| `email_draft_update` | Change a draft's recipients, subject, body, attachments or mailbox; expectedRevision refuses the change if the draft moved on. | Not needed |
| `email_draft_attach` | Attach a file (base64) to a draft. | Not needed |
| `email_draft_send` | Send a draft from the user's mailbox. | Required |
| `email_native_send` | Send an email from one of the user's connected mailboxes (Gmail, Outlook) in one step. | Required |
| `email_template_create` | Save an email template with placeholders for bulk email campaigns. | Not needed |
| `email_campaign_create` | Create a bulk email campaign draft from a template and a sender. | Not needed |
| `email_campaign_recipients_add` | Add recipients to a bulk email campaign: a recipients list, or objectName with entryIds to pick CRM records. | Required |
| `email_campaign_submit` | Submit a bulk email campaign: it sends now, or at its scheduled time. | Required |
| `email_campaign_set_state` | Pause a sending campaign, resume a paused one (sending restarts), or cancel it for good. | To resume |
| `email_sequence_create` | Create an email sequence (a multi-step follow-up cadence) from a verified identity or connected mailboxes. | Not needed |
| `email_sequence_update` | Change a sequence's name, sender, reply and stop settings, sending window, schedule or daily cap. | Not needed |
| `email_sequence_set_active` | Turn a sequence on (it starts emailing its enrolled people) or off. | To activate |
| `email_sequence_archive` | Archive a sequence; it stops sending and leaves the list. | Not needed |
| `email_sequence_step_add` | Add an email step to a sequence, sent delayHours after the previous one. | Not needed |
| `email_sequence_step_update` | Change an email step's subject, body or delay. | Not needed |
| `email_sequence_step_remove` | Remove a step from an email sequence (delete). | Not needed |
| `email_sequence_steps_reorder` | Put a sequence's steps in a new order (every step id). | Not needed |
| `email_sequence_enroll` | Enroll people in a sequence: a recipients list (email, name, personalization), or objectName with entryIds to pick CRM records. | Required |
| `email_sequence_enrollment_set_state` | Pause, resume (emails restart) or stop one person's sequence. | To resume |

<Warning>
  Adding people to a campaign that is already running starts outreach to
  them right away.
</Warning>

Approval is in addition to Dench's usual checks. Sending still enforces
sender ownership and suppression rules. Launching still needs a current
readiness fingerprint and, when required, your acknowledgement of the
LinkedIn risk.

## Disconnect

In Dench, open **Settings → API keys**. Under **Connected AI apps**, click
**Disconnect** next to the app to revoke its access. Removing the connector
in your AI app stops that app from calling Dench, but only disconnecting in
Dench revokes the connection itself.

## Limits

* A list tool returns at most 50 items per page. `limit` takes 1 to 50
  (20 if you leave it out); any other value, such as `0` or `-5`, answers
  `validation_failed` instead of being reduced. Pass the returned
  `nextCursor`, unchanged, as `cursor` to get the next page; a cursor the
  tool didn't hand out answers `invalid_cursor`. A few tools page their own
  way: `list_view_records` by page number, and the web and data tools by the
  page token they return.
* Every tool that takes a `cursor` returns its rows as `items`, with
  `nextCursor` beside them (`null` on the last page), plus any fields of its
  own such as `total` or `message`. The one exception is `search`, which
  returns `results` as AI apps' company-knowledge search expects. Tools that
  used to return `continueCursor` and `isDone` still do, for older clients:
  `continueCursor` equals `nextCursor`, and `isDone` is true when
  `nextCursor` is `null`. Rows that used to come back as `page` now come
  back as `items`.
* Each tool call has 25 seconds. If a write runs out of time, it returns
  `outcome_unknown` because it may still finish. Check the result before
  trying again.
* Each connection can make 300 requests and 60 writes per minute.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Join a workspace before connecting an AI app" icon="user-slash">
    Your Dench account isn't a member of any workspace yet. Create or join
    one at [dench.com](https://dench.com/login), then connect again.
  </Accordion>

  <Accordion title="insufficient_scope" icon="lock">
    The tool needs a permission you didn't grant. Disconnect, connect again,
    and tick that permission on the consent screen.
  </Accordion>

  <Accordion title="approval_required" icon="shield-halved">
    Approve the request in [Approvals](https://www.dench.com/approvals), then
    let the app call again with the `approval_id` it was given.
  </Accordion>

  <Accordion title="validation_failed" icon="triangle-exclamation">
    An argument doesn't match the tool's schema, such as a `limit` above 50,
    or a required argument is missing (`job_id: Required`). The error names
    each argument to fix and why, all in one answer, and nothing runs until
    they're fixed. Dench never quietly changes the value.
  </Accordion>

  <Accordion title="invalid_cursor" icon="arrow-rotate-left">
    The `cursor` isn't one this tool handed out: it was edited, cut short,
    or came from another tool. Pass `nextCursor` from the tool's previous
    page exactly as returned, or leave `cursor` out to start from the first
    page.
  </Accordion>

  <Accordion title="not_found for an id" icon="magnifying-glass">
    The id doesn't name anything in this workspace: it was mistyped, the
    item was deleted, or it belongs to another workspace. `get_record`,
    `get_routine`, `list_routine_runs`, `update_routine`, `run_routine`,
    `get_saved_list`, `update_saved_list` and `delete_document` answer
    `not_found` for it, and the writes change nothing. List the items again,
    for example with `list_routines`, `list_saved_lists` or `list_documents`,
    and use an id from the result.
  </Accordion>

  <Accordion title="Object not found" icon="table">
    The error lists every object in the workspace, starting with `people`,
    `company`, and `task`, with display labels in brackets.
    `availableObjects` holds the same list. Call again with one of those
    names as `object_name`.
  </Accordion>

  <Accordion title="Inbox tools return an empty page" icon="inbox">
    No email inbox or LinkedIn account is connected to the workspace. Connect
    one in Dench. See [Integrations](/docs/integrations).
  </Accordion>
</AccordionGroup>

## Support and privacy

For help, email [support@dench.com](mailto:support@dench.com). To learn how
Dench handles your data, read the
[privacy policy](https://www.dench.com/privacy).


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