Skip to content

The Claude connector (MCP)

Business Studio ships a remote Model Context Protocol server. Add it to Claude as a custom connector and Claude works your board directly: files cards, reads what’s on them, edits them, drafts social and blog posts against your connected channels — and publishes them when you ask.

Everything is scoped to your account. Claude signs in as you, so it sees your cards and nobody else’s; another user’s card id reads back as “Card not found”, which is also what a genuinely missing id returns.

  1. Copy your connector URL from the dashboard: Settings → Integrations → Claude & ChatGPT. It is your API origin plus /api/mcp — on the hosted platform, https://platform-api.viite.ai/api/mcp.
  2. In Claude: Settings → Connectors → Add custom connector, paste the URL.
  3. Claude sends you through a Business Studio login and consent screen. Approve it, and the card in the dashboard flips to Connected.

There is nothing to configure on our side — no client id, no secret to paste. Authorization is OAuth 2.0 with Dynamic Client Registration: Claude discovers the auth server from the /.well-known/oauth-* routes and registers itself. The access token it receives is bound to your user, and every tool call is scoped to it.

ToolWhat it does
list_tasksRead your cards, newest-updated first. Filter by status or by kind (task, user-story, page, post, link, email, deal, contact, company, custom). Each row reports its kind and, for posts and links, its inner status — e.g. draft.
get_taskRead one card in full: its description, for a page its markdown document, and for a post the published body, excerpt and destination that list_tasks leaves out. This is how Claude sees what a draft actually says before rewriting it.
create_taskFile a card in To-do. Optional description, priority, tags, image, and kind — and, for a page, its markdown body.
update_taskEdit a card — title, priority, tags, due date, start date (where its bar begins on the Gantt view; not on a post, link or email), and its text (description for a plain card, body for a page or a post, excerpt for a blog post) — and/or move it. One exception: a support ticket cannot be renamed, because its title is the requester’s own subject and the same words open the thread; everything else about a ticket is editable. This is also how Claude publishes (see below).
merge_cardsFold 2–20 To-do cards (tasks, user stories, custom cards) into one new To-do card: a short generated title, the descriptions joined in the order given, the highest priority, the earliest due date and every tag. The originals are archived, not deleted. Same rules as the board’s Merge button.
list_destinationsThe channels you’ve connected (X, LinkedIn, Facebook, Instagram, Reddit, the blog) with each one’s format rules: title required?, maximum body length, excerpt and image support. Instagram requires an image.
create_postDraft a post — one card per destination, so one body can be cross-posted. Refuses to write anything if the body breaks a destination’s rules (over 280 characters for X, say).
upload_assetUpload image bytes and get a public URL back, for an image that isn’t already online. PNG, JPEG, WebP, GIF, AVIF; the format is read from the bytes, not from what the caller claims.
create_tracked_linkMint a tracked link and get one ready-to-share URL per channel, so you can tell where a post’s traffic came from.
get_funnel_reportRead visits → signups → paid per traffic source, plus signups by viite.ai CTA placement and by onboarding playbook. Requires the analytics feature; Claude is told to rank on signup rate, not visit count.
search_contactsFind a person by email, phone, company or name — colleagues’ contacts included, not just yours.
log_activityLog a call, note, meeting or email onto a contact, company or deal’s timeline.
link_recordsRecord a typed relationship between two CRM cards — a contact at a company, a contact on a deal, a shareholder, an adviser, a member, a partner. get_task also lists a card’s attached documents (titles and links only).
state_factRecord a fact you told Claude about a contact or company — or about yourself (me) and your own company (my-company). Personal and banking facts (IBAN, VAT and registration numbers, legal name, addresses, date of birth, personal phone) stay private to you; get_task with me / my-company reads them back (“what is my company’s IBAN?”).
rememberPropose something for viite’s agent NEO to remember about you — “remember I want LinkedIn posts in French”, or what Claude already remembers about you. It lands as a suggestion in your daily Review; nothing is kept until you accept it in viite.

update_task’s status argument speaks each card’s own vocabulary — the same one its status selector offers in the dashboard:

  • a task, user-story, page, deal or custom card moves on the board spine: todo → in_progress → done → archived;
  • a post moves on draft → reviewed → archived;
  • a link moves on captured → enriched → failed → archived, and separately accepts a board-spine value to change which column it sits in.

A value the card can’t take comes back listing the ones it can, so Claude corrects itself rather than guessing twice. Statuses owned by a worker — a post’s posting — are never settable: taking that lock without doing the work would leave a post that never publishes.

Every move Claude makes is written on the card’s timeline, signed with the name the client registered under (“Moved from todo to in_progress by Claude”). The board tile and the card show Moved by Claude · 2m ago. When Claude marks one of your cards done, you get a push notification on every device where you turned notifications on. When Claude moves a card to in_progress and then writes nothing on it for 4 hours, the card shows up under Needs attention until something changes: Claude moves it again or writes on it.

A page is a markdown document on the board — the dashboard opens it in a calm, Typora-like editor that renders headings, lists, task boxes, tables, images and fenced code as you write. create_task with entity: "page" files one: the title names it and body carries the document in markdown. update_task with a body replaces the document whole, so Claude is told to get_task the page first and edit what it actually holds. The format is always markdown — there is no bodyFormat to pass — and body is refused on any other board kind, which keeps its notes in description. A page has nothing to run and never publishes; it moves on the board spine like a task.

A person is a card too. create_task with entity: "contact" files one: the title is their name, the description is the message that introduced them (paste it verbatim), the tags are how you categorise them — headhunter, investor, client — and a contact object carries what you already know (phone, email, company, role, linkedinUrl). When the lookup is free — you connected your own AI key — the card is handed to NEO, whose contact squad looks the person up on LinkedIn and fills in the rest; a field you gave is never overwritten by one it found. On the platform’s key that lookup would spend your credits, so by default the card is just filed and Claude is told to fill in what it can itself; enrich: true runs the lookup anyway, enrich: false never does. A known person (same profile, email or phone) is returned rather than duplicated.

update_task takes the same contact object to change a field (an empty string clears one), and list_tasks filters on entity: "contact". The card reads captured until the lookup lands, then enriched or failed — with the reason on the card.

A contact is the only card Claude hands to NEO. Giving NEO any other card — which can reach a coding squad acting with your GitHub token — is done by assigning it on the board, never from a conversation that may have just read an untrusted page.

An organisation is a card too. create_task with entity: "company" files one: the title is the company’s name and a company object carries what you know (domain or website, industry, size, location, linkedinUrl — the LinkedIn company page). A known company (same domain, or the same LinkedIn page) is returned rather than duplicated, for the whole organisation, not just you. Then link_records with company_of puts a contact or a deal at that company; a contact’s own company text stays a display label — the link is the relation. update_task takes the same company object, and list_tasks filters on entity: "company". The lookup follows the same rule as a contact’s: it runs by default only on your own AI key, where it is free, and enrich: true or enrich: false overrides that.

What a contact, a company and a deal are — and why they are shared with your whole organisation — is the CRM guide. This section is only the connector’s view of it.

get_task on a contact, company or deal card also returns its last 10 timeline entries and every record it’s linked to — a call logged, a note, who it’s linked with — so Claude sees the history before acting on it. log_activity adds to that timeline (a call, a note, a meeting), and link_records records a typed relationship between two cards: contact_of (belongs to a contact), company_of (a contact or deal belongs to a company), deal_contact (a deal has a contact as a party to it), blocked_by (a card cannot start before another one is done — see Blocking cards), or part_of (a card sits under one bigger card, such as a topic or a user story — see Grouping cards). search_contacts is how Claude finds the right card in the first place.

On a deal card, update_task’s deal object edits the structured fields — amount, currency, expected close date, company name — and status moves it along the sales pipeline: new → qualified → proposal → won / lost.

Claude can publish. Moving a post to reviewed arms the publish worker, so:

  • “draft a LinkedIn post about the release” → a draft card, nothing published;
  • “looks good, publish it” → update_task sets reviewed, and it goes out;
  • “…schedule it for Monday 9am” → the same call with a dueDate, and it goes out then instead.

Nothing publishes that you didn’t ask for: create_post only ever drafts, and reviewed is a separate, explicit move. You can equally review the draft on the board yourself and hit Publish now — the connector doesn’t change that path, it adds one.

Publishing to a social channel needs that channel connected first (Channels); list_destinations reports exactly what’s available, which is why Claude should call it before drafting.

Anthropic’s terms do not let a third party run requests on a Claude Pro/Max login — no app may take your Claude.ai sign-in and spend it on its own servers — so Business Studio cannot “plug in” your subscription. The connector turns that around: in Claude, your plan runs the model and Business Studio only moves the data. Nothing Claude does through these tools debits your Business Studio credits.

So the cheapest way to get AI work done on your board is to ask Claude to do it here:

  • Research my new contacts and Draft posts from my saved links are ready-made prompts in Claude’s + menu once the connector is added. Each has Claude read the cards, do the research or writing itself, and save the result with update_task / create_post.
  • Anything Business Studio runs on its own — NEO, squads, scheduled workflows, the dashboard’s Rephrase and Suggest next step — runs on your AI channel if you connected one (an API key, not a plan login), and is then free: your provider bills you, and we debit nothing. Without one it runs on the managed key and spends credits.
  • No delete. The connector cannot destroy a card. archived is the reversible equivalent, and it’s reachable through update_task.
  • create_post for posts, create_task for everything else. A post needs a destination and its own lane status; create_task deliberately refuses to stamp entity: 'post' on a card the publish worker could never route.
  • A page’s document is body too — markdown, replaced whole on every update.
  • A post’s text is body, not description. description is the card’s internal summary, which nothing publishes — so update_task refuses it on a post rather than writing it and reporting success, and the error names body (or excerpt, for the blog). Rewriting a draft is update_task with a body, and it is held to the same length rules as create_post: an edit that pushes an X post past 280 characters is refused, not saved to fail at publish time. A body replaces the old one, so Claude is told to get_task the card first and edit what it actually holds — rather than retyping the draft from memory, which is how a stale version gets published.
  • Blog posts need your website in Channels. A blog post is written for your organization’s own website, so create_post to the blog and update_task on a blog post are both refused until a website channel (post://blog@<your-domain>) is connected. The dashboard’s Blog posts menu stays visible but disabled until then.
  • Tags replace, they don’t merge. Passing tags overwrites the card’s set.
  • One org. Tools act in your active organization.