### Build and Start Server Source: https://github.com/cline/linear-mcp/blob/main/README.md Commands to build the server code and then start the Linear MCP Server. ```bash npm run build npm start ``` -------------------------------- ### Install Dependencies Source: https://github.com/cline/linear-mcp/blob/main/README.md Installs the necessary Node.js dependencies for the Linear MCP Server. ```bash npm install ``` -------------------------------- ### Environment Configuration Source: https://github.com/cline/linear-mcp/blob/main/README.md Copies the example environment file to be used for server configuration. ```bash cp .env.example .env ``` -------------------------------- ### API Key Authentication Setup Source: https://github.com/cline/linear-mcp/blob/main/README.md Configures the Linear API Key in the .env file for server authentication. ```bash LINEAR_API_KEY=your_api_key ``` -------------------------------- ### Cline MCP Server Configuration Source: https://github.com/cline/linear-mcp/blob/main/README.md Example JSON configuration for integrating the Linear MCP Server with Cline. ```json { "mcpServers": { "linear": { "command": "node", "args": ["/path/to/linear-mcp/build/index.js"], "env": { "LINEAR_API_KEY": "your_personal_access_token" }, "disabled": false, "autoApprove": [] } } } ``` -------------------------------- ### File Organization Example Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Illustrates a recommended file organization structure for features within the project, separating handlers, types, and tests for better maintainability. ```plaintext features/issues/ ├── handlers/ # Issue-related handlers │ └── issue.handler.ts ├── types/ # Issue-specific types │ └── issue.types.ts └── __tests__/ # Tests ├── issue.test.ts └── issue.integration.test.ts ``` -------------------------------- ### Caching Layer Implementation Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Provides a CacheManager class for implementing a caching layer with configurable Time-To-Live (TTL) and maximum size. It supports getting, setting, and invalidating cached data. ```typescript interface CacheConfig { ttl: number; maxSize: number; } class CacheManager { private cache: Map; get(key: string): T | undefined; set(key: string, value: T, ttl?: number): void; invalidate(pattern: string): void; } ``` -------------------------------- ### Run Tests Source: https://github.com/cline/linear-mcp/blob/main/README.md Executes the test suite for the Linear MCP Server. ```bash npm test ``` -------------------------------- ### API Documentation - Linear Client Methods Source: https://github.com/cline/linear-mcp/blob/main/todo.md Provides documentation for the LinearClient methods, including their purpose, parameters, and return values. This serves as a reference for developers using the client. ```APIDOC LinearClient: __init__(apiKey: str) apiKey: Your Linear API key. issues(params?: { filter?: string, after?: string, first?: number }): Promise Retrieves a list of issues. Supports filtering, pagination, and limiting results. Parameters: params.filter: Filter issues by a specific query. params.after: Cursor for fetching issues after a specific issue. params.first: The number of issues to fetch. Returns: A promise that resolves to an array of Issue objects. projects(params?: { filter?: string, after?: string, first?: number }): Promise Retrieves a list of projects. Supports filtering, pagination, and limiting results. Parameters: params.filter: Filter projects by a specific query. params.after: Cursor for fetching projects after a specific project. params.first: The number of projects to fetch. Returns: A promise that resolves to an array of Project objects. createIssue(input: CreateIssueInput): Promise Creates a new issue. Parameters: input: An object containing the details for the new issue (e.g., projectId, title, description). Returns: A promise that resolves to the created Issue object. updateIssue(id: string, input: UpdateIssueInput): Promise Updates an existing issue. Parameters: id: The ID of the issue to update. input: An object containing the fields to update. Returns: A promise that resolves to the updated Issue object. deleteIssue(id: string): Promise Deletes an issue. Parameters: id: The ID of the issue to delete. Returns: A promise that resolves to true if the deletion was successful, false otherwise. batchCreateIssues(input: BatchCreateIssueInput): Promise Creates multiple issues in a single batch operation. Parameters: input: An object containing the projectId and an array of issue data. Returns: A promise that resolves to an array of the created Issue objects. // ... other LinearClient methods ``` -------------------------------- ### Rich Text Description Handling Source: https://github.com/cline/linear-mcp/blob/main/README.md Explains how the server handles Linear's rich text descriptions using `documentContent` and the legacy `description` field. ```javascript // The MCP server automatically queries both fields from Linear's API // and prioritizes `documentContent.content` over the legacy `description` field. // A utility function `getProjectDescription()` provides consistent access, // returning an `actualDescription` field in responses. ``` -------------------------------- ### Linear MCP Architecture Overview Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Provides a directory structure overview of the Linear MCP codebase, highlighting core, features, infrastructure, and utility modules. ```apidoc Project Structure: src/ ├── core/ # Core infrastructure │ ├── handlers/ # Base handler and factory │ │ ├── base.handler.ts │ │ └── handler.factory.ts │ ├── types/ # Shared type definitions │ │ ├── tool.types.ts # MCP tool schemas │ │ └── common.types.ts │ └── interfaces/ # Core interfaces │ └── tool-handler.interface.ts │ ├── features/ # Feature modules by domain │ ├── auth/ # Authentication │ │ └── handlers/ │ ├── issues/ # Issue management │ │ └── handlers/ │ ├── projects/ # Project operations │ │ └── handlers/ │ ├── teams/ # Team operations │ │ └── handlers/ │ └── users/ # User operations │ └── handlers/ │ ├── infrastructure/ # Infrastructure concerns │ ├── graphql/ # GraphQL implementation │ │ ├── operations/ # GraphQL operations by domain │ │ └── fragments/ # Shared GraphQL fragments │ └── http/ # HTTP client │ └── utils/ # Shared utilities ├── logger.ts # Logging system └── config.ts # Configuration management ``` -------------------------------- ### OAuth Authentication Configuration Source: https://github.com/cline/linear-mcp/blob/main/README.md Sets up OAuth environment variables in the .env file for an alternative authentication method. ```bash LINEAR_CLIENT_ID=your_oauth_client_id LINEAR_CLIENT_SECRET=your_oauth_client_secret LINEAR_REDIRECT_URI=http://localhost:3000/callback ``` -------------------------------- ### Run Integration Tests Source: https://github.com/cline/linear-mcp/blob/main/README.md Runs integration tests, which require a LINEAR_API_KEY to be set. ```bash npm run test:integration ``` -------------------------------- ### Run Integration Tests Source: https://github.com/cline/linear-mcp/blob/main/README.md Executes the integration tests for the project. This command is typically used after setting up authentication credentials. ```bash npm run test:integration ``` -------------------------------- ### Project Description Handling Improvements Source: https://github.com/cline/linear-mcp/blob/main/README.md Details recent enhancements to how project descriptions are managed, including support for rich text content via Linear's `documentContent` field, TypeScript typing, and backward compatibility. ```typescript // Fixed empty project descriptions by implementing Linear's `documentContent` field support // Added proper TypeScript types for rich text content // Implemented automatic fallback from rich content to legacy description // Updated all project-related queries and handlers // Added comprehensive tests for new description handling // Maintained backward compatibility with existing API consumers ``` -------------------------------- ### GraphQL Client Operations Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Illustrates the Linear GraphQL client for executing operations, including atomic and composite patterns for creating projects and issues. ```typescript class LinearGraphQLClient { // Execute GraphQL operations async execute(document: DocumentNode, variables?: any): Promise; // Atomic operations async createProject(input: ProjectInput): Promise; async createBatchIssues(issues: CreateIssueInput[]): Promise; // Composite operations (built from atomic operations) async createProjectWithIssues( projectInput: ProjectInput, issues: CreateIssueInput[] ): Promise { // Creates project first, then creates issues with project reference const project = await this.createProject(projectInput); const issuesWithProject = issues.map(issue => ({ ...issue, projectId: project.projectCreate.project.id })); const batchResult = await this.createBatchIssues(issuesWithProject); return { projectCreate: project.projectCreate, issueBatchCreate: batchResult.issueBatchCreate }; } } ``` -------------------------------- ### Authentication Layer Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Details the authentication system supporting API Key and OAuth flows, including configuration options. ```typescript class AuthHandler extends BaseHandler { handleAuth(args: any): Promise; handleAuthCallback(args: any): Promise; } interface AuthConfig { type: 'apikey' | 'oauth'; accessToken?: string; clientId?: string; clientSecret?: string; redirectUri?: string; } ``` -------------------------------- ### LinearClient Mock Implementation Source: https://github.com/cline/linear-mcp/blob/main/todo.md Enhances the mock implementation of the LinearClient for testing purposes. This allows for more accurate and controlled testing of components that interact with the Linear API. ```typescript class MockLinearClient { async issues(params: any) { return [{ id: '1', title: 'Mock Issue' }]; } async projects(params: any) { return [{ id: 'p1', name: 'Mock Project' }]; } // ... other mocked methods } // Usage in tests: // const mockClient = new MockLinearClient(); // const issues = await mockClient.issues({}); ``` -------------------------------- ### Test Organization with Dedicated Config Directory Source: https://github.com/cline/linear-mcp/blob/main/todo.md Improves test organization by moving Jest configurations into a dedicated directory. This makes the project structure cleaner and configurations easier to manage. ```javascript /* Project Structure */ / ├── src/ ├── tests/ │ ├── __tests__/ // Your test files │ └── jest.config.js // Jest config file └── package.json ``` -------------------------------- ### Automated Code Formatting Source: https://github.com/cline/linear-mcp/blob/main/todo.md Implements automated code formatting using tools like Prettier. This ensures consistent code style across the project, making it more readable and maintainable. ```javascript /* .prettierrc.js */ module.exports = { semi: true, trailingComma: 'es5', singleQuote: true, printWidth: 100, tabWidth: 2, }; /* package.json scripts */ "scripts": { "format": "prettier --write '**/*.{js,ts,json}'" } ``` -------------------------------- ### Atomic Operations for Project Creation Source: https://github.com/cline/linear-mcp/blob/main/todo.md Refactors project creation to use atomic operations. This involves splitting the `createProjectWithIssues` method into smaller, more manageable, and independently testable atomic methods, ensuring proper error handling and batch issue creation. ```javascript async createProjectWithIssues(projectData, issuesData) { const project = await this.atomicCreateProject(projectData); const issues = await this.atomicBatchCreateIssues(project.id, issuesData); return { ...project, issues }; } async atomicCreateProject(data) { // ... implementation for creating a project atomically ... return createdProject; } async atomicBatchCreateIssues(projectId, issues) { // ... implementation for batch creating issues atomically ... return createdIssues; } ``` -------------------------------- ### Linear Authentication Interfaces and Implementations Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Defines the ILinearAuth interface for authentication and provides concrete implementations for OAuth and API key-based authentication. This promotes modularity and allows for different authentication strategies. ```typescript interface ILinearAuth { initialize(config: AuthConfig): void; isAuthenticated(): boolean; getClient(): LinearClient; } class OAuthLinearAuth implements ILinearAuth { // OAuth-specific implementation } class APILinearAuth implements ILinearAuth { // API-specific implementation } ``` -------------------------------- ### GraphQL Client Batch Mutations Source: https://github.com/cline/linear-mcp/blob/main/todo.md Replaces Promise.all with single GraphQL mutations for bulk operations like creating, updating, and deleting issues. This improves performance by reducing the number of network requests. ```javascript async createIssues(projectId: string, issues: IssueInput[]): Promise { const mutation = ` mutation CreateIssues($projectId: ID!, $issues: [IssueInput!]!) { createIssues(projectId: $projectId, issues: $issues) { id title description } } `; const variables = { projectId, issues }; const response = await this.graphqlClient.request(mutation, variables); return response.createIssues; } async updateIssues(updates: IssueUpdateInput[]): Promise { const mutation = ` mutation UpdateIssues($updates: [IssueUpdateInput!]!) { updateIssues(updates: $updates) { id title description } } `; const variables = { updates }; const response = await this.graphqlClient.request(mutation, variables); return response.updateIssues; } async deleteIssues(ids: string[]): Promise { const mutation = ` mutation DeleteIssues($ids: [ID!]!) { deleteIssues(ids: $ids) } `; const variables = { ids }; const response = await this.graphqlClient.request(mutation, variables); return response.deleteIssues; } ``` -------------------------------- ### Handler Architecture Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Defines the base handler with shared functionality and feature-specific handlers that extend it. Includes a factory for managing handlers. ```typescript abstract class BaseHandler { protected verifyAuth(): LinearGraphQLClient; protected createResponse(text: string): BaseToolResponse; protected createJsonResponse(data: unknown): BaseToolResponse; protected handleError(error: unknown, operation: string): never; protected validateRequiredParams(params: Record, required: string[]): void; } class IssueHandler extends BaseHandler { handleCreateIssue(args: any): Promise; handleSearchIssues(args: any): Promise; // ... other issue operations } class HandlerFactory { private authHandler: AuthHandler; private issueHandler: IssueHandler; // ... other handlers getHandlerForTool(toolName: string): { handler: BaseHandler; method: string }; } ``` -------------------------------- ### Rate Limiting Middleware Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Implements a RateLimiter class to manage and enforce rate limits on operations. It includes methods to check current limits and wait for availability. ```typescript class RateLimiter { private readonly limits: Map; private readonly windowMs: number; async checkLimit(operation: string): Promise; async waitForAvailability(operation: string): Promise; } ``` -------------------------------- ### MCP Error Handling Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Defines the structure for tool responses, including a specific interface for error responses within the MCP system. ```typescript interface BaseToolResponse { content: Array<{ type: string; text: string; }>; } interface ErrorToolResponse extends BaseToolResponse { isError: true; } ``` -------------------------------- ### Jest Configuration for ESM Modules Source: https://github.com/cline/linear-mcp/blob/main/todo.md Fixes the Jest configuration to correctly handle ECMAScript Modules (ESM). This ensures that tests can be run reliably in projects using modern JavaScript module syntax. ```javascript /* jest.config.js */ module.exports = { // ... other Jest configurations transform: { '^.+\.js$': ['babel-jest', { presets: ['@babel/preset-env'] }], '^.+\.ts$': ['ts-jest', { tsconfig: 'tsconfig.json' }], }, moduleFileExtensions: ['js', 'ts', 'json', 'node'], testEnvironment: 'node', // Add this if you are using ESM and need to transpile // transformIgnorePatterns: [ // "/node_modules/(?!axios)", // Example: if axios is ESM and needs transpilation // ], }; ``` -------------------------------- ### Type Safety in GraphQL Client Input Parameters Source: https://github.com/cline/linear-mcp/blob/main/todo.md Enhances type safety by replacing 'any' types with proper interfaces for GraphQL client input parameters. This ensures that the data passed to GraphQL mutations and queries conforms to expected structures. ```typescript interface CreateIssueInput { projectId: string; title: string; description?: string; } async createIssue(input: CreateIssueInput): Promise { const mutation = ` mutation CreateIssue($input: CreateIssueInput!) { createIssue(input: $input) { id title } } `; const variables = { input }; const response = await this.graphqlClient.request(mutation, variables); return response.createIssue; } ``` -------------------------------- ### GraphQL Client Error Handling Source: https://github.com/cline/linear-mcp/blob/main/todo.md Adds proper error handling for GraphQL errors within the client. This ensures that errors returned by the GraphQL API are caught and processed correctly. ```javascript async request(query: string, variables?: object): Promise { try { const response = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ query, variables }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(`GraphQL Error: ${errorData.errors.map((e: any) => e.message).join(', ')}`); } const data = await response.json(); if (data.errors) { throw new Error(`GraphQL Error: ${data.errors.map((e: any) => e.message).join(', ')}`); } return data.data; } catch (error) { console.error('GraphQL Request Failed:', error); throw error; } } ``` -------------------------------- ### Type Safety in GraphQL Response Handling Source: https://github.com/cline/linear-mcp/blob/main/todo.md Improves type safety by adding proper return types for GraphQL responses, particularly in issue operations. This helps prevent runtime errors caused by unexpected data structures. ```typescript interface Issue { id: string; title: string; description: string; // ... other issue properties } interface GraphQLResponse { data?: T; errors?: Array<{ message: string }>; } async getIssue(id: string): Promise { const query = ` query GetIssue($id: ID!) { issue(id: $id) { id title description } } `; const variables = { id }; const response: GraphQLResponse<{ issue: Issue }> = await this.graphqlClient.request(query, variables); if (!response.data || !response.data.issue) { throw new Error('Failed to fetch issue'); } return response.data.issue; } ``` -------------------------------- ### Type Safety in Batch Issue Creation Operations Source: https://github.com/cline/linear-mcp/blob/main/todo.md Improves type safety for batch issue creation operations. This ensures that the input data for creating multiple issues is correctly typed and validated. ```typescript interface BatchCreateIssueInput { projectId: string; issues: Array<{ title: string; description?: string }>; } async batchCreateIssues(input: BatchCreateIssueInput): Promise { // ... implementation using GraphQL batch mutation ... return createdIssues; } ``` -------------------------------- ### ESLint Rules for Type Safety Source: https://github.com/cline/linear-mcp/blob/main/todo.md Adds ESLint rules specifically focused on improving type safety in the codebase. This helps enforce best practices and catch potential type-related issues during development. ```javascript /* .eslintrc.js */ module.exports = { // ... other ESLint configurations plugins: [ '@typescript-eslint', // ... other plugins ], rules: { '@typescript-eslint/no-explicit-any': 'warn', // Warn about 'any' types '@typescript-eslint/no-unused-vars': 'error', // Error on unused variables '@typescript-eslint/explicit-function-return-type': 'error', // Require explicit return types // ... other type-safety related rules }, }; ``` -------------------------------- ### Type Safety in Project and Team Operations Source: https://github.com/cline/linear-mcp/blob/main/todo.md Enhances type safety within project and team operations by replacing 'any' types with specific interfaces. This leads to more robust and predictable code when managing projects and teams. ```typescript interface Project { id: string; name: string; teams: Team[]; } interface Team { id: string; name: string; } async getProject(projectId: string): Promise { // ... fetch project data ... return fetchedProject as Project; } async getTeamProjects(teamId: string): Promise { // ... fetch team projects ... return fetchedProjects as Project[]; } ``` -------------------------------- ### Type Safety in Execute Method Generic Constraints Source: https://github.com/cline/linear-mcp/blob/main/todo.md Improves type safety by applying proper generic constraints to the execute method. This ensures that the method operates correctly with different data types and prevents type-related errors. ```typescript async execute(operation: Operation, payload: T): Promise { // ... implementation details ... // Ensure T and R are properly constrained if necessary return this.sendRequest(operation, payload); } interface Operation { name: string; // ... other operation details } // Example usage with constraints: // async executeQuery(query: QueryOperation): Promise { // return this.execute, T>(query, query.variables); // } ``` -------------------------------- ### Custom Linear API Error Type Source: https://github.com/cline/linear-mcp/blob/main/architecture.md Defines a custom error class, LinearApiError, to represent errors specific to the Linear API. It includes error codes, operation context, and a descriptive message. ```typescript class LinearApiError extends Error { constructor( public code: string, public operation: string, message: string ) { super(message); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.