Skip to content

Boardroom Revenue Control

by boardroomgen-ai-ae · remote · no sign-in to list tools · v1.0.0 · published by GitHub user boardroomgen-ai-ae

Read-only sales CRM for AI clients: leads, pipeline, AI-agent chats, calls, ad attribution.

Changes · 7

13 tools: 7 change things and 6 only read.

Scanned Oct 21, 2026

3 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http boro-ai https://control.boardroom-ai.ae/mcp --header 'Authorization: <your-authorization>'

Findings

Matches of fixed checks, with the text they matched.

2 warn1 info
  • The server marks "crm_leads_without_task" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "open": a word for a change.

    What this check looks for
  • The server marks "voice_calls" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "voice_calls" says "call": a word for a change.

    What this check looks for
  • The description mentions "credential".

    Matched text

    description: "...e whole is a separate, narrower ask. No credential of any kind is reachable from here: an..."

    What this check looks for

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

13 tools

Changes things 7Claude Code: ask
  • ad_attributionWhich advertisement produced which conversation: ad id, creative, first-touch flag, and the lead it bound to.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Which advertisement produced which conversation: ad id, creative, first-touch flag, and the lead it bound to. The per-click id is NOT returned — only whether one exists. An empty result means no ad-driven conversation has been recorded in the window, not that the tool failed. [scope: marketing:read]

    Annotations the server declares

    • title: Ad attribution
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • agent_configHow the AI agent is set up for this workspace: mode and persona, working hours, hand-over rules, follow-up cadence, trigger list, actions, voice scenarios, and the TITLES of its kn…1 finding

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Info

      The description mentions "credential".

      Matched text

      description: "...e whole is a separate, narrower ask. No credential of any kind is reachable from here: an..."

      What this check looks for
    Description, as the server wrote it
    How the AI agent is set up for this workspace: mode and persona, working hours, hand-over rules, follow-up cadence, trigger list, actions, voice scenarios, and the TITLES of its knowledge documents. Document text is not returned — the list answers what the agent knows about; reading one whole is a separate, narrower ask. No credential of any kind is reachable from here: an agent's instructions are not its keys. [scope: agent:read]

    Annotations the server declares

    • title: AI-agent configuration
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • agent_conversationsConversations the AI agent handled, with intent, language, message count and the deal they bound to.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Conversations the AI agent handled, with intent, language, message count and the deal they bound to. Contacts masked. [scope: agent:read]

    Annotations the server declares

    • title: AI-agent conversations
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • crm_leads_without_taskOpen leads with no unfinished task against them — the follow-up leak.1 finding

    Why it is in this group

    • The description's first verb is "open": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "crm_leads_without_task" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "open": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Open leads with no unfinished task against them — the follow-up leak. Sorted by idle time, longest first. Idle days are counted in Asia/Dubai. [scope: crm:read]

    Annotations the server declares

    • title: Leads without a follow-up task
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • crm_pipeline_overviewEvery pipeline and stage with its lead count and total value.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Every pipeline and stage with its lead count and total value. The shape of the funnel. [scope: crm:read]

    Annotations the server declares

    • title: Pipeline overview
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • partner_overviewThis partner's own cabinet: referral code and link, the clients who registered through it, the agreed commission rate, what has accrued so far, and which client workspaces this par…No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    This partner's own cabinet: referral code and link, the clients who registered through it, the agreed commission rate, what has accrued so far, and which client workspaces this partner currently holds a grant for. Only answers for a token bound to a partner. [scope: partner:read]

    Annotations the server declares

    • title: Partner overview
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • voice_callsCalls with direction, disposition and talk time.1 finding

    Why it is in this group

    • The name "voice_calls" says "call": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "voice_calls" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}; The name "voice_calls" says "call": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Calls with direction, disposition and talk time. Customer numbers masked. [scope: crm:read]

    Annotations the server declares

    • title: Voice calls
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
Only reads 6Claude Code: allow
  • agent_get_conversationOne conversation with its transcript — what the customer wrote and what the agent answered.No findings

    Why it is in this group

    • The name "agent_get_conversation" says "get": a word for reading.
    Description, as the server wrote it
    One conversation with its transcript — what the customer wrote and what the agent answered. [scope: agent:read]

    Annotations the server declares

    • title: One conversation transcript
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • crm_get_leadOne lead — notes, events, stage history and open tasks.No findings

    Why it is in this group

    • The name "crm_get_lead" says "get": a word for reading.
    Description, as the server wrote it
    One lead — notes, events, stage history and open tasks. Phone, e-mail and messenger ids are MASKED unless this key also holds crm:read_pii, which the workspace owner grants separately. Scoped to this workspace: a lead id from elsewhere reads as not_found. [scope: crm:read]

    Annotations the server declares

    • title: Get one lead
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • crm_list_leadsLeads in this workspace, newest activity first.No findings

    Why it is in this group

    • The name "crm_list_leads" says "list": a word for reading.
    Description, as the server wrote it
    Leads in this workspace, newest activity first. Phone and email are MASKED here — use crm_get_lead for one record when the full contact is genuinely needed. `total` is the count before paging, so it answers 'how many leads exist'. [scope: crm:read]

    Annotations the server declares

    • title: List leads
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • dashboard_snapshotThe workspace's own KPI contract as the dashboard renders it, with the time it was built.No findings

    Why it is in this group

    • The name "dashboard_snapshot" says "snapshot": a word for reading.
    Description, as the server wrote it
    The workspace's own KPI contract as the dashboard renders it, with the time it was built. [scope: crm:read]

    Annotations the server declares

    • title: Dashboard snapshot
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • marketing_snapshotAdvertising performance: spend, reach, clicks, cost per lead, per campaign, plus the CRM join.No findings

    Why it is in this group

    • The name "marketing_snapshot" says "snapshot": a word for reading.
    Description, as the server wrote it
    Advertising performance: spend, reach, clicks, cost per lead, per campaign, plus the CRM join. [scope: marketing:read]

    Annotations the server declares

    • title: Marketing snapshot
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • whoamiWho this token is, which workspace it can read, and which scopes it carries.No findings

    Why it is in this group

    • The name "whoami" says "whoami": a word for reading.
    Description, as the server wrote it
    Who this token is, which workspace it can read, and which scopes it carries. Call this first: it tells you which of the other tools will work.

    Annotations the server declares

    • title: Who am I (token and workspace)
    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Install

Pinned to version 1.0.0. Values in angle brackets are yours to fill in.

claude mcp add --transport http boro-ai https://control.boardroom-ai.ae/mcp --header 'Authorization: <your-authorization>'

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__boro-ai__whoami",
      "mcp__boro-ai__crm_list_leads",
      "mcp__boro-ai__crm_get_lead",
      "mcp__boro-ai__agent_get_conversation",
      "mcp__boro-ai__dashboard_snapshot",
      "mcp__boro-ai__marketing_snapshot"
    ],
    "ask": [
      "mcp__boro-ai__crm_pipeline_overview",
      "mcp__boro-ai__crm_leads_without_task",
      "mcp__boro-ai__ad_attribution",
      "mcp__boro-ai__agent_conversations",
      "mcp__boro-ai__agent_config",
      "mcp__boro-ai__partner_overview",
      "mcp__boro-ai__voice_calls"
    ],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as boro-ai. Review it before you use it.