# MCP Linear.app Server - Agent Instructions
## Project Overview
**MCP Linear.app Server** is a Model Context Protocol server that enables MCP clients to interact with Linear.app's API for issue tracking, project management, and workflow automation.
- **Language:** TypeScript (ES Modules)
- **Runtime:** Bun 1.0.0+ (or Node.js 18.0.0+)
- **Build Tool:** Bun (with TypeScript compilation)
- **Key Dependencies:** @modelcontextprotocol/sdk, @linear/sdk, zod
- **Current Version:** 1.0.0
- **Architecture:** MCP server with stdio transport, modular tool handlers, type-safe API client wrapper
## Architecture
```
MCP Linear Server (stdio transport)
├── Tool Registry (32 MCP tools)
├── LinearAPIClient (API wrapper)
│ └── @linear/sdk (Linear GraphQL SDK)
├── Zod Schemas (runtime validation)
└── Tool Handlers (domain-organized modules)
├── Issues (7 tools)
├── Teams & Workflow (5 tools)
├── Projects (6 tools)
├── Custom Views (5 tools)
├── Cycles/Sprints (6 tools)
├── Labels (2 tools)
└── Users (1 tool)
```
## Key Patterns
### MCP Tool Registration
All tools follow the MCP specification pattern:
```typescript
{
name: 'linear_tool_name',
description: 'Clear description for LLM clients about what this tool does',
inputSchema: {
type: 'object',
properties: {
paramName: {
type: 'string',
description: 'Parameter description',
},
},
required: ['paramName'],
},
}
```
### Zod Schema-First Validation
Define schemas before implementation:
```typescript
export const MyToolSchema = z.object({
paramName: z.string().describe('Description for LLM clients'),
optionalParam: z.number().optional().describe('Optional parameter'),
});
export type MyToolInput = z.infer<typeof MyToolInput>;
```
### Tool Handler Pattern
All tool handlers follow this structure:
```typescript
export async function myTool(client: LinearAPIClient, args: unknown) {
// 1. Validate input with Zod
const params = MyToolSchema.parse(args);
// 2. Call Linear API via client
const result = await client.myOperation(params);
// 3. Return MCP response format
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(result, null, 2),
},
],
};
}
```
### Error Handling Strategy
Three-layer error handling:
1. **Zod validation errors** - Caught by MCP SDK, return clear field errors
2. **Linear API errors** - Wrapped with context in LinearAPIClient
3. **Tool handler errors** - Return McpError for protocol compliance
```typescript
try {
const result = await this.client.operation();
return this.formatResult(result);
} catch (error) {
throw new Error(`Failed to [operation]: ${this.getErrorMessage(error)}`);
}
```
### ES Module Imports
All imports must use `.js` extension (TypeScript ES module requirement):
```typescript
import { LinearAPIClient } from './linear-client.js';
import * as issuesModule from './tools/issues.js';
```
### Response Formatting
LinearAPIClient normalizes all responses to plain objects:
```typescript
private formatResult<T>(data: T): T {
return JSON.parse(JSON.stringify(data));
}
```
## Directory Structure
```
mcp-linearapp/
├── src/
│ ├── index.ts # MCP server entry point, tool registry
│ ├── linear-client.ts # Linear API wrapper
│ ├── tools/ # Tool handler modules
│ │ ├── issues.ts # 7 issue management tools
│ │ ├── teams.ts # 2 team/workflow tools
│ │ ├── projects.ts # 1 project listing tool
│ │ ├── cycles.ts # 2 cycle/sprint tools
│ │ ├── labels.ts # 2 label management tools
│ │ └── users.ts # 1 user listing tool
│ └── schemas/
│ └── index.ts # All Zod schemas (centralized)
├── dist/ # Compiled JavaScript (build output)
├── docs/ # Documentation
│ ├── API_REFERENCE.md # Complete tool API reference
│ ├── QUICK_START.md # 5-minute setup guide
│ └── DEPLOYMENT.md # Deployment instructions
├── package.json
├── tsconfig.json
├── .env.example
└── README.md
```
## Implementation Rules
1. **Type Safety First** - Use strict TypeScript, no `any` types
2. **Schema-Driven Validation** - All inputs validated with Zod before processing
3. **ES Module Imports** - Always use `.js` extensions in imports
4. **Error Context** - Wrap errors with operation context (what failed)
5. **Async/Await** - Use async/await, avoid raw promises
6. **Const Over Let** - Prefer immutable bindings
7. **Export Types** - Export both implementation and TypeScript types
8. **JSON Serialization** - Always serialize Linear objects before returning (they contain non-serializable methods)
9. **MCP Response Format** - Return `{ content: [{ type: 'text', text: string }] }`
10. **Tool Naming** - Use `linear_` prefix for all tool names
## Agent Usage Guidelines
When working on this project, leverage specialized agents for different tasks:
### Primary Agents (Auto-proactive)
| Agent | When to Use | For What |
| ----------------------- | --------------------------------------- | -------------------------------------------------------------------------------- |
| **typescript-backend** | Backend implementation, API integration | Building MCP tools, Linear SDK integration, Zod schemas, error handling patterns |
| **code-review** | After writing significant code | Review TypeScript code quality, async patterns, error handling, MCP compliance |
| **architecture-review** | After adding new tools/modules | Ensure consistency with modular architecture, validate MCP patterns |
| **markdown-formatter** | Creating/updating docs | Format API reference, README updates, deployment guides |
| **git-flow-manager** | Branch management, PRs | Feature branches, release management, changelog updates |
| **mcp-server** | MCP-specific features | Protocol compliance, tool registration, schema design |
### Task-Based Agents (Use via delegation)
| Agent | Command Pattern | Good For |
| ------------------- | ----------------- | -------------------------------------------------------------------- |
| **explore** | Codebase searches | Finding Linear SDK usage patterns, schema definitions, tool handlers |
| **general** | Multi-step tasks | Complex workflows requiring multiple operations across modules |
| **error-detective** | Debugging issues | MCP protocol errors, Linear API failures, stdio communication issues |
### TypeScript Backend Agent Usage
Use `typescript-backend` agent PROACTIVELY for:
1. **Adding New Tools** - Plan tool structure, schema, handler implementation
2. **Linear SDK Integration** - Understand GraphQL API patterns, SDK methods
3. **Type Safety** - Ensure proper TypeScript types, generic usage, inference
4. **Async Patterns** - Review promise handling, error propagation, concurrent operations
### MCP Server Agent Usage
Use `mcp-server` agent PROACTIVELY for:
1. **Tool Schema Design** - Validate JSON Schema compatibility with Zod
2. **Protocol Compliance** - Ensure tools follow MCP specification
3. **Integration Patterns** - Best practices for MCP server implementation
### Code Review Workflow
Use `code-review` agent PROACTIVELY after:
1. Implementing new tools (e.g., adding `linear_create_milestone`)
2. Refactoring LinearAPIClient methods
3. Updating Zod schemas with new validations
4. Modifying error handling patterns
### Example Agent Delegation
```bash
# For adding a new Linear API integration
/delegate Implement linear_create_milestone tool with proper schema validation
# For debugging MCP protocol issues
/delegate Investigate why tool responses aren't appearing in the MCP client
```
## Pull Request Guidelines
### PR Creation Process
1. **Branch Naming**
- Feature: `feature/tool-name` (e.g., `feature/linear-milestones`)
- Bug fix: `fix/issue-description`
- Documentation: `docs/what-changed`
- Refactor: `refactor/component-name`
2. **Commit Messages**
- Follow conventional commits: `type: description`
- Types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`
- Examples:
- `feat: add linear_create_milestone tool`
- `fix: handle null assignee in issue listing`
- `docs: update API reference with new tools`
3. **PR Description Template**
```markdown
## Summary
Brief overview of changes
### Tools Added/Modified
- `linear_tool_name` - Description of functionality
### Schema Changes
- Added: `NewToolSchema` with validation for...
- Modified: `ExistingSchema` to support...
### API Client Changes
- New method: `clientMethod()` - Purpose
- Modified: `existingMethod()` - Reason
### Documentation Updates
- Updated README.md with usage examples
- Added API_REFERENCE.md entry for new tools
### Testing
- [ ] Built successfully (`bun run build`)
- [ ] Type checks pass (`bun run typecheck`)
- [ ] Lint passes (`bun run lint`)
- [ ] Tested with MCP client
- [ ] Manual testing with Linear workspace
### Breaking Changes
- None / List any breaking changes
---
**Closes:** #issue-number
**Version:** Specify if version bump needed
```
4. **Before Creating PR**
- Code compiles: `bun run build`
- Type checking passes: `bun run typecheck`
- Linting passes: `bun run lint`
- Format code: `bun run format`
- Documentation updated (README, API_REFERENCE, CHANGELOG)
- Test with MCP client
- Self-review completed
5. **Using git-flow-manager Agent**
The `git-flow-manager` agent can assist with PR creation:
- Analyzes commit history
- Generates comprehensive PR description
- Formats with proper markdown structure
### PR Review Checklist
**Code Quality:**
- [ ] Strict TypeScript types (no `any`)
- [ ] Zod schemas for all inputs
- [ ] Proper error handling with context
- [ ] ES module imports use `.js` extension
- [ ] Async/await patterns (no raw promises)
- [ ] Const over let where applicable
**MCP Compliance:**
- [ ] Tool name follows `linear_*` convention
- [ ] Tool registered in `TOOLS` array
- [ ] Tool handler added to switch statement
- [ ] Input schema matches Zod schema
- [ ] Response format: `{ content: [{ type: 'text', text }] }`
**Linear SDK Integration:**
- [ ] Uses LinearAPIClient methods
- [ ] Results JSON-serialized (no methods/circular refs)
- [ ] Error handling in client wrapper
- [ ] Efficient API usage (filters, limits)
**Testing:**
- [ ] Manual testing with MCP client
- [ ] Tested with real Linear workspace
- [ ] Error cases handled gracefully
- [ ] Required vs optional parameters validated
**Documentation:**
- [ ] README.md updated (if user-facing)
- [ ] API_REFERENCE.md entry added/updated
- [ ] CHANGELOG.md entry added
- [ ] DEVELOPMENT.md updated (if dev workflow changes)
- [ ] JSDoc comments for public functions
## Current Status
**Enhanced Release** - 32 functional MCP tools covering comprehensive Linear operations:
- Issue management (create, update, list, search, assign, comment) with cycle assignment
- **Team management (list, get, create, update)** with full configuration support
- Workflow state listing
- **Full project management (create, update, get, list, archive, unarchive)**
- **Custom view management (create, update, get, list, delete)**
- **Complete cycle/sprint management (create, list, get, update, archive, unarchive)**
- Label management (with parent label filtering)
- User listing
**Production Ready:**
- Type-safe implementation
- Comprehensive error handling
- Full documentation suite
- MCP client integration tested
- Complete project lifecycle management
- Advanced filtering with custom views
## Building and Deploying
### IMPORTANT: Build Process
**Always use Bun for building and testing:**
```bash
# Install dependencies (first time or after package.json changes)
bun install
# Build TypeScript to JavaScript
bun run build
# Type check without building
bun run typecheck
# Lint code
bun run lint
# Format code
bun run format
# Start server (for manual testing)
bun start
```
### Development Workflow
```bash
# 1. Start watch mode for active development
bun run dev
# 2. In another terminal, test changes
bun start
# 3. Before committing
bun run typecheck
bun run lint
bun run format
```
### MCP Client Integration
**Configuration Format:**
```json
{
"mcpServers": {
"linear": {
"command": "node",
"args": ["/absolute/path/to/mcp-linearapp/dist/index.js"],
"env": {
"LINEAR_API_KEY": "lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
```
**Deployment Steps:**
1. Build the project: `bun run build`
2. Get Linear API key from https://linear.app/settings/api
3. Update your MCP client's config with absolute path and API key
4. Restart your MCP client
5. Test: "List all Linear teams"
### Environment Configuration
**Required:**
- `LINEAR_API_KEY` - Linear API key (get from https://linear.app/settings/api)
**Optional:**
- None currently
## Debugging Commands
### Build and Test
```bash
# Full build and type check
bun run build && bun run typecheck
# Check for type errors
bun run typecheck
# Check for linting issues
bun run lint
# Test server startup
bun start
# (Server will wait for stdio input)
```
### Common Issues
**"LINEAR_API_KEY is required" error:**
- Verify API key is set in environment
- Check MCP client config has `env` section
- Ensure no extra spaces in .env file
**Tool not appearing in MCP client:**
- Rebuild: `bun run build`
- Check tool registered in `TOOLS` array
- Verify absolute path in config is correct
- Restart your MCP client
**TypeScript compilation errors:**
- Run `bun run typecheck` for details
- Ensure imports use `.js` extension
- Check Zod schema types match usage
**Linear API errors:**
- Verify API key hasn't been revoked
- Check required parameters are provided
- Use list tools to get valid IDs (teams, users, projects)
- Ensure issue identifiers are case-sensitive (ENG-123, not eng-123)
**MCP client connection issues:**
- Check absolute path in config
- Verify `dist/index.js` exists (run `bun run build`)
- Look for errors in your MCP client's logs
- Ensure Bun 1.0+ or Node.js 18+ is in PATH
## Key References
### Documentation
- `README.md` - User guide, tool documentation, workflow examples
- `DEVELOPMENT.md` - Development workflow, adding tools, testing strategies
- `docs/API_REFERENCE.md` - Complete API reference for all 15 tools
- `docs/QUICK_START.md` - 5-minute setup guide
- `docs/DEPLOYMENT.md` - Deployment instructions (MCP clients, Docker, production)
- `TESTING_CHECKLIST.md` - Comprehensive testing checklist
- `docs/CHANGELOG.md` - Version history and roadmap
- `IMPLEMENTATION_SUMMARY.md` - Technical decisions, architecture overview
### External References
- **Linear API Documentation**: https://developers.linear.app/
- **Linear SDK**: https://github.com/linear/linear
- **MCP Specification**: https://modelcontextprotocol.io/
- **MCP SDK**: https://github.com/modelcontextprotocol/sdk
- **Zod Documentation**: https://zod.dev/
- **TypeScript Handbook**: https://www.typescriptlang.org/docs/handbook/intro.html
### Code Organization
- `src/index.ts` - Main entry point, tool registry, request handlers
- `src/linear-client.ts` - Linear API wrapper with error handling
- `src/schemas/index.ts` - All Zod validation schemas
- `src/tools/*.ts` - Tool handler modules (issues, teams, projects, cycles, labels, users)
## Tools Summary
### Issue Management (7 tools)
- `linear_list_issues` - List/filter issues
- `linear_create_issue` - Create new issues
- `linear_update_issue` - Update existing issues
- `linear_get_issue` - Get issue details
- `linear_search_issues` - Full-text search
- `linear_assign_issue` - Assign to user
- `linear_add_comment` - Add comments
### Team & Workflow (5 tools)
- `linear_list_teams` - List teams
- `linear_get_team` - Get team details
- `linear_create_team` - Create teams
- `linear_update_team` - Update teams
- `linear_list_workflow_states` - List workflow states
### Projects (6 tools)
- `linear_list_projects` - List/filter projects
- `linear_create_project` - Create new projects
- `linear_update_project` - Update existing projects
- `linear_get_project` - Get project details
- `linear_archive_project` - Archive projects
- `linear_unarchive_project` - Unarchive projects
### Custom Views (5 tools)
- `linear_list_custom_views` - List custom views
- `linear_create_custom_view` - Create new custom views
- `linear_update_custom_view` - Update custom views
- `linear_get_custom_view` - Get custom view details
- `linear_delete_custom_view` - Delete custom views
### Cycles/Sprints (6 tools)
- `linear_create_cycle` - Create cycles
- `linear_list_cycles` - List cycles
- `linear_get_cycle` - Get cycle details
- `linear_update_cycle` - Update cycles
- `linear_archive_cycle` - Archive cycles
- `linear_unarchive_cycle` - Unarchive cycles
### Labels (2 tools)
- `linear_create_label` - Create labels
- `linear_list_labels` - List labels
### Users (1 tool)
- `linear_list_users` - List users
## Adding New Tools
Follow this workflow when adding new Linear integrations:
### 1. Define Zod Schema
```typescript
// src/schemas/index.ts
export const LinearNewToolSchema = z.object({
requiredParam: z.string().describe('Description for LLM clients'),
optionalParam: z.number().optional().describe('Optional parameter'),
});
export type LinearNewToolInput = z.infer<typeof LinearNewToolSchema>;
```
### 2. Add LinearAPIClient Method
```typescript
// src/linear-client.ts
async newOperation(data: LinearNewToolInput) {
try {
const result = await this.client.linearSdkMethod(data);
return this.formatResult(result);
} catch (error) {
throw new Error(`Failed to perform new operation: ${this.getErrorMessage(error)}`);
}
}
```
### 3. Create Tool Handler
```typescript
// src/tools/module.ts
export async function linearNewTool(client: LinearAPIClient, args: unknown) {
const params = LinearNewToolSchema.parse(args);
const result = await client.newOperation(params);
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(result, null, 2),
},
],
};
}
```
### 4. Register Tool
```typescript
// src/index.ts
// Add to TOOLS array:
{
name: 'linear_new_tool',
description: 'Clear description for LLM clients',
inputSchema: {
type: 'object',
properties: {
requiredParam: { type: 'string', description: 'Parameter description' },
optionalParam: { type: 'number', description: 'Optional parameter' },
},
required: ['requiredParam'],
},
}
// Add to switch statement:
case 'linear_new_tool':
return await module.linearNewTool(client, args);
```
### 5. Update Documentation
- Add tool to README.md under appropriate section
- Add entry to API_REFERENCE.md with full details
- Add example usage to QUICK_START.md
- Update CHANGELOG.md
### 6. Test
- Build: `bun run build`
- Type check: `bun run typecheck`
- Test with MCP client
- Verify with real Linear workspace
## Best Practices
### TypeScript
- Enable all strict flags
- Use `const` over `let`
- Avoid `any`, use `unknown` with type guards
- Export both implementation and types
- Use async/await over raw promises
### Error Handling
- Wrap Linear SDK calls with try/catch
- Add operation context to errors
- Use Zod for input validation
- Return clear error messages
### Linear API
- Use filters instead of client-side filtering
- Respect rate limits (120/min, 5000/hour)
- Use `first` parameter to limit results
- Serialize results (remove methods/circular refs)
### MCP Protocol
- Follow tool naming convention (`linear_*`)
- Provide clear descriptions for LLM clients
- Use consistent response format
- Validate all inputs with Zod
- Return text content type
### Code Organization
- Group related tools in modules
- Centralize schemas in one file
- Keep client wrapper clean
- One handler per tool
- Clear function names
## Performance Considerations
### API Efficiency
- Use Linear's filter parameters instead of fetching all
- Leverage `first` parameter for pagination
- Consider caching for team/user lookups (change infrequently)
- Be cautious with issue caching (change frequently)
### Rate Limiting
- Linear API limits: 120 requests/min, 5000 requests/hour
- Batch operations when possible
- Add delays for bulk operations
- Handle rate limit errors gracefully
### Memory
- JSON serialize Linear objects (remove methods)
- Avoid holding large result sets
- Stream for very large operations (future enhancement)
## Future Enhancements
See CHANGELOG.md "Future Enhancements" section for planned features:
- Comments listing and management
- Issue relationships (blocks, relates to)
- Milestones management
- Notifications access
- Custom views and saved filters
- Webhooks integration
- Real-time updates
- Bulk operations
- Advanced search (multiple filters, sorting)
- Issue attachments
- Time tracking
- Custom fields