{
  "markdown": "<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/KazKozDev/abscissa/main/docs/assets/banner.png\" alt=\"Abscissa\" width=\"350\">\n</p>\n\n<!-- mcp-name: io.github.KazKozDev/abscissa -->\n\nAbscissa is a Python stdio MCP server for [Linear](https://linear.app/). It turns Linear's GraphQL\nAPI into 42 tools for an MCP client: issues, projects, cycles, dependencies,\ncomments, labels, workflow states, teams, and users.\n\nThe design priority is deliberate control over project data. Read operations\nreturn cursor-paginated results; `get_user_issues()` resolves the authenticated\nLinear user; archive and delete tools require an explicit `confirm=true` before\nthey make a destructive API call. The server stores no credentials and reads\n`LINEAR_API_KEY` from its process environment.\n\nAbscissa uses the stdio transport from the\n[Model Context Protocol](https://modelcontextprotocol.io/). Any client that\nsupports stdio MCP can launch it as a local tool process.\n\n## Run it\n\nYou need Python 3.10+ and a [Linear personal API key](https://linear.app/settings/api).\n\n```sh\ngit clone https://github.com/KazKozDev/abscissa.git\ncd abscissa\npython3 -m venv .venv\n.venv/bin/pip install -e '.[dev]'\nexport LINEAR_API_KEY='lin_api_…'\n.venv/bin/abscissa\n```\n\nYou can also install Abscissa directly from PyPI:\n\n```sh\npip install abscissa\n```\n\nThe final command starts the MCP server on standard input and output. Register\n`.venv/bin/abscissa` as a stdio command in your MCP client, and pass\n`LINEAR_API_KEY` through that client's environment or secret manager.\n\nThe key remains outside the repository. The `.gitignore` excludes common local\nenvironment files, including `.env` and `.venv`.\n\n## Example prompts\n\nOnce Abscissa is registered in your MCP client, try prompts like:\n\n```text\nShow my open Linear issues grouped by project.\nCreate an issue in ENG for fixing onboarding copy.\nList issues blocked by GEN-32.\n```\n\n## Tools\n\n| Area | Tools |\n| --- | --- |\n| Identity | `get_current_user` |\n| Issues | `create_issue`, `update_issue`, `search_issues`, `get_user_issues`, `get_issue`, `assign_issue`, `add_comment`, `set_issue_estimate` |\n| Issue lifecycle | `archive_issue`, `delete_issue` |\n| Dependencies | `list_issue_dependencies`, `add_issue_dependency`, `remove_issue_dependency` |\n| Labels and workflow | `list_workflow_states`, `list_issue_labels`, `create_label`, `add_issue_label`, `remove_issue_label` |\n| Teams and people | `list_teams`, `get_team`, `list_users` |\n| Projects | `create_project`, `get_project`, `list_projects`, `list_project_issues`, `set_issue_project`, `remove_issue_from_project`, `update_project`, `update_project_details`, `archive_project` |\n| Project labels | `list_project_labels`, `create_project_label`, `add_project_label`, `remove_project_label` |\n| Project updates | `create_project_update`, `list_project_updates` |\n| Cycles | `create_cycle`, `update_cycle`, `archive_cycle`, `list_cycles`, `list_cycle_issues` |\n\nSearch and list tools accept `limit` and `cursor`. Their responses keep the same\nshape:\n\n```json\n{\n  \"items\": [],\n  \"next_cursor\": null\n}\n```\n\nPass a non-null `next_cursor` back as `cursor` to request the next page.\n\n`list_issue_dependencies` returns separate `blocks` and `blocked_by` lists.\nEach item includes its `relation_id`; use it to remove that dependency. Its\n`next_cursors` object has separate cursors for each direction.\n\n## Destructive actions\n\n`archive_issue`, `archive_project`, and `delete_issue` are marked with MCP's\n`destructiveHint`. They refuse to call Linear until the client invokes them\nwith `confirm=true`.\n\n```text\nDeletion requires explicit confirmation: set confirm=true\n```\n\nThis prevents an accidental tool call from deleting or archiving data. It does\nnot replace Linear's own access controls: the API key still determines which\nresources the server may read or change.\n\n## Verify the checkout\n\n```sh\n.venv/bin/ruff check .\n.venv/bin/python -m pytest\n```\n\nThe current checkout produces:\n\n```text\nAll checks passed!\n..........                                                               [100%]\n10 passed\n```\n\nThe tests cover pagination bounds and response shape, authenticated-user issue\nresolution, project membership, cycle queries, dependency direction, confirmation\nguards, cycle lifecycle operations, and MCP tool registration. GitHub Actions\nruns the same lint and test commands on Python 3.10, 3.11, 3.12, and 3.13.\n\n## Limitations\n\nAbscissa is a local stdio server, not an HTTP service. It needs a running\nMCP-capable client and a valid Linear API key. The automated suite avoids\nmutating a real Linear workspace; create, update, archive, and delete behavior\nis therefore protected by unit tests rather than a live write test.\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 4744,
  "sha": "29ad73a3e0b927c4f2b76cf6934e89fd2de311efeb7be7f727bec451a2a9288c",
  "repo_slug": "kazkozdev/abscissa",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_kazkozdev_abscissa_98afb05d/readme"
}