A Stavrobot plugin for managing your Linear workspace — issues, comments, labels, and projects — through the assistant.
Install the plugin by asking the bot to install https://github.com/stavrobot/plugin-linear.git.
Set api_key to a Linear personal API key:
api_key configuration value.The key acts as your Linear user and can read and write your workspace data, so treat it as a secret.
update_issue has no replacing labels parameter. Change labels with add_labels and remove_labels; the issue's other labels are preserved, so adding one label keeps the rest.
Those are Linear's native label deltas, and they are strict. Removing a label that is not currently on the issue is an error, not a silent no-op, and naming the same label in both add_labels and remove_labels is an error too. In either case the whole update fails and nothing else in it is applied. This is deliberate: the alternative would quietly do the wrong thing.
With no filters, list_issues returns your open issues — assigned to you, excluding completed and cancelled ones. Pass assignee as anyone to see everyone's open issues instead, or an explicit name or me.
No tool paginates. Each list returns a single page and reports in its output when the limit cut the results short. list_issues and search_issues default to 25 results and accept limit up to 250; list_projects returns up to 50 projects. To see more, raise limit or narrow the filters.
Tool parameters have no array type, so parameters that accept several values — labels, add_labels, remove_labels and links — take a single comma-separated string, for example "Bug, P1".
priority takes a word: none, urgent, high, medium, or low. Not Linear's integer values.
get_issue, update_issue and add_comment take the human identifier Linear displays, such as ENG-123, not a UUID. It is case-insensitive: eng-123 works.
The plugin talks to a single Linear team and no tool takes a team parameter; your account's first team is used, so on a workspace with several teams this may not be the one you expect.
The tests run offline: every network call is replaced with a fake and no credentials are read. Run the whole suite with:
for t in tests/test_*.py; do uv run "$t" || exit 1; done
Each script prints a PASS/FAIL line per check and exits non-zero if any check fails.