Skip to content

Fin Operator tools

Part of the Intercom MCP server

The Fin Operator tools are part of the Intercom MCP server at https://mcp.intercom.com/mcp. Connect your client by following the Intercom MCP setup steps.

Operator is Fin's internal AI agent. The Fin Operator tools let an AI client ask Operator to do work inside your Fin workspace and read the answers back, without you moving between the two products.

What it does

Your client asks Operator something in plain language, Operator does the work, and hands back the answer plus any changes it suggests. Operator already knows your workspace, so you can:

  • Ask why Fin missed resolutions over a period
  • Investigate a specific conversation
  • Ask Operator to propose configuration changes

Proposed changes are reviewed and applied from the client, without leaving it.

Reviewing proposals

Proposals are not applied until apply_proposals is called. Review each one with get_proposal_details before you apply it — some changes cannot be undone.

How it works

Operator turns run asynchronously: a request returns as soon as Operator accepts the work, and the client collects the answer with a later call.

When a client calls a tool:

  1. The client is connected to the Intercom MCP server over OAuth, with the Use Fin Operator permission
  2. We check that the workspace has Fin Operator and that the teammate has permission to use Operator
  3. The tool runs as that teammate, inside that workspace
  4. Answers, and any proposed changes, are returned to the client

Available tools

There are 5 Fin Operator tools.


send_operator_message

Send a message to Operator.

Returns as soon as Operator accepts the turn — it does not wait for the answer. The turn keeps running in Intercom; collect the answer with get_operator_response using the chat_id from the response. Once a turn has been accepted, never re-send the same message to retry.

Parameters:

  • message: the message to send to Operator. Send either message or answers, not both.
  • answers: your answers to Operator's clarifying questions, when get_operator_response returned needs_input. An object keyed by each question's index, with the option text as the value — an array of option texts for a multi_select question. Answer every question. Text that matches no option reaches Operator as your own words. Requires chat_id.
  • chat_id: continue an existing conversation. Omit to start a new chat. Use one chat per topic.

Status in the response envelope:

  • working: Operator accepted the turn and is running it. Turns normally take one to three minutes.
  • error: the error text opens with a code (rate_limited, chat_busy, usage_limit, invalid_answers, no_pending_question, …) when the turn definitively never started. A bare error: means the turn may have started anyway — check the chat in Intercom via chat_url before retrying.

get_operator_response

Read the latest response from an Operator chat. Never starts new work and never waits — it returns the chat's current state immediately.

Parameters:

  • chat_id (required): the chat to read, which is the UUID at the end of an Operator chat URL

Status in the response envelope:

  • complete: the latest turn finished; answer_text and tool_outputs are final
  • working: the turn is still running — check again shortly
  • needs_input: Operator asked the questions in clarifying_questions and is waiting for an answer. Put them to the user, then send the answers with send_operator_message.
  • needs_approval_in_ui: Operator is waiting for teammate input or confirmation in Intercom (open chat_url to respond)
  • error: the turn failed — check the chat in Intercom via chat_url rather than calling again

Proposals are returned only once the turn is known to have stopped writing. Until then proposals is empty and proposals_withheld is true: an empty array does not mean the turn proposed nothing.

Each entry in clarifying_questions has an index, the question, its options, and multi_select. follow_up_suggestions lists next steps Operator suggests after it replies; to take one, send its text as the message. Both are also written into the text response, for clients that show only text.


get_proposal_details

Show what each pending proposal would change, plus anything blocking it. Read-only, and costs no Operator credits.

For every proposal the response gives what it is, what applying and rejecting would do, and the entity's complete file as Operator reads it, in two fields: before (the file now) and after (the file once the proposal is applied). The client compares the two itself; the server does not render a diff. A deletion has after set to null; a creation of guidance or content (a snippet, article or internal article) has before set to null and after holding the content it would add, since the entity has no file yet. For other creations, or when an entity's file does not reflect pending edits, both fields are null and files_show_change is false; the text response then gives a link to review the proposal in Intercom instead.

Parameters:

  • chat_id (required): the chat whose proposals to describe
  • proposal_ids: proposals to describe. Omit to describe every pending proposal on the chat.

The response is filled in order until it reaches its size limit (about 1 MB). Proposals after that point still carry their details, but before and after are null and they are flagged content_omitted: true; the text response links to review them in Intercom. A chat with more than 50 pending proposals is described 50 at a time, and the response names the rest so they can be asked for by proposal_ids.


apply_proposals

Apply Operator proposals to the workspace's live configuration. This creates, updates or deletes real objects, and some of it cannot be undone. It runs the same code path as the Apply button in Intercom.

Parameters:

  • chat_id (required): the chat whose proposals to apply
  • proposals (required): up to 5 proposals per call, each with:
    • proposal_id (required): from the response envelope's proposals array
    • apply_mode: one of apply, draft, release, publish, destroy. Omit to apply in the proposal's default_apply_mode — a new entity lands as a draft, and an edit keeps the entity's publication state. Set it only when a human explicitly chose a mode, and only to a mode listed in that proposal's supported_apply_modes.

reject_proposals

Discard proposals. Nothing in the workspace changes.

Parameters:

  • chat_id (required): the chat whose proposals to reject
  • proposal_ids (required): up to 20 proposal IDs per call

Tool annotations

The Fin Operator tools are published with MCP tool annotations — hints that tell the client how careful it should be with a tool, before it ever calls it. Claude uses them to decide what it can run freely, what it should confirm with you, and what to show you first.

Tool Read‑onlyDestructiveIdempotentOpen‑world
send_operator_messagefalsetruefalsetrue
get_operator_responsetruefalsetruefalse
get_proposal_detailstruefalsetruefalse
apply_proposalsfalsetruefalsetrue
reject_proposalsfalsefalsefalsefalse

The columns are the readOnlyHint, destructiveHint, idempotentHint and openWorldHint fields of each tool's annotations.

What the hints are saying:

  • get_operator_response and get_proposal_details are read-only and idempotent. Calling them again has no additional effect, so Claude can reach for them without asking you. This is deliberate: it makes showing you a change cheaper than applying it. Idempotent does not mean the answer is fixed — get_operator_response reports the chat's current state, so the status and proposals do change as a turn progresses.
  • apply_proposals is destructive and open-world. It writes to live workspace configuration and some of it cannot be undone, so clients that gate on destructiveHint will ask you to confirm before it runs. Treat a client that applies without asking as misconfigured.
  • send_operator_message is also marked destructive and open-world. It does not write configuration itself, but it starts an Operator turn that acts on your workspace and consumes Operator usage, so it is not a free retry. The openWorldHint is what tells the client the effect reaches outside its own state.
  • reject_proposals is neither read-only nor destructive. Discarding a suggestion changes nothing in the workspace, so it needs no confirmation, but it is not read-only either — the proposal is gone afterwards.

readOnlyHint and destructiveHint are separate on purpose: applying a change and discarding one are different decisions, which is why the two are separate tools rather than one tool with a flag.

Annotations are hints, not enforcement. The authorization described in How permissions work is what actually decides whether a call is allowed.

A typical workflow

1. Ask Operator something

{
  "name": "send_operator_message",
  "arguments": {
    "message": "Why did Fin's resolution rate drop last week?"
  }
}

The response carries status: "working" and a chat_id.

2. Collect the answer

{
  "name": "get_operator_response",
  "arguments": { "chat_id": "b0c1d2e3-..." }
}

Turns normally take one to three minutes, so do not call this back-to-back. While the status is working, do something else and check again — repeated immediate calls are rate limited.

3. Answer Operator's questions

When the status is needs_input, Operator needs a decision before it continues:

"clarifying_questions": [
  {
    "index": 0,
    "question": "Which approach do you want for changing how Fin handles refund requests?",
    "options": ["Guidance", "Content", "Procedure", "Data connector"],
    "multi_select": false
  }
]

Ask the user, then send their choice back on the same chat:

{
  "name": "send_operator_message",
  "arguments": {
    "chat_id": "b0c1d2e3-...",
    "answers": { "0": "Guidance" }
  }
}

Operator receives the exact option, the same as when it is picked in Intercom. Collect the rest of the turn with get_operator_response.

4. Review anything Operator proposed

{
  "name": "get_proposal_details",
  "arguments": { "chat_id": "b0c1d2e3-..." }
}

Each proposal comes back with its before and after file; Claude compares them and tells you what changes.

5. Apply or reject

Once a human has reviewed a specific proposal and confirmed it:

{
  "name": "apply_proposals",
  "arguments": {
    "chat_id": "b0c1d2e3-...",
    "proposals": [{ "proposal_id": "p_123" }]
  }
}

Quote numbers and data from tool_outputs verbatim rather than re-deriving them.

How permissions work

Teammate-level permissions apply through the MCP in exactly the same way they do for Operator in the product. Any teammate who can use Operator in Intercom can use it through the MCP too: there is nothing extra to grant them and no seat upgrade involved.

The Fin Operator tools appear in a client only when all of the following are true:

  • The workspace has Fin Operator
  • The connection was made over OAuth by a teammate — the tools are never available to a Bearer token
  • The teammate has the Operator access permission in that workspace
  • The connection includes the Use Fin Operator permission

The Use Fin Operator permission is granted on the Intercom MCP consent screen. It only lets the connection send work to Operator; it grants no direct access to conversation or contact data. Operator reads what it needs inside Intercom under the connecting teammate's own permissions.

Rate limits

Fin Operator tool calls are limited to 60 per minute per connection, shared across all five tools: polling get_operator_response spends the same budget as reading proposal details. Ordinary interactive use sits well below this.

A throttled call is returned as a rate limit, telling the client to slow down rather than failing opaquely. The usual cause is polling get_operator_response in a tight loop.

Operator's own usage limits also apply, and are reported as a usage_limit error code from send_operator_message.

Debugging and troubleshooting

  • The Fin Operator tools do not appear — check the workspace has Fin Operator, the teammate has Operator access, and the connection uses OAuth rather than a Bearer token.
  • A tool call asks you to reconnect — the connection was made before the Use Fin Operator permission existed. Disconnect and reconnect the Intercom MCP server, and approve the permission on the consent screen.
  • Missing permission errors — the teammate needs Operator access in that workspace, granted the same way as for Operator in the Intercom UI.
  • A turn seems stuck — open chat_url from the response and look at the chat in Intercom. Do not re-send the message.
  • Empty proposals array — check proposals_withheld. If it is true, the turn is still writing; call get_operator_response again.