Read and write the Productboard product hierarchy, customer notes, teams, members and webhooks over the Productboard REST API v2.
Productboard ships in the w6w first-party pack. It declares 41 actions, 3 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.productboardProductboard organizes product management around one hierarchy — products, components, features, subfeatures, initiatives, objectives, key results, releases and release groups — and this app lets a workflow read and write that whole structure plus the customer feedback that feeds it. List, create, update and search entities anywhere in the hierarchy, set an entity’s parent, and link related entities together.
Feedback runs through notes: create a note against an existing customer or company, comment on one, search across the note inbox, and link a note straight to the feature or initiative it is about. Look up teams and members, read which Jira issues and plugin integrations are connected to which entities, and track engagement with member activity data.
Manage the webhook subscriptions that tell your systems when something in the hierarchy changes, so a workflow can react the moment a feature moves, a note lands, or a release ships.
Three routes to the same 41 actions. The Workflow tab is generated from Productboard's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
entity-configuration-get Fields, types, validation rules and supported patch operations for one entity type in this workspace.
entity-configuration-list Discover which fields each entity type has in this workspace, their types, and the patch operations they support. Custom fields are addressed by UUID; this is where those UUIDs get their names.
entity-create Create a product, component, feature, subfeature, initiative, objective, key result, release, release group, company or user.
entity-delete Delete an entity. In API v2 this CASCADES — deleting a feature deletes its subfeatures and deleting a release group deletes its releases, with no warning and no undo.
entity-field-value-list List the values a select or status field accepts, so a write can use a real option rather than a guess.
entity-get Retrieve one product, component, feature, initiative, objective, release, company or user by ID.
entity-list List products, components, features, subfeatures, initiatives, objectives, key results, releases, release groups, companies and users, with optional filters.
entity-parent-set Move an entity under a new parent, replacing its current one. This is the only way to re-parent — creating a parent relationship on an entity that already has one is a 409.
entity-relationship-create Link one entity to another as link, child, isBlockedBy or isBlocking. Use Set entity parent to re-parent, which is a replace rather than a create.
entity-relationship-delete Remove one relationship between two entities. Deletes the link only — both entities survive.
entity-relationship-list List an entity's parent, child, link, isBlockedBy and isBlocking relationships, optionally narrowed to one type or one target.
entity-score-get Retrieve the customer score Productboard computes for one entity. The vendor documents this endpoint as beta, so treat its response shape as unstable.
entity-search Filter entities by several alternative values per field, by custom field UUID, and by relationship — the cases the List entities query string cannot express.
entity-update Update an entity by replacing whole field values, by applying set/addItems/removeItems/clear patch operations, or both.
jira-integration-connection-list List the links between Productboard entities and Jira issues for one integration, optionally narrowed to a single issue key or issue id.
jira-integration-list List the Jira integrations configured in this workspace. The v2 Jira surface is read-only — integrations are created and edited in the Productboard UI.
member-activity-list Workspace usage and engagement data per member, for adoption dashboards. Needs the analytics:read scope, which is separate from the entity scopes.
member-get Retrieve one workspace member by ID. Not a whoami — API v2 has no endpoint that identifies the calling token.
member-list List workspace members, optionally filtered by role or a search term. Disabled, invitation-pending and invited members are excluded unless asked for.
member-search Look members up by up to 100 ids or emails at once, or by role — the batch form that List members cannot express.
note-comment-create Add a comment to a note. Write-only — v2 removed comments from the note response and offers no endpoint to read them back.
note-configuration-list Discover which fields notes have in this workspace, their types, and the patch operations they support. v2 notes no longer carry followers, comments or importance.
note-create Create a customer feedback note, optionally linking it to a customer and to product hierarchy entities in the same call. The customer must already exist — v2 does not auto-create users or companies.
note-delete Permanently delete a note. Consider archiving instead (Update note with archived: true), which keeps the feedback and its links to features.
note-get Retrieve one customer feedback note by ID. Personal fields read `[redacted]` when the token lacks the members:pii:read scope.
note-list List customer feedback notes, filtered by type, processing state, owner, creator, source system or date range.
note-relationship-create Link a note to the customer it came from, or to a feature, subfeature, product or component (creating an insight).
note-relationship-delete Remove a note's customer relationship or one of its product links. Deletes the link only.
note-relationship-list List the customer a note came from and the product entities it is linked to (its insights).
note-search Full-text search across note content, with structured filters. Replaces v1's `term` parameter. Tag filtering is not yet available in v2.
note-update Update a note by replacing field values or by applying set/clear/addItems/removeItems patch operations. Setting `processed` is how a workflow clears the triage inbox.
plugin-integration-connection-list List the entities a plugin integration is connected to, filtered by connection state. Filtering on `error` finds the links that are currently broken.
plugin-integration-list List the custom plugin integrations registered in this workspace. The authorization header each one sends is write-only and never returned.
team-list List the workspace's teams, optionally filtered by name, handle or a search term.
team-member-list List the members of one team. Emails read `[redacted]` when the token lacks the PII scope.
webhook-create Subscribe an HTTPS endpoint to Productboard events. Retrying creates a SECOND subscription — your endpoint would then receive every event twice.
webhook-delete Delete a webhook subscription. There is no update endpoint — changing a subscription means deleting and recreating it, re-supplying the authorization header.
webhook-list List webhook subscriptions. The authorization header configured on each one is never returned, by design.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying Productboard's real ids.
{
"manifestVersion": "2",
"name": "productboard-example",
"steps": [
{
"id": "entity-configuration-get",
"uses": {
"app": "io.w6w.productboard",
"action": "entity-configuration-get",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"type": "<type>"
}
}
]
}entity-configuration-get entity-configuration-list entity-create entity-field-value-list entity-get +36 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for Productboard, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to Productboard. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "note-create",
payload: {
type: "<value>",
fields: "<value>",
// relationships: "<value>",
// metadata: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action note-create --payload '{"type":"<value>","fields":"<value>"}' Give an AI agent Productboard — without giving it Productboard's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.productboard#entity-configuration-get",
"input": {
"type": "<type>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's Productboard connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
Productboard's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. Productboard itself is MIT, and the runtime that executes it is source-available (FSL).
Productboard declares its own checks, so its health is a property of the app rather than something the host guesses at.
Component status from status.productboard.com. Covers Spark AI, the Web Application, MCP/APIs/Integrations (the component this app's requests depend on), Identity & Access and the website, plus the eleven external services (Anthropic, Stripe, Cloudflare, AWS, Pusher, Slack, Intercom, SendGrid) Productboard itself depends on.
Unauthenticated GET against api.productboard.com/v2. A 401 is a pass — it proves the host resolves and the v2 route is alive. A 404 route.notFound means the path moved, which is a different problem from an expired token.
Reads X-RateLimit-Limit and X-RateLimit-Remaining from an authenticated read. Productboard allows 50 requests/second per access token and meters nothing else. Reports unknown rather than ok when the headers are absent — see the module header for why that case is expected.