A headless coding agent powered by the Claude Agent SDK that integrates with Linear to automatically implement tickets assigned to it. The bot runs on a local machine using Express.js and Tailscale to expose webhooks to Linear.
This bot monitors Linear for tickets assigned to it and automatically implements them following a workflow defined as a Claude skill. Each ticket comes with a complete implementation plan (created by upstream planning bots), which this bot executes by:
- Creating a git worktree for isolated development
- Initializing the worktree environment
- Following the implementation plan step-by-step
- Committing changes and creating pull requests
The bot runs as an Express.js server on your local machine, exposed to the internet via Tailscale:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Linear │──────│ Tailscale │──────│ Local Machine │
│ Webhooks │ │ Funnel │ │ Express.js │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Claude Agent │
│ SDK │
└─────────────────┘
src/
├── index.ts # Express.js server entry point
├── lib/
│ ├── agent/
│ │ ├── agentClient.ts # Claude Agent SDK integration
│ │ └── prompt.ts # System prompt for coding tasks
│ ├── github/
│ │ ├── githubClient.ts # GitHub PR management (Octokit wrapper)
│ │ └── index.ts
│ ├── workflow/
│ │ ├── ticketHandler.ts # Extract implementation plans from tickets
│ │ ├── worktreeLifecycle.ts # Git worktree operations
│ │ ├── envSetup.ts # Environment setup and validation
│ │ └── index.ts
│ ├── oauth.ts # Linear OAuth handling
│ └── types.ts # TypeScript type definitions
- Ticket Assignment - A ticket is assigned to the bot in Linear with an attached implementation plan
- Worktree Creation - Bot creates a new git worktree for the feature branch
- Environment Setup - Initializes the worktree (dependencies, environment, etc.)
- Implementation - Executes the plan using Claude Agent SDK as the coding engine
- Completion - Commits changes, pushes branch, creates PR, and updates Linear ticket status
- Node.js 18+
- Git
- Tailscale installed and configured
- Local access to target repositories
- Linear workspace with permissions to create an OAuth app
- Anthropic API key (for Claude Agent SDK)
- GitHub token (for PR creation)
npm installTailscale Funnel exposes your local Express.js server to the internet, allowing Linear to send webhooks to your machine.
# Enable Tailscale Funnel (requires admin approval in Tailscale admin console)
tailscale funnel 3000This will give you a public URL like https://your-machine.tailnet-name.ts.net
Create a .env file with the following (see .env.example for a template):
# Server Configuration
PORT=3000
TAILSCALE_HOSTNAME=https://your-machine.tailnet-name.ts.net
# Anthropic API
ANTHROPIC_API_KEY=your-anthropic-api-key
# Linear OAuth
LINEAR_CLIENT_ID=your-linear-client-id
LINEAR_CLIENT_SECRET=your-linear-client-secret
LINEAR_WEBHOOK_SECRET=your-webhook-secret
# GitHub (for PR creation)
GITHUB_TOKEN=your-github-token
# Repository Configuration
REPO_BASE_PATH=/path/to/your/repositories- Create a new OAuth app in Linear
- Set the redirect URI to
https://your-machine.tailnet-name.ts.net/oauth/callback - Enable webhooks and set the webhook endpoint to
https://your-machine.tailnet-name.ts.net/webhook - Subscribe to agent session webhooks
- Copy the client ID, client secret, and webhook signing secret
# Start the Express.js server
npm run start
# Or for development with auto-reload
npm run devThe server will start on http://localhost:3000 and be accessible via your Tailscale Funnel URL.
The bot uses git worktrees to enable parallel development without branch switching:
# Bot automatically creates worktrees like:
git worktree add ../feature-USP-1234 -b feature/USP-1234
# After completion, worktrees can be cleaned up:
git worktree remove ../feature-USP-1234This allows the bot to work on multiple tickets simultaneously without conflicts.
Tickets should include an implementation plan in a structured format. The bot expects plans created by upstream planning bots that include:
- List of files to create/modify
- Specific code changes with context
- Test requirements
- Dependencies to install (if any)
- Build/validation steps
Example format in ticket description:
## Implementation Plan
### Files
- [create] src/lib/newFeature.ts - New feature implementation
- [modify] src/index.ts - Add endpoint for new feature
### Dependencies
- lodash
### Test Commands
- npm run test
### Build Commands
- npm run buildThe bot uses the Claude Agent SDK which provides:
- Built-in tools for file operations, shell commands, and git operations
- Permission modes for safe autonomous execution
- Streaming responses for real-time progress updates to Linear
The SDK handles all coding operations, so no custom tool implementations are needed.
The Express.js server exposes:
GET /- Root endpoint with service infoGET /health- Simple health check endpointGET /status- Detailed status with configuration infoPOST /webhook- Receives Linear webhooks for ticket assignmentsGET /oauth/authorize- OAuth authorization endpointGET /oauth/callback- OAuth callback handler
# Start with hot reload
npm run dev
# Type check
npm run typecheck
# Lint
npm run lintWith Tailscale Funnel running, Linear webhooks will reach your local machine directly. You can also use the Tailscale admin console to monitor traffic.
- Modify
src/lib/agent/prompt.tsto adjust the agent's coding behavior - Update workflow modules in
src/lib/workflow/for custom orchestration - Extend GitHub client in
src/lib/github/for additional PR features
This bot is designed to work as part of a multi-agent system:
- Planning Bot - Analyzes tickets and creates detailed implementation plans
- Coding Bot (this repo) - Executes the implementation plans
- Review Bot (optional) - Reviews PRs and provides feedback
The handoff between bots happens via Linear ticket updates with structured plan data.
Using Tailscale instead of cloud deployment provides:
- Local execution - Full access to local file system and git repositories
- Security - Traffic encrypted end-to-end, no exposed ports
- Simplicity - No cloud infrastructure to manage
- Cost - No hosting fees for webhook endpoints
This project is licensed under the MIT License.