Skip to content
Aaron K. White

lin.

Roledesigned, built, and shipped it
Teamjust me, with Claude Code
ToolsRust, Linear's GraphQL API, Claude Code, crates.io and Homebrew
Outcomeall of Linear from the terminal, zero idle tokens instead of the MCP's ~19,659

Ninety percent of my day is in the terminal

Our feature requests lived in a Slack channel, a black box where things went in and never came out. I started using Linear to pull them into one place, and it worked so well we migrated the whole team off Jira and onto Linear.

But I live in Claude Code. Ninety percent of my day is in the terminal, and Claude already has all my context, my code, my meetings, my docs. The last thing I wanted was to keep breaking out of that to click around a Linear or Jira web UI, which feels slow the second you’re used to working at the speed of the tools. I wanted Claude to just drive the tracker for me.

An MCP is just a wrapper on an API

So I started with the MCP server, the standard way you plug a service into a coding agent. It was great, until it bloated every session with tokens I never used. But it got me thinking. An MCP is just a wrapper on top of an API that already exists. So why hand the agent the heavy wrapper at all? Why not give it the API directly, and load nothing until it actually reaches for it?

So I built the tools myself. Linear tools in Python, sitting right on the API, then the matching set for Jira. Now I could tell Claude what to do and it would do it through my tools instead of the MCP.

It worked. For a while. But I had to be exact about everything. Constantly remind Claude the tools were there, tell it to go discover them, spell out when to use them in a CLAUDE.md and an AGENTS.md. And it still fought me. It would slip back to the MCP, or decide the tools weren’t enough and write MORE Python on the fly to hit the API itself, redundant code to do the exact thing the tools already did.

The idea was right, the packaging was wrong

Loose scripts and a note telling the agent to use them don’t hold. Around then I’d gone deep on how a real CLI is built for agents, and it was everything my scripts weren’t: the instructions baked in, mapped to the API, always there, obviously the thing to reach for.

Lin is one Rust binary, lin, mapped straight onto Linear’s API, carrying its own instructions: what each command does, when to reach for it, how to chain it. The agent doesn’t have to be told to use it in some fragile note, and it can’t wander off and reinvent it.

It covers pretty much all of Linear: issues, projects, cycles, initiatives, roadmap, teams, labels, customers, docs, views, notifications, relations, attachments, search. An agent that hits a gap writes throwaway code to get around it, and then you’re debugging its improvisation instead of doing your work. So I wrapped the whole API. When I hadn’t wrapped something yet, lin api '{ ... }' passes any raw GraphQL through with auth injected, so the agent is never stuck waiting on me to add a command. The commands you’re not using cost nothing, because a CLI only loads the string you actually type.

Every command speaks --json, compact, with Linear’s GraphQL {"data": {...}} envelope stripped, so lin issues list --team ENG --json pipes straight into jq. Errors come back as an exit code plus stderr an agent can actually parse. It ships a Claude Code skill that points the agent at lin first. And a person can run the same commands, skip the agent entirely, and get the same result.

The binary is lin, short for Linear, two letters, fast to type a hundred times a day. The crate on crates.io is lincli because the short names were taken.

Lin became the blueprint for bosshogg

Lin is out, free, and open source, built solo and shipped with real CI, calendar versioning, crates.io, a Homebrew tap, and prebuilt binaries for macOS and Linux so nobody has to compile anything. I dogfooded it on my own real Linear workspace the whole way.

It’s built for an AI-native product and engineering team that wants to move faster in Linear, whichever way they drive it.

Then I pointed the same pattern at PostHog. That became BossHogg.

Nextriver & run

Open to product & design leadership roles, advisory work, and good conversations.

Get in touch

cookie preferences.

Required storage keeps your theme and this choice on your own machine. Analytics (PostHog) helps me see what people actually read. Nothing loads until you say yes.

requiredtheme · this choice. local only.
privacy