Claude connector (MCP)

Tool reference · 48 tools · 22 read, 26 write

How it works

Fishladder is a remote MCP server. Add it to Claude (Settings → Connectors → Add custom connector) with this URL, then sign in to Fishladder when Claude asks:

https://app.ladder.fish/api/mcp
  • Claude acts as you. It can only do what you can do in Fishladder, and changes appear under your name. A write tool asks for your confirmation before it runs.
  • The tools offered depend on your access. Viewers get read tools only; tools for modules you can't open aren't offered at all; tools marked Admins need the admin role. So the list below is the most anyone sees.
  • HubSpot replaces the CRM. The HubSpot tools appear only when your team has HubSpot connected, and the CRM tools disappear then (the built-in CRM is switched off).
  • One team per connection. Every result names the team it read from. Use whoami, list_teams and switch_team when data looks missing.
  • Restricted boards stay restricted. Boards in project groups you can't open, and their tasks, don't appear in any result and can't be changed.
  • Results carry a url for the thing they describe, and an empty result carries a note explaining why, written to be passed on to you.

For examples of what to ask, see Using the Claude connector. Inputs marked * are required.

Team & account

list_team_membersList team membersReadEveryone

List the people on this team with their user IDs. Call this to turn a name mentioned by the user into an assigneeId or ownerId before filtering or creating anything.

No inputs.

whoamiWho this Fishladder connection is signed in asReadEveryone

Report which Fishladder account this connection is authenticated as, which team it is reading from, and what that account can do there. Use it when they ask who they are connected as, and whenever results look wrong or a team name cannot be found — the common cause is that the connector was authorized by a different account than they have in mind, and no other tool can reveal that.

No inputs.

list_teamsList your Fishladder teamsReadEveryone

List the Fishladder teams this person belongs to, and say which one this connection reads from. Use this when an answer looks wrong or empty and they expected data — the connection covers one team at a time, and they may be thinking of another. Also use it when they ask which teams they have, or before switch_team if the name they gave is ambiguous. To change team, call switch_team — it takes effect immediately, with no reconnect. If the team they want is not in this list, call whoami: the connector is probably authorized as a different account than they expect.

No inputs.

switch_teamSwitch Fishladder teamWriteEveryone

Change which Fishladder team this conversation reads from and writes to. Accepts the team name as the person would say it. Use list_teams first if you are unsure what exists, or if the name given is ambiguous. Everything after this — tasks, CRM, wiki — comes from the new team, and their role and modules there may differ.

InputTypeDescription
team*stringTeam name, or part of it. Case-insensitive.

Projects (tasks & boards)

list_tracker_projectsList tracker boardsReadEveryoneProjects

List tracker projects (task boards). Call this first when the user names a board or you need a projectId for search_tasks or create_task.

InputTypeDescription
includeArchivedbooleanInclude archived boards (default false).
limitintegerMaximum rows to return (default 50, max 200).
create_tracker_boardCreate a tracker boardWriteAdminsProjects

Create a tracker board — the columns and statuses that tasks live on. Use this when someone is starting a new piece of work and there is no board for it yet; check list_tracker_projects first so you do not make a second board for something that already has one. A board is created from a template, which decides its starting columns and statuses. Pass skipTasks true unless they want the template's example tasks as well.

InputTypeDescription
name*stringWhat the board is called.
descriptionstringWhat the board is for.
templatestringTemplate to build it from. Defaults to blank. Ask if you are unsure rather than guessing — the template decides the columns and statuses, and changing them afterwards is more work than choosing correctly.
skipTasksbooleanLeave out the template's example tasks. Defaults to true here.
search_tasksSearch tasksReadEveryoneProjects

Search tracker tasks by free text, project, assignee, or priority. Use this for any question about work items — what someone is working on, what is overdue, or whether something already exists before creating it.

InputTypeDescription
querystringFree-text match against task title and description.
projectIdstringRestrict to one tracker project (see list_tracker_projects).
assigneeIdstringRestrict to one assignee (see list_team_members).
prioritystringFilter by priority: "none", "low", "medium", "high", "urgent".
includeCompletedbooleanInclude tasks in a closed status (default false).
limitintegerMaximum rows to return (default 50, max 200).
create_taskCreate a taskWriteMembers & adminsProjects

Create a tracker task. Search first with search_tasks to avoid duplicates, and resolve the assignee with list_team_members rather than guessing an ID.

InputTypeDescription
projectId*stringTracker project to create the task in (see list_tracker_projects).
title*stringShort imperative title.
descriptionstringOptional detail, plain text.
assigneeIdstringOptional assignee user ID (see list_team_members).
prioritystringOptional priority: "none", "low", "medium", "high", "urgent".
dueDatestringOptional due date as YYYY-MM-DD.
update_taskUpdate a taskWriteMembers & adminsProjects

Update a tracker task: change its status, mark it complete or reopen it, or edit its title, description, assignee, priority or due date. Find the task with search_tasks first. Only the fields you pass are changed; everything else is left alone. To move a task to a named column, read the status IDs from search_tasks rather than guessing.

InputTypeDescription
taskId*stringTask to update (see search_tasks).
titlestringNew title.
descriptionstringNew description, plain text.
assigneeIdstringNew assignee user ID (see list_team_members).
prioritystringNew priority: "none", "low", "medium", "high", "urgent".
dueDatestringNew due date as YYYY-MM-DD.
statusIdstringMove the task to this status/column. Must belong to the same board.
completedbooleanTrue marks the task complete, false reopens it.
attach_file_to_taskAttach a file to a taskWriteMembers & adminsProjects

Attach a file to a tracker task — PNG, JPEG, GIF, WEBP or PDF — passed as base64. Use it for something you produced in this conversation, such as a chart you generated or a report you assembled. You CANNOT use it for a screenshot or image the person uploaded to the chat: you were shown that image, you do not hold its bytes, and inventing base64 would attach garbage. In that case say so plainly and give them the task link so they can drop it on the task themselves. Maximum 10MB.

InputTypeDescription
taskId*stringTask to attach to (see search_tasks).
fileName*stringFile name including its extension, for example "pipeline-chart.png".
contentBase64*stringThe file contents, base64 encoded.
contentTypestringIgnored — the format is read from the contents.

Roadmap

list_roadmap_projectsList roadmap projectsReadEveryoneRoadmap

List roadmap projects (the strategic plan: title, status, start/target dates). Use this when the user asks what is planned, in flight, or shipping — not for individual tasks.

InputTypeDescription
statusstringFilter by status, e.g. "planned", "in_progress", "completed".
limitintegerMaximum rows to return (default 50, max 200).
create_roadmap_projectCreate a roadmap projectWriteMembers & adminsRoadmap

Create an item on the roadmap — a strategic piece of work with a status and optional start and target dates. This is the plan, not the day-to-day board: use create_task for the work underneath it. Search list_roadmap_projects first so you extend the plan rather than duplicating something already on it.

InputTypeDescription
title*stringWhat the roadmap item is called.
descriptionstringWhat it covers. Plain text.
statusstringOne of: planned, in_progress, completed, on_hold, cancelled. Defaults to planned.
startDatestringStart date as YYYY-MM-DD.
targetDatestringTarget date as YYYY-MM-DD.
trackerProjectIdstringOptional tracker board to link this to, so the work underneath is reachable from the roadmap item. See list_tracker_projects.
update_roadmap_projectUpdate a roadmap projectWriteMembers & adminsRoadmap

Update a roadmap item: change its status, dates, description or title, or link it to a tracker board. Find it with list_roadmap_projects first. Only the fields you pass are changed; everything else is left alone.

InputTypeDescription
projectId*stringRoadmap item to update (see list_roadmap_projects).
titlestringNew title.
descriptionstringNew description. Replaces the existing one.
statusstringOne of: planned, in_progress, completed, on_hold, cancelled.
startDatestringStart date as YYYY-MM-DD.
targetDatestringTarget date as YYYY-MM-DD.
trackerProjectIdstringTracker board to link this to. See list_tracker_projects.

Calendar

list_calendarList what is dueReadEveryoneCalendar

List what is due or scheduled in a time frame, across the whole workspace: task due dates, roadmap project target dates, deal expected-close dates, quote expirations, interviews, security questionnaire due dates, audit milestones and calendar events. Use this for any "what is due / coming up / deadlines / what did we miss" question, optionally narrowed to named projects. Finished work is left out unless asked for.

InputTypeDescription
daysintegerHow many days from today to cover (default 14). Negative looks back, e.g. -7 for the past week.
startstringStart date as YYYY-MM-DD. Use with end or days instead of the default "from today".
endstringInclusive end date as YYYY-MM-DD. Maximum range is 400 days.
typesstring[]Limit to these kinds of item. task = task due dates, roadmap = project target dates, crm_close = deal close dates, cpq_expiry = quote expirations, interview, ts_due = questionnaires, milestone = audit milestones, event = calendar events. Default: all.
projectsstring[]Project names (or ids) to narrow to — task boards or roadmap projects. Partial names match. When given, only tasks and project target dates are returned.
includeCompletedbooleanInclude finished tasks and completed roadmap projects (default false).
timezonestringIANA time zone that decides what "today" is, e.g. "America/New_York". Default UTC.
limitintegerMaximum items to return (default 200, max 500).

River wiki

list_river_spacesList Fishladder wiki spacesReadEveryoneRiver

List the spaces (sections) of the team's River wiki in Fishladder. A space can sit inside another space: parentSpaceId names it, and path reads like "Customer Success / Cursor". Call this before create_river_page to choose where a new page belongs.

InputTypeDescription
limitintegerMaximum rows to return (default 50, max 200).
search_river_pagesSearch Fishladder wikiReadEveryoneRiver

Search the team's River wiki inside Fishladder — internal docs, specs, runbooks, process and policy pages written by this team. Use this for questions about how the team does something ("how does our escalation process work", "what is our release process"). This is distinct from a general file store such as Google Drive: it searches only pages authored in Fishladder. Call get_river_page for the full text of a result.

InputTypeDescription
querystringFree-text match against page title and excerpt.
limitintegerMaximum rows to return (default 50, max 200).
get_river_pageRead a Fishladder wiki pageReadEveryoneRiver

Fetch the full text of one River wiki page in Fishladder, as Markdown, along with its version number and any open comment or suggestion threads. Use after search_river_pages when the excerpt is not enough to answer the question. The result can be edited and sent back through update_river_page (pass version as baseVersion) without losing formatting.

InputTypeDescription
pageId*stringPage ID from search_river_pages.
add_page_commentComment on a wiki page passageWriteMembers & adminsRiver

Attach a comment to a specific passage of a River wiki page WITHOUT changing the page — the passage is highlighted and the comment appears in a margin panel, labeled as coming from Claude. Use this for review feedback instead of editing reviewer notes into the body. Quote the passage exactly as get_river_page returned it.

InputTypeDescription
pageId*stringPage to comment on (see search_river_pages).
quotedText*stringThe exact passage the comment is about, quoted verbatim from get_river_page.
comment*stringThe comment itself.
occurrenceintegerWhen the quoted text appears more than once: which occurrence (0-based, in page order). Defaults to the first.
suggest_page_editSuggest an edit to a wiki pageWriteMembers & adminsRiver

Propose replacing a specific passage of a River wiki page with new text. This does NOT change the page: the proposal appears as a tracked change that a person accepts or rejects in Fishladder. Use it for concrete wording fixes; use add_page_comment for open questions. Quote the passage exactly as get_river_page returned it. An empty replacement proposes deletion.

InputTypeDescription
pageId*stringPage to suggest on (see search_river_pages).
quotedText*stringThe exact passage to replace, quoted verbatim from get_river_page.
replacement*stringThe text it should become. Empty string proposes deleting the passage.
notestringOptional rationale shown with the suggestion.
occurrenceintegerWhen the quoted text appears more than once: which occurrence (0-based, in page order). Defaults to the first.
reply_page_commentReply to a wiki page commentWriteMembers & adminsRiver

Reply to an existing comment or suggestion thread on a River wiki page. Thread IDs come from get_river_page (openThreads) or from add_page_comment/suggest_page_edit results.

InputTypeDescription
threadId*stringThread to reply to.
comment*stringThe reply.
resolve_page_commentResolve a wiki page commentWriteMembers & adminsRiver

Mark a comment thread on a River wiki page as resolved — the highlight is removed and the thread moves to the resolved list. Only for plain comments: a suggestion is accepted or rejected by a person in Fishladder, never through a tool.

InputTypeDescription
threadId*stringThread to resolve.
create_river_pageCreate a Fishladder wiki pageWriteMembers & adminsRiver

Create a new page in the team's River wiki inside Fishladder — a doc, spec, runbook or process note. Search with search_river_pages first so you update an existing page instead of duplicating it. If the team has more than one space, call list_river_spaces and ask which one to use.

InputTypeDescription
title*stringPage title.
contentstringPage body as Markdown: headings, bullet/numbered/task lists, links, bold/italic/strike, inline code, fenced code blocks, blockquotes, pipe tables. Plain text is fine as-is; blank lines separate paragraphs. Raw HTML is not interpreted.
spaceIdstringSpace to create the page in (see list_river_spaces). Optional when the team has only one.
parentIdstringOptional parent page ID, to nest this page beneath it.
update_river_pageEdit a Fishladder wiki pageWriteMembers & adminsRiver

Edit an existing page in the team's River wiki inside Fishladder. Only the fields you pass change — sending just a title renames the page and leaves its body alone. Passing content replaces the whole body rather than appending to it, so read the page with get_river_page first and send everything it should end up saying, along with the version you read as baseVersion — if the page changed meanwhile, this call fails and you should read it again. Inline comments survive the rewrite as long as their quoted text does. The previous version is kept in the page history. To move the page, pass spaceId and/or parentId (or moveToTopLevel) — a move needs no content, and child pages move with it. The result includes the page's location (space and parent pages).

InputTypeDescription
pageId*stringPage to edit (see search_river_pages).
baseVersion*integerThe version number from get_river_page. If the page changed since you read it, this call fails with a conflict — read it again and resend.
titlestringNew title. Omit to leave it unchanged.
contentstringNew body as Markdown, replacing the current body (same support as create_river_page). Raw HTML is not interpreted.
spaceIdstringMove the page (and its child pages) to this space (see list_river_spaces).
parentIdstringMove the page beneath this parent page (must be in the target space).
moveToTopLevelbooleanMove the page to the top level of its space (no parent).

Canvases

list_canvasesList hosted diagramsReadEveryoneRiver

List the interactive diagrams and documents hosted on the team's Fishladder. Returns titles and IDs, not the documents themselves — call get_canvas for one of those. Check here before creating a canvas, so an existing diagram gets updated rather than duplicated.

No inputs.

get_canvasRead a hosted diagramReadEveryoneRiver

Fetch a hosted diagram including its full HTML source. Read this before calling update_canvas so an edit builds on what is there rather than replacing it blind.

InputTypeDescription
canvasId*stringID of the canvas (see list_canvases).
create_canvasHost an interactive diagramWriteMembers & adminsRiver

Publish an interactive HTML diagram or document to Fishladder and get back a URL the team can open. Use this for diagrams whose interactivity carries the meaning — hover detail, expandable nodes, filtering. For a static flowchart, a Mermaid code block in a River wiki page is lighter and easier to edit later. Call list_canvases first to avoid creating a second copy of a diagram that already exists.

InputTypeDescription
title*stringShort name for the diagram.
html*stringA complete, self-contained HTML document. Inline all CSS and JavaScript, and embed any images as data: URIs — the page is rendered with a strict policy that blocks every outbound request, so external stylesheets, fonts, scripts and image URLs will silently fail to load. Scripts themselves run normally, so interactivity works.
descriptionstringOptional one-line summary of what the diagram shows.
update_canvasUpdate a hosted diagramWriteMembers & adminsRiver

Update a hosted diagram. Only the fields you pass change — sending just a title renames it and leaves the document alone. Passing html replaces the whole document rather than appending to it, so call get_canvas first and send everything it should end up with, not a fragment. The previous document is kept in the canvas history.

InputTypeDescription
canvasId*stringID of the canvas (see list_canvases).
titlestringNew title. Omit to leave unchanged.
htmlstringReplacement document. Omit to leave unchanged. A complete, self-contained HTML document. Inline all CSS and JavaScript, and embed any images as data: URIs — the page is rendered with a strict policy that blocks every outbound request, so external stylesheets, fonts, scripts and image URLs will silently fail to load. Scripts themselves run normally, so interactivity works.
descriptionstringNew one-line summary. Omit to leave unchanged.

Presentations

list_presentationsList slide decksReadEveryone

List the team's slide decks in Fishladder with their build status. A deck still showing "building" is not finished — decks are generated asynchronously and take minutes.

No inputs.

get_presentationRead a slide deckReadEveryone

Fetch one slide deck with its slides and live build status. Call this to check whether a deck you started has finished: status goes building → generating_images → assembling → complete, or failed with a reason. Read it before editing a slide, so an edit builds on what is there.

InputTypeDescription
presentationId*stringID of the deck (see list_presentations).
create_presentationStart building a slide deckWriteAdminsPresentations

Start building a PowerPoint deck from the team's Fishladder data — roadmap, projects, goals and feedback, chosen with the include flags. IMPORTANT: this returns immediately with a deck that is NOT built yet. Generation is asynchronous and takes minutes. Tell the person it has started, then use get_presentation to check whether it finished — do not report it as ready. Limits: 10 builds an hour per team, 2 at a time. For an interactive diagram, use create_canvas instead — slides are PowerPoint and cannot hold one, though a slide can link to a canvas.

InputTypeDescription
title*stringTitle of the deck.
audienceTypestringWho it is for: executive, engineering, investor, client or team. Defaults to executive.
themestringVisual theme: default, dark, minimal or bold. Defaults to default.
includeInitiativesbooleanInclude roadmap initiatives.
includeProjectsbooleanInclude projects.
includeGoalsbooleanInclude goals.
includeFeedbackbooleanInclude customer feedback.
additionalNotesstringExtra guidance for the deck, up to 2000 characters.
add_presentation_slideAdd a slideWriteMembers & adminsPresentations

Add a slide to an existing deck. Appended at the end unless you give sortOrder. Slides are PowerPoint and therefore static — for an interactive diagram, publish a canvas with create_canvas and reference its URL from a bullet.

InputTypeDescription
presentationId*stringDeck to add to (see list_presentations).
title*stringSlide title.
slideTypestringOne of: title, section_divider, narrative_text, key_metrics, custom. Defaults to custom.
contentobjectSlide body. Shape depends on slideType: "narrative_text" takes {"body": "a paragraph"}; "title" and "section_divider" need no content; everything else, including the default "custom", takes {"bullets": ["point one", "point two"]}. Unknown types still render a title and bullets, so bullets are the safe default.
sortOrderintegerPosition in the deck, 0-based. Appended when omitted.
update_presentation_slideEdit a slideWriteMembers & adminsPresentations

Edit one slide. Only the fields you pass change — sending just a title leaves the body alone. Passing content replaces the whole body rather than merging into it, so call get_presentation first and send everything the slide should end up with.

InputTypeDescription
slideId*stringSlide to edit (from get_presentation).
titlestringNew title. Omit to leave unchanged.
contentobjectReplacement body. Omit to leave unchanged. Shape depends on slideType: "narrative_text" takes {"body": "a paragraph"}; "title" and "section_divider" need no content; everything else, including the default "custom", takes {"bullets": ["point one", "point two"]}. Unknown types still render a title and bullets, so bullets are the safe default.
sortOrderintegerNew position in the deck, 0-based.

CRM

list_crm_companiesSearch CRM companiesReadEveryoneCRM

Search CRM companies by name or domain. Use this when the user mentions a customer or prospect and you need their record or companyId.

InputTypeDescription
querystringFree-text match against company name and domain.
lifecycleStagestringFilter by lifecycle stage, e.g. "prospecting", "customer".
limitintegerMaximum rows to return (default 50, max 200).
list_crm_contactsSearch CRM contactsReadEveryoneCRM

Search CRM contacts by name, email or job title. Use this to answer "who do we know at X", and before create_crm_contact so you update an existing person instead of duplicating them.

InputTypeDescription
querystringFree-text match against name, email and job title.
companyIdstringOnly contacts at this company (see list_crm_companies).
limitintegerMaximum rows to return (default 50, max 200).
create_crm_companyAdd a company to the CRMWriteMembers & adminsCRM

Add a company to the CRM. Search with list_crm_companies first — a duplicate customer record splits their deals and history across two entries, which someone then has to merge.

InputTypeDescription
name*stringCompany name.
domainstringPrimary domain, e.g. "acme.com". Worth setting — it is how duplicates are spotted.
industrystringIndustry, free text.
websitestringFull website URL.
descriptionstringWhat the company does, plain text.
lifecycleStagestringOne of "prospecting", "qualified", "customer", "churned". Defaults to prospecting.
create_crm_contactAdd a contact to the CRMWriteMembers & adminsCRM

Add a person to the CRM. Search with list_crm_contacts first to avoid duplicating them. Attach them to a company with companyId, resolved via list_crm_companies — a contact with no company is hard to find again.

InputTypeDescription
firstName*stringFirst name.
lastName*stringLast name.
emailstringEmail address.
titlestringJob title.
phonestringPhone number.
companyIdstringCompany they work at (see list_crm_companies).
lifecycleStagestringOne of "prospecting", "qualified", "customer", "churned". Defaults to prospecting.
update_crm_companyUpdate a CRM companyWriteMembers & adminsCRM

Update a company already in the CRM — its lifecycle stage, industry, domain, website or description. Only the fields you pass change. Find the company with list_crm_companies.

InputTypeDescription
companyId*stringCompany to update (see list_crm_companies).
namestringNew name.
domainstringNew primary domain.
industrystringNew industry.
websitestringNew website URL.
descriptionstringNew description, plain text.
lifecycleStagestringOne of "prospecting", "qualified", "customer", "churned".
update_crm_contactUpdate a CRM contactWriteMembers & adminsCRM

Update a person already in the CRM — their job title, email, phone, company or lifecycle stage. Only the fields you pass change. Find them with list_crm_contacts.

InputTypeDescription
contactId*stringContact to update (see list_crm_contacts).
firstNamestringNew first name.
lastNamestringNew last name.
emailstringNew email address.
titlestringNew job title.
phonestringNew phone number.
companyIdstringMove them to this company (see list_crm_companies).
lifecycleStagestringOne of "prospecting", "qualified", "customer", "churned".
list_crm_dealsList CRM dealsReadEveryoneCRM

List CRM deals with value, stage and status. Use this for pipeline questions — what is open, what closed, how much is in flight. Values are returned in cents.

InputTypeDescription
statusstringFilter by status: "open", "won", "lost".
companyIdstringRestrict to one company (see list_crm_companies).
ownerIdstringRestrict to one deal owner (see list_team_members).
limitintegerMaximum rows to return (default 50, max 200).

HubSpot

search_hubspotSearch HubSpotReadEveryoneHubSpot connected

Search the team's connected HubSpot portal for companies or contacts by name, domain or email. Use this to find the HubSpot record ID before link_hubspot_record. Returns name, domain or email, and a link to the record in HubSpot.

InputTypeDescription
query*stringName, domain or email to search for.
objectTypestringDefault company.One of: company, contact
limitintegerMaximum results (default 10, max 50).

Feedback

list_feedbackSearch customer feedbackReadEveryone

Search customer feedback entries. Use this when the user asks what customers are asking for, or wants evidence behind a roadmap decision.

InputTypeDescription
querystringFree-text match against title, details, and the problem being solved.
statusstringFilter by status, e.g. "open", "planned", "shipped".
limitintegerMaximum rows to return (default 50, max 200).

Generated from the connector's tool definitions, so it always matches what Claude is offered.