productlane
productlane.
Productlane — customer feedback threads: what customers have said.
setup & usage
create a key in Productlane (Settings → API), then paste it into oto.
threads:read, threads:write, contacts:*, companies:*, projects:*, issues:*, changelogs:*, docs:*, tags:*, snippets:*, portal:read): a 403 refusal means one is missing, not that the key is badproductlane_threads(op="search", status="open"), or productlane_roadmap(op="projects", sort="total_score") to rank by the weight of attached feedback rather than by dateproductlane_threads(op="get", thread_id="…", expand=["messages","comments"])productlane_threads(op="send", thread_id="…", content="…") — ⚠️ this really goes out, through the channel the thread came fromproductlane_threads(op="comment", …): visible to teammates only, nothing goes outproductlane_threads(op="link", thread_id="…", issue_ids=[…]): this is the gesture that raises a project's scoreproductlane_contacts(op="search", …) then op="issues" / op="projects" on the contactproductlane_changelogs(op="create", fields={…}), then op="update" with {"published": true} to make it visibleproductlane_changelogs(op="broadcast", changelog_id="…", email=true, dry_run=false)productlane_docs(op="articles", title_contains="…")productlane_workspace(op="me"): it returns the granted scopes and requires no right⚠️ `op="broadcast"` has NO effect on `published` — the vendor spells it out. The two gestures are independent, and mixing them up is costly in both directions:
publish = productlane_changelogs(op="update", fields={"published": true}). broadcast = op="broadcast", which is dry-run by default: you need dry_run=false for anything to go out, and there is no cancel or recall.
⚠️ a write can succeed here while the Linear sync fails: the vendor logs it on its side and does not surface it in the response. A success on update_project / update_issue therefore does not prove that Linear followed.
team_id, state_id, assignee_id, linear_status_id are Linear identifiers — read them via productlane_roadmap(op="workflows", team_id="…") and op="statuses", never hardcode themstatus is not a fixed enum: these are the Linear team's workflow states, specific to each workspacepriority follows Linear numbering: `0` = no priority, `1` = urgent, then 2, 3, 4 in decreasing urgency. It is not an ascending scale"EMAIL" targets only one addresscompany_id company survives, the one in source_id is deletedaccepted: the draft no longer applies cleanly, the article having moved underneath it. It is an HTTP success that applied nothing — read the returned status, not just the absence of an errorthis connector accepts multiple comptes: each stored credential becomes a named account (one name per compte), at your level, your team's or your org's.
_account="<name>" on the tool; list them: oto_identity(op='list', connector='productlane') (scope='org' or scope='group' for the org's or team's)oto_identity(op='set', connector='productlane', identity_id='<name>'); rename: op='rename' with new_name_account) and adding upoutils
usage
claude plugin marketplace add otomata-tech/oto-plugin — mcp + skill configured.pipx install oto-cli then oto productlane …