mdcontext 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/README.md +28 -0
- package/.changeset/config.json +11 -0
- package/.claude/settings.local.json +25 -0
- package/.github/workflows/ci.yml +83 -0
- package/.github/workflows/claude-code-review.yml +44 -0
- package/.github/workflows/claude.yml +85 -0
- package/.github/workflows/release.yml +113 -0
- package/.tldrignore +112 -0
- package/BACKLOG.md +338 -0
- package/CONTRIBUTING.md +186 -0
- package/NOTES/NOTES +44 -0
- package/README.md +434 -11
- package/biome.json +36 -0
- package/cspell.config.yaml +14 -0
- package/dist/chunk-23UPXDNL.js +3044 -0
- package/dist/chunk-2W7MO2DL.js +1366 -0
- package/dist/chunk-3NUAZGMA.js +1689 -0
- package/dist/chunk-7TOWB2XB.js +366 -0
- package/dist/chunk-7XOTOADQ.js +3065 -0
- package/dist/chunk-AH2PDM2K.js +3042 -0
- package/dist/chunk-BNXWSZ63.js +3742 -0
- package/dist/chunk-BTL5DJVU.js +3222 -0
- package/dist/chunk-HDHYG7E4.js +104 -0
- package/dist/chunk-HLR4KZBP.js +3234 -0
- package/dist/chunk-IP3FRFEB.js +1045 -0
- package/dist/chunk-KHU56VDO.js +3042 -0
- package/dist/chunk-KRYIFLQR.js +88 -0
- package/dist/chunk-LBSDNLEM.js +287 -0
- package/dist/chunk-MNTQ7HCP.js +2643 -0
- package/dist/chunk-MUJELQQ6.js +1387 -0
- package/dist/chunk-MXJGMSLV.js +2199 -0
- package/dist/chunk-N6QJGC3Z.js +2636 -0
- package/dist/chunk-OBELGBPM.js +1713 -0
- package/dist/chunk-OT7R5XTA.js +3192 -0
- package/dist/chunk-P7X4RA2T.js +106 -0
- package/dist/chunk-PIDUQNC2.js +3185 -0
- package/dist/chunk-POGCDIH4.js +3187 -0
- package/dist/chunk-PSIEOQGZ.js +3043 -0
- package/dist/chunk-PVRT3IHA.js +3238 -0
- package/dist/chunk-QNN4TT23.js +1430 -0
- package/dist/chunk-RE3R45RJ.js +3042 -0
- package/dist/chunk-S7E6TFX6.js +803 -0
- package/dist/chunk-SG6GLU4U.js +1378 -0
- package/dist/chunk-SJCDV2ST.js +274 -0
- package/dist/chunk-SYE5XLF3.js +104 -0
- package/dist/chunk-T5VLYBZD.js +103 -0
- package/dist/chunk-TOQB7VWU.js +3238 -0
- package/dist/chunk-VFNMZ4ZQ.js +3228 -0
- package/dist/chunk-VVTGZNBT.js +1629 -0
- package/dist/chunk-W7Q4RFEV.js +104 -0
- package/dist/chunk-XTYYVRLO.js +3190 -0
- package/dist/chunk-Y6MDYVJD.js +3063 -0
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +5458 -0
- package/dist/index.d.ts +653 -0
- package/dist/index.js +79 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +472 -0
- package/dist/schema-BAWSG7KY.js +22 -0
- package/dist/schema-E3QUPL26.js +20 -0
- package/dist/schema-EHL7WUT6.js +20 -0
- package/docs/019-USAGE.md +625 -0
- package/docs/020-current-implementation.md +364 -0
- package/docs/021-DOGFOODING-FINDINGS.md +175 -0
- package/docs/BACKLOG.md +80 -0
- package/docs/CONFIG.md +1123 -0
- package/docs/DESIGN.md +439 -0
- package/docs/ERRORS.md +383 -0
- package/docs/PROJECT.md +88 -0
- package/docs/ROADMAP.md +407 -0
- package/docs/summarization.md +320 -0
- package/docs/test-links.md +9 -0
- package/justfile +40 -0
- package/package.json +74 -9
- package/pnpm-workspace.yaml +5 -0
- package/research/INDEX.md +315 -0
- package/research/code-review/README.md +90 -0
- package/research/code-review/cli-error-handling-review.md +979 -0
- package/research/code-review/code-review-validation-report.md +464 -0
- package/research/code-review/main-ts-review.md +1128 -0
- package/research/config-analysis/01-current-implementation.md +470 -0
- package/research/config-analysis/02-strategy-recommendation.md +428 -0
- package/research/config-analysis/03-task-candidates.md +715 -0
- package/research/config-analysis/033-research-configuration-management.md +828 -0
- package/research/config-analysis/034-research-effect-cli-config.md +1504 -0
- package/research/config-analysis/04-consolidated-task-candidates.md +277 -0
- package/research/config-docs/SUMMARY.md +357 -0
- package/research/config-docs/TEST-RESULTS.md +776 -0
- package/research/config-docs/TODO.md +542 -0
- package/research/config-docs/analysis.md +744 -0
- package/research/config-docs/fix-validation.md +502 -0
- package/research/config-docs/help-audit.md +264 -0
- package/research/config-docs/help-system-analysis.md +890 -0
- package/research/dogfood/consolidated-tool-evaluation.md +373 -0
- package/research/dogfood/strategy-a/a-synthesis.md +184 -0
- package/research/dogfood/strategy-a/a1-docs.md +226 -0
- package/research/dogfood/strategy-a/a2-amorphic.md +156 -0
- package/research/dogfood/strategy-a/a3-llm.md +164 -0
- package/research/dogfood/strategy-b/b-synthesis.md +228 -0
- package/research/dogfood/strategy-b/b1-architecture.md +207 -0
- package/research/dogfood/strategy-b/b2-gaps.md +258 -0
- package/research/dogfood/strategy-b/b3-workflows.md +250 -0
- package/research/dogfood/strategy-c/c-synthesis.md +451 -0
- package/research/dogfood/strategy-c/c1-explorer.md +192 -0
- package/research/dogfood/strategy-c/c2-diver-memory.md +145 -0
- package/research/dogfood/strategy-c/c3-diver-control.md +148 -0
- package/research/dogfood/strategy-c/c4-diver-failure.md +151 -0
- package/research/dogfood/strategy-c/c5-diver-execution.md +221 -0
- package/research/dogfood/strategy-c/c6-diver-org.md +221 -0
- package/research/effect-cli-error-handling.md +845 -0
- package/research/effect-errors-as-values.md +943 -0
- package/research/errors-task-analysis/00-consolidated-tasks.md +207 -0
- package/research/errors-task-analysis/cli-commands-analysis.md +909 -0
- package/research/errors-task-analysis/embeddings-analysis.md +709 -0
- package/research/errors-task-analysis/index-search-analysis.md +812 -0
- package/research/frontmatter/COMMENTS-ARE-SKIPPED.md +149 -0
- package/research/frontmatter/LLM-CODE-NAVIGATION.md +276 -0
- package/research/issue-review.md +603 -0
- package/research/llm-summarization/agent-cli-tools-2026.md +1082 -0
- package/research/llm-summarization/alternative-providers-2026.md +1428 -0
- package/research/llm-summarization/anthropic-2026.md +367 -0
- package/research/llm-summarization/claude-cli-integration.md +1706 -0
- package/research/llm-summarization/cli-integration-patterns.md +3155 -0
- package/research/llm-summarization/openai-2026.md +473 -0
- package/research/llm-summarization/openai-compatible-providers-2026.md +1022 -0
- package/research/llm-summarization/opencode-cli-integration.md +1552 -0
- package/research/llm-summarization/prompt-engineering-2026.md +1426 -0
- package/research/llm-summarization/prototype-results.md +56 -0
- package/research/llm-summarization/provider-switching-patterns-2026.md +2153 -0
- package/research/llm-summarization/typescript-llm-libraries-2026.md +2436 -0
- package/research/mdcontext-error-analysis.md +521 -0
- package/research/mdcontext-pudding/00-EXECUTIVE-SUMMARY.md +282 -0
- package/research/mdcontext-pudding/01-index-embed.md +956 -0
- package/research/mdcontext-pudding/02-search-COMMANDS.md +142 -0
- package/research/mdcontext-pudding/02-search-SUMMARY.md +146 -0
- package/research/mdcontext-pudding/02-search.md +970 -0
- package/research/mdcontext-pudding/03-context.md +779 -0
- package/research/mdcontext-pudding/04-navigation-and-analytics.md +803 -0
- package/research/mdcontext-pudding/04-tree.md +704 -0
- package/research/mdcontext-pudding/05-config.md +1038 -0
- package/research/mdcontext-pudding/06-links-summary.txt +87 -0
- package/research/mdcontext-pudding/06-links.md +679 -0
- package/research/mdcontext-pudding/07-stats.md +693 -0
- package/research/mdcontext-pudding/BUG-FIX-PLAN.md +388 -0
- package/research/mdcontext-pudding/P0-BUG-VALIDATION.md +167 -0
- package/research/mdcontext-pudding/README.md +168 -0
- package/research/mdcontext-pudding/TESTING-SUMMARY.md +128 -0
- package/research/npm_publish/011-npm-workflow-research-agent2.md +792 -0
- package/research/npm_publish/012-npm-workflow-research-agent1.md +530 -0
- package/research/npm_publish/013-npm-workflow-research-agent3.md +722 -0
- package/research/npm_publish/014-npm-workflow-synthesis.md +556 -0
- package/research/npm_publish/031-npm-workflow-task-analysis.md +134 -0
- package/research/research-quality-review.md +834 -0
- package/research/semantic-search/002-research-embedding-models.md +490 -0
- package/research/semantic-search/003-research-rag-alternatives.md +523 -0
- package/research/semantic-search/004-research-vector-search.md +841 -0
- package/research/semantic-search/032-research-semantic-search.md +427 -0
- package/research/semantic-search/embedding-text-analysis.md +156 -0
- package/research/semantic-search/multi-word-failure-reproduction.md +171 -0
- package/research/semantic-search/query-processing-analysis.md +207 -0
- package/research/semantic-search/root-cause-and-solution.md +114 -0
- package/research/semantic-search/threshold-validation-report.md +69 -0
- package/research/semantic-search/vector-search-analysis.md +63 -0
- package/research/task-management-2026/00-synthesis-recommendations.md +295 -0
- package/research/task-management-2026/01-ai-workflow-tools.md +416 -0
- package/research/task-management-2026/02-agent-framework-patterns.md +476 -0
- package/research/task-management-2026/03-lightweight-file-based.md +567 -0
- package/research/task-management-2026/04-established-tools-ai-features.md +541 -0
- package/research/task-management-2026/linear/01-core-features-workflow.md +771 -0
- package/research/task-management-2026/linear/02-api-integrations.md +930 -0
- package/research/task-management-2026/linear/03-ai-features.md +368 -0
- package/research/task-management-2026/linear/04-pricing-setup.md +205 -0
- package/research/task-management-2026/linear/05-usage-patterns-best-practices.md +605 -0
- package/research/test-path-issues.md +276 -0
- package/review/ALP-76/1-error-type-design.md +962 -0
- package/review/ALP-76/2-error-handling-patterns.md +906 -0
- package/review/ALP-76/3-error-presentation.md +624 -0
- package/review/ALP-76/4-test-coverage.md +625 -0
- package/review/ALP-76/5-migration-completeness.md +440 -0
- package/review/ALP-76/6-effect-best-practices.md +755 -0
- package/scripts/apply-branch-protection.sh +47 -0
- package/scripts/branch-protection-templates.json +79 -0
- package/scripts/prototype-summarization.ts +346 -0
- package/scripts/rebuild-hnswlib.js +58 -0
- package/scripts/setup-branch-protection.sh +64 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/active-provider.json +7 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.json +541 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.meta.json +5 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/config.json +8 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/documents.json +60 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/links.json +13 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/sections.json +1197 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/configuration-management.md +99 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/distributed-systems.md +92 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/error-handling.md +78 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/failure-automation.md +55 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/job-context.md +69 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/process-orchestration.md +99 -0
- package/src/cli/argv-preprocessor.test.ts +210 -0
- package/src/cli/argv-preprocessor.ts +202 -0
- package/src/cli/cli.test.ts +627 -0
- package/src/cli/commands/backlinks.ts +54 -0
- package/src/cli/commands/config-cmd.ts +642 -0
- package/src/cli/commands/context.ts +285 -0
- package/src/cli/commands/duplicates.ts +122 -0
- package/src/cli/commands/embeddings.ts +529 -0
- package/src/cli/commands/index-cmd.ts +480 -0
- package/src/cli/commands/index.ts +16 -0
- package/src/cli/commands/links.ts +52 -0
- package/src/cli/commands/search.ts +1281 -0
- package/src/cli/commands/stats.ts +149 -0
- package/src/cli/commands/tree.ts +128 -0
- package/src/cli/config-layer.ts +176 -0
- package/src/cli/error-handler.test.ts +235 -0
- package/src/cli/error-handler.ts +655 -0
- package/src/cli/flag-schemas.ts +341 -0
- package/src/cli/help.ts +588 -0
- package/src/cli/index.ts +9 -0
- package/src/cli/main.ts +435 -0
- package/src/cli/options.ts +41 -0
- package/src/cli/shared-error-handling.ts +199 -0
- package/src/cli/typo-suggester.test.ts +105 -0
- package/src/cli/typo-suggester.ts +130 -0
- package/src/cli/utils.ts +259 -0
- package/src/config/file-provider.test.ts +320 -0
- package/src/config/file-provider.ts +273 -0
- package/src/config/index.ts +72 -0
- package/src/config/integration.test.ts +667 -0
- package/src/config/precedence.test.ts +277 -0
- package/src/config/precedence.ts +451 -0
- package/src/config/schema.test.ts +414 -0
- package/src/config/schema.ts +603 -0
- package/src/config/service.test.ts +320 -0
- package/src/config/service.ts +243 -0
- package/src/config/testing.test.ts +264 -0
- package/src/config/testing.ts +110 -0
- package/src/core/index.ts +1 -0
- package/src/core/types.ts +113 -0
- package/src/duplicates/detector.test.ts +183 -0
- package/src/duplicates/detector.ts +414 -0
- package/src/duplicates/index.ts +18 -0
- package/src/embeddings/embedding-namespace.test.ts +300 -0
- package/src/embeddings/embedding-namespace.ts +947 -0
- package/src/embeddings/heading-boost.test.ts +222 -0
- package/src/embeddings/hnsw-build-options.test.ts +198 -0
- package/src/embeddings/hyde.test.ts +272 -0
- package/src/embeddings/hyde.ts +264 -0
- package/src/embeddings/index.ts +10 -0
- package/src/embeddings/openai-provider.ts +414 -0
- package/src/embeddings/pricing.json +22 -0
- package/src/embeddings/provider-constants.ts +204 -0
- package/src/embeddings/provider-errors.test.ts +967 -0
- package/src/embeddings/provider-errors.ts +565 -0
- package/src/embeddings/provider-factory.test.ts +240 -0
- package/src/embeddings/provider-factory.ts +225 -0
- package/src/embeddings/provider-integration.test.ts +788 -0
- package/src/embeddings/query-preprocessing.test.ts +187 -0
- package/src/embeddings/semantic-search-threshold.test.ts +508 -0
- package/src/embeddings/semantic-search.ts +1270 -0
- package/src/embeddings/types.ts +359 -0
- package/src/embeddings/vector-store.ts +708 -0
- package/src/embeddings/voyage-provider.ts +313 -0
- package/src/errors/errors.test.ts +845 -0
- package/src/errors/index.ts +533 -0
- package/src/index/ignore-patterns.test.ts +354 -0
- package/src/index/ignore-patterns.ts +305 -0
- package/src/index/index.ts +4 -0
- package/src/index/indexer.ts +684 -0
- package/src/index/storage.ts +260 -0
- package/src/index/types.ts +147 -0
- package/src/index/watcher.ts +189 -0
- package/src/index.ts +30 -0
- package/src/integration/search-keyword.test.ts +678 -0
- package/src/mcp/server.ts +612 -0
- package/src/parser/index.ts +1 -0
- package/src/parser/parser.test.ts +291 -0
- package/src/parser/parser.ts +394 -0
- package/src/parser/section-filter.test.ts +277 -0
- package/src/parser/section-filter.ts +392 -0
- package/src/search/__tests__/hybrid-search.test.ts +650 -0
- package/src/search/bm25-store.ts +366 -0
- package/src/search/cross-encoder.test.ts +253 -0
- package/src/search/cross-encoder.ts +406 -0
- package/src/search/fuzzy-search.test.ts +419 -0
- package/src/search/fuzzy-search.ts +273 -0
- package/src/search/hybrid-search.ts +448 -0
- package/src/search/path-matcher.test.ts +276 -0
- package/src/search/path-matcher.ts +33 -0
- package/src/search/query-parser.test.ts +260 -0
- package/src/search/query-parser.ts +319 -0
- package/src/search/searcher.test.ts +280 -0
- package/src/search/searcher.ts +724 -0
- package/src/search/wink-bm25.d.ts +30 -0
- package/src/summarization/cli-providers/claude.ts +202 -0
- package/src/summarization/cli-providers/detection.test.ts +273 -0
- package/src/summarization/cli-providers/detection.ts +118 -0
- package/src/summarization/cli-providers/index.ts +8 -0
- package/src/summarization/cost.test.ts +139 -0
- package/src/summarization/cost.ts +102 -0
- package/src/summarization/error-handler.test.ts +127 -0
- package/src/summarization/error-handler.ts +111 -0
- package/src/summarization/index.ts +102 -0
- package/src/summarization/pipeline.test.ts +498 -0
- package/src/summarization/pipeline.ts +231 -0
- package/src/summarization/prompts.test.ts +269 -0
- package/src/summarization/prompts.ts +133 -0
- package/src/summarization/provider-factory.test.ts +396 -0
- package/src/summarization/provider-factory.ts +178 -0
- package/src/summarization/types.ts +184 -0
- package/src/summarize/budget-bugs.test.ts +620 -0
- package/src/summarize/formatters.ts +419 -0
- package/src/summarize/index.ts +20 -0
- package/src/summarize/summarizer.test.ts +275 -0
- package/src/summarize/summarizer.ts +597 -0
- package/src/summarize/verify-bugs.test.ts +238 -0
- package/src/types/huggingface-transformers.d.ts +66 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/tokens.test.ts +142 -0
- package/src/utils/tokens.ts +186 -0
- package/tests/fixtures/cli/.mdcontext/active-provider.json +7 -0
- package/tests/fixtures/cli/.mdcontext/config.json +8 -0
- package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/indexes/documents.json +33 -0
- package/tests/fixtures/cli/.mdcontext/indexes/links.json +12 -0
- package/tests/fixtures/cli/.mdcontext/indexes/sections.json +247 -0
- package/tests/fixtures/cli/README.md +9 -0
- package/tests/fixtures/cli/api-reference.md +11 -0
- package/tests/fixtures/cli/getting-started.md +11 -0
- package/tests/integration/embed-index.test.ts +712 -0
- package/tests/integration/search-context.test.ts +469 -0
- package/tests/integration/search-semantic.test.ts +522 -0
- package/tsconfig.json +26 -0
- package/vitest.config.ts +16 -0
- package/vitest.setup.ts +12 -0
|
@@ -0,0 +1,930 @@
|
|
|
1
|
+
# Linear API and Integrations for AI/Automation Workflows (2026)
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Linear provides a comprehensive GraphQL API that powers both their internal applications and external integrations. The API supports full CRUD operations on all entities, real-time webhooks, and multiple authentication methods. Linear has also embraced the AI ecosystem with an official MCP server for Claude integration.
|
|
6
|
+
|
|
7
|
+
**API Endpoint**: `https://api.linear.app/graphql`
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## GraphQL API Capabilities
|
|
12
|
+
|
|
13
|
+
### Authentication Methods
|
|
14
|
+
|
|
15
|
+
**1. Personal API Keys**
|
|
16
|
+
|
|
17
|
+
- Create at `https://linear.app/settings/api`
|
|
18
|
+
- Best for personal scripts and local development
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
curl \
|
|
22
|
+
-X POST \
|
|
23
|
+
-H "Content-Type: application/json" \
|
|
24
|
+
-H "Authorization: <API_KEY>" \
|
|
25
|
+
--data '{ "query": "{ issues { nodes { id title } } }" }' \
|
|
26
|
+
https://api.linear.app/graphql
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**2. OAuth 2.0**
|
|
30
|
+
|
|
31
|
+
- Recommended for applications used by others
|
|
32
|
+
- Supports dynamic client registration for MCP servers
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
curl \
|
|
36
|
+
-X POST \
|
|
37
|
+
-H "Content-Type: application/json" \
|
|
38
|
+
-H "Authorization: Bearer <ACCESS_TOKEN>" \
|
|
39
|
+
--data '{ "query": "{ issues { nodes { id title } } }" }' \
|
|
40
|
+
https://api.linear.app/graphql
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Query Operations (Read)
|
|
44
|
+
|
|
45
|
+
**Get Current User**
|
|
46
|
+
|
|
47
|
+
```graphql
|
|
48
|
+
query Me {
|
|
49
|
+
viewer {
|
|
50
|
+
id
|
|
51
|
+
name
|
|
52
|
+
email
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Fetch All Teams**
|
|
58
|
+
|
|
59
|
+
```graphql
|
|
60
|
+
query Teams {
|
|
61
|
+
teams {
|
|
62
|
+
nodes {
|
|
63
|
+
id
|
|
64
|
+
name
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Get Team Issues**
|
|
71
|
+
|
|
72
|
+
```graphql
|
|
73
|
+
query Team {
|
|
74
|
+
team(id: "9cfb482a-81e3-4154-b5b9-2c805e70a02d") {
|
|
75
|
+
id
|
|
76
|
+
name
|
|
77
|
+
issues {
|
|
78
|
+
nodes {
|
|
79
|
+
id
|
|
80
|
+
title
|
|
81
|
+
description
|
|
82
|
+
assignee {
|
|
83
|
+
id
|
|
84
|
+
name
|
|
85
|
+
}
|
|
86
|
+
createdAt
|
|
87
|
+
archivedAt
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Get Single Issue by Identifier**
|
|
95
|
+
|
|
96
|
+
```graphql
|
|
97
|
+
query Issue {
|
|
98
|
+
issue(id: "BLA-123") {
|
|
99
|
+
id
|
|
100
|
+
title
|
|
101
|
+
description
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Issues Assigned to User**
|
|
107
|
+
|
|
108
|
+
```graphql
|
|
109
|
+
query {
|
|
110
|
+
user(id: "USERID") {
|
|
111
|
+
id
|
|
112
|
+
name
|
|
113
|
+
assignedIssues {
|
|
114
|
+
nodes {
|
|
115
|
+
id
|
|
116
|
+
title
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Workflow States**
|
|
124
|
+
|
|
125
|
+
```graphql
|
|
126
|
+
query {
|
|
127
|
+
workflowStates {
|
|
128
|
+
nodes {
|
|
129
|
+
id
|
|
130
|
+
name
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Mutation Operations (Create/Update)
|
|
137
|
+
|
|
138
|
+
**Create Issue**
|
|
139
|
+
|
|
140
|
+
```graphql
|
|
141
|
+
mutation IssueCreate {
|
|
142
|
+
issueCreate(
|
|
143
|
+
input: {
|
|
144
|
+
title: "New exception"
|
|
145
|
+
description: "More detailed error report in markdown"
|
|
146
|
+
teamId: "9cfb482a-81e3-4154-b5b9-2c805e70a02d"
|
|
147
|
+
}
|
|
148
|
+
) {
|
|
149
|
+
success
|
|
150
|
+
issue {
|
|
151
|
+
id
|
|
152
|
+
title
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Create Issue with All Common Fields**
|
|
159
|
+
|
|
160
|
+
```graphql
|
|
161
|
+
mutation IssueCreate {
|
|
162
|
+
issueCreate(
|
|
163
|
+
input: {
|
|
164
|
+
title: "Bug: Login fails on mobile"
|
|
165
|
+
description: "Users report login button unresponsive on iOS Safari"
|
|
166
|
+
teamId: "YOUR_TEAM_ID"
|
|
167
|
+
priority: 2
|
|
168
|
+
labelIds: ["label-id-1", "label-id-2"]
|
|
169
|
+
assigneeId: "assignee-user-id"
|
|
170
|
+
estimate: 3
|
|
171
|
+
projectId: "project-id"
|
|
172
|
+
stateId: "workflow-state-id"
|
|
173
|
+
}
|
|
174
|
+
) {
|
|
175
|
+
success
|
|
176
|
+
issue {
|
|
177
|
+
id
|
|
178
|
+
title
|
|
179
|
+
identifier
|
|
180
|
+
priority
|
|
181
|
+
priorityLabel
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Priority Values**:
|
|
188
|
+
|
|
189
|
+
- 0: No priority
|
|
190
|
+
- 1: Urgent
|
|
191
|
+
- 2: High
|
|
192
|
+
- 3: Medium
|
|
193
|
+
- 4: Low
|
|
194
|
+
|
|
195
|
+
**Estimate Values** (T-shirt sizes):
|
|
196
|
+
|
|
197
|
+
- 1: XS
|
|
198
|
+
- 2: S
|
|
199
|
+
- 3: M
|
|
200
|
+
- 5: L
|
|
201
|
+
- 8: XL
|
|
202
|
+
- 13: XXL
|
|
203
|
+
- 21: XXXL
|
|
204
|
+
|
|
205
|
+
**Update Issue**
|
|
206
|
+
|
|
207
|
+
```graphql
|
|
208
|
+
mutation IssueUpdate {
|
|
209
|
+
issueUpdate(
|
|
210
|
+
id: "BLA-123"
|
|
211
|
+
input: { title: "New Issue Title", stateId: "NEW-STATE-ID" }
|
|
212
|
+
) {
|
|
213
|
+
success
|
|
214
|
+
issue {
|
|
215
|
+
id
|
|
216
|
+
title
|
|
217
|
+
state {
|
|
218
|
+
id
|
|
219
|
+
name
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Pagination
|
|
227
|
+
|
|
228
|
+
Linear uses Relay-style cursor-based pagination with `first`/`after` and `last`/`before` arguments.
|
|
229
|
+
|
|
230
|
+
**Basic Pagination**
|
|
231
|
+
|
|
232
|
+
```graphql
|
|
233
|
+
query Issues {
|
|
234
|
+
issues(first: 10) {
|
|
235
|
+
edges {
|
|
236
|
+
node {
|
|
237
|
+
id
|
|
238
|
+
title
|
|
239
|
+
}
|
|
240
|
+
cursor
|
|
241
|
+
}
|
|
242
|
+
pageInfo {
|
|
243
|
+
hasNextPage
|
|
244
|
+
endCursor
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Subsequent Page Request**
|
|
251
|
+
|
|
252
|
+
```graphql
|
|
253
|
+
query Issues {
|
|
254
|
+
issues(first: 10, after: "CURSOR_FROM_PREVIOUS_RESPONSE") {
|
|
255
|
+
edges {
|
|
256
|
+
node {
|
|
257
|
+
id
|
|
258
|
+
title
|
|
259
|
+
}
|
|
260
|
+
cursor
|
|
261
|
+
}
|
|
262
|
+
pageInfo {
|
|
263
|
+
hasNextPage
|
|
264
|
+
endCursor
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Simplified Node Syntax** (without edges)
|
|
271
|
+
|
|
272
|
+
```graphql
|
|
273
|
+
query Teams {
|
|
274
|
+
teams {
|
|
275
|
+
nodes {
|
|
276
|
+
id
|
|
277
|
+
name
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Ordering Results**
|
|
284
|
+
|
|
285
|
+
```graphql
|
|
286
|
+
query Issues {
|
|
287
|
+
issues(orderBy: updatedAt) {
|
|
288
|
+
nodes {
|
|
289
|
+
id
|
|
290
|
+
identifier
|
|
291
|
+
title
|
|
292
|
+
createdAt
|
|
293
|
+
updatedAt
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Default Behavior**:
|
|
300
|
+
|
|
301
|
+
- 50 results returned by default
|
|
302
|
+
- Results ordered by `createdAt`
|
|
303
|
+
- Archived resources hidden by default (use `includeArchived: true` to include)
|
|
304
|
+
|
|
305
|
+
### Rate Limiting
|
|
306
|
+
|
|
307
|
+
Linear uses complexity-based rate limiting with a leaky bucket algorithm.
|
|
308
|
+
|
|
309
|
+
| Authentication Type | Requests/Hour | Complexity Points/Hour |
|
|
310
|
+
| ------------------- | ------------- | ---------------------- |
|
|
311
|
+
| API Key | 1,500 | 250,000 |
|
|
312
|
+
| OAuth App | 500 | 200,000 |
|
|
313
|
+
| Unauthenticated | 60 | 10,000 |
|
|
314
|
+
|
|
315
|
+
**Best Practices**:
|
|
316
|
+
|
|
317
|
+
- Use webhooks instead of polling
|
|
318
|
+
- Specify explicit `first`/`last` limits to reduce complexity
|
|
319
|
+
- Filter in GraphQL queries, not in code
|
|
320
|
+
- Avoid fetching data you do not need
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Bulk Issue Creation
|
|
325
|
+
|
|
326
|
+
Linear does not have a dedicated bulk mutation endpoint. Use GraphQL aliases to batch multiple mutations in a single request.
|
|
327
|
+
|
|
328
|
+
**Batch Create Issues**
|
|
329
|
+
|
|
330
|
+
```graphql
|
|
331
|
+
mutation BulkCreate {
|
|
332
|
+
issue1: issueCreate(
|
|
333
|
+
input: { title: "Issue 1", teamId: "TEAM_ID", priority: 2 }
|
|
334
|
+
) {
|
|
335
|
+
success
|
|
336
|
+
issue {
|
|
337
|
+
id
|
|
338
|
+
identifier
|
|
339
|
+
title
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
issue2: issueCreate(
|
|
343
|
+
input: { title: "Issue 2", teamId: "TEAM_ID", priority: 3 }
|
|
344
|
+
) {
|
|
345
|
+
success
|
|
346
|
+
issue {
|
|
347
|
+
id
|
|
348
|
+
identifier
|
|
349
|
+
title
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
issue3: issueCreate(
|
|
353
|
+
input: { title: "Issue 3", teamId: "TEAM_ID", priority: 3 }
|
|
354
|
+
) {
|
|
355
|
+
success
|
|
356
|
+
issue {
|
|
357
|
+
id
|
|
358
|
+
identifier
|
|
359
|
+
title
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**Important**: GraphQL mutations execute in series (not parallel), so large batches may hit timeouts or rate limits. Recommended approach for high-volume operations:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
import { LinearClient } from "@linear/sdk";
|
|
369
|
+
|
|
370
|
+
const client = new LinearClient({ apiKey: process.env.LINEAR_API_KEY });
|
|
371
|
+
|
|
372
|
+
async function bulkCreateIssues(
|
|
373
|
+
issues: Array<{ title: string; description?: string }>,
|
|
374
|
+
teamId: string,
|
|
375
|
+
) {
|
|
376
|
+
const results = [];
|
|
377
|
+
|
|
378
|
+
for (const issue of issues) {
|
|
379
|
+
const result = await client.createIssue({
|
|
380
|
+
title: issue.title,
|
|
381
|
+
description: issue.description,
|
|
382
|
+
teamId,
|
|
383
|
+
});
|
|
384
|
+
results.push(result);
|
|
385
|
+
|
|
386
|
+
// Add delay to respect rate limits
|
|
387
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return results;
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## TypeScript SDK
|
|
397
|
+
|
|
398
|
+
### Installation
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
npm install @linear/sdk
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Authentication
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
import { LinearClient } from "@linear/sdk";
|
|
408
|
+
|
|
409
|
+
// API Key authentication
|
|
410
|
+
const client = new LinearClient({
|
|
411
|
+
apiKey: process.env.LINEAR_API_KEY,
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// OAuth authentication
|
|
415
|
+
const oauthClient = new LinearClient({
|
|
416
|
+
accessToken: process.env.LINEAR_OAUTH_TOKEN,
|
|
417
|
+
});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Getting Current User
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
import { LinearClient, LinearFetch, User } from "@linear/sdk";
|
|
424
|
+
|
|
425
|
+
const linearClient = new LinearClient({ apiKey });
|
|
426
|
+
|
|
427
|
+
async function getCurrentUser(): LinearFetch<User> {
|
|
428
|
+
return linearClient.viewer;
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Querying Issues
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
async function getMyIssues() {
|
|
436
|
+
const me = await linearClient.viewer;
|
|
437
|
+
const myIssues = await me.assignedIssues();
|
|
438
|
+
|
|
439
|
+
if (myIssues.nodes.length) {
|
|
440
|
+
myIssues.nodes.map((issue) =>
|
|
441
|
+
console.log(`${me.displayName} has issue: ${issue.title}`),
|
|
442
|
+
);
|
|
443
|
+
} else {
|
|
444
|
+
console.log(`${me.displayName} has no issues`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
getMyIssues();
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Promise-Based Alternative
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
linearClient.viewer.then((me) => {
|
|
455
|
+
return me.assignedIssues().then((myIssues) => {
|
|
456
|
+
if (myIssues.nodes.length) {
|
|
457
|
+
myIssues.nodes.map((issue) =>
|
|
458
|
+
console.log(`${me.displayName} has issue: ${issue.title}`),
|
|
459
|
+
);
|
|
460
|
+
} else {
|
|
461
|
+
console.log(`${me.displayName} has no issues`);
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Raw GraphQL Access
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
import { LinearGraphQLClient } from "@linear/sdk";
|
|
471
|
+
|
|
472
|
+
const graphQLClient = new LinearGraphQLClient(apiKey);
|
|
473
|
+
|
|
474
|
+
const response = await graphQLClient.rawRequest(`
|
|
475
|
+
query {
|
|
476
|
+
issues(first: 10) {
|
|
477
|
+
nodes {
|
|
478
|
+
id
|
|
479
|
+
title
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
`);
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Custom Headers
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
const client = new LinearClient({
|
|
490
|
+
apiKey,
|
|
491
|
+
headers: { "my-header": "value" },
|
|
492
|
+
});
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## MCP Servers for Claude Integration
|
|
498
|
+
|
|
499
|
+
### Official Linear MCP Server
|
|
500
|
+
|
|
501
|
+
Linear provides an officially supported MCP server for AI integration.
|
|
502
|
+
|
|
503
|
+
**Transport Options**:
|
|
504
|
+
|
|
505
|
+
- HTTP (Streamable): `https://mcp.linear.app/mcp` (recommended)
|
|
506
|
+
- SSE: `https://mcp.linear.app/sse`
|
|
507
|
+
|
|
508
|
+
**Claude Code Setup**:
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
claude mcp add --transport http linear-server https://mcp.linear.app/mcp
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Then run `/mcp` in Claude Code to authenticate.
|
|
515
|
+
|
|
516
|
+
**Available Tools**:
|
|
517
|
+
|
|
518
|
+
- Search and find issues, projects, and comments
|
|
519
|
+
- Create new issues
|
|
520
|
+
- Update existing issues
|
|
521
|
+
- Add comments to issues
|
|
522
|
+
- More functionality planned
|
|
523
|
+
|
|
524
|
+
**Authentication**:
|
|
525
|
+
|
|
526
|
+
- OAuth 2.1 with dynamic client registration (interactive flow)
|
|
527
|
+
- Direct API key/OAuth token via `Authorization: Bearer <token>` header
|
|
528
|
+
|
|
529
|
+
**Claude Desktop Configuration** (`claude_desktop_config.json`):
|
|
530
|
+
|
|
531
|
+
```json
|
|
532
|
+
{
|
|
533
|
+
"mcpServers": {
|
|
534
|
+
"linear": {
|
|
535
|
+
"command": "npx",
|
|
536
|
+
"args": ["mcp-remote", "https://mcp.linear.app/mcp"]
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
**Troubleshooting**:
|
|
543
|
+
|
|
544
|
+
- Clear cached auth: `rm -rf ~/.mcp-auth`
|
|
545
|
+
- WSL users: Use `--transport sse-only` flag
|
|
546
|
+
|
|
547
|
+
### Community MCP Server (jerhadf/linear-mcp-server)
|
|
548
|
+
|
|
549
|
+
**Note**: Deprecated in favor of official Linear MCP server.
|
|
550
|
+
|
|
551
|
+
**Installation**:
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
npx @smithery/cli install linear-mcp-server --client claude
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
**Manual Configuration**:
|
|
558
|
+
|
|
559
|
+
```json
|
|
560
|
+
{
|
|
561
|
+
"mcpServers": {
|
|
562
|
+
"linear": {
|
|
563
|
+
"command": "npx",
|
|
564
|
+
"args": ["-y", "linear-mcp-server"],
|
|
565
|
+
"env": { "LINEAR_API_KEY": "your_key_here" }
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Available Tools**:
|
|
572
|
+
|
|
573
|
+
1. **Issue Creation** - Create issues with title, team ID, description, priority (0-4), status
|
|
574
|
+
2. **Issue Updates** - Modify issues via ID (title, description, priority, status)
|
|
575
|
+
3. **Issue Searching** - Filter by query, team, status, assignee, labels, priority
|
|
576
|
+
4. **User Issue Retrieval** - Fetch assigned tasks
|
|
577
|
+
5. **Comment Addition** - Add markdown comments to issues
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## Webhooks and Automation Triggers
|
|
582
|
+
|
|
583
|
+
### Supported Events
|
|
584
|
+
|
|
585
|
+
**Data Change Webhooks**:
|
|
586
|
+
|
|
587
|
+
- Issues, Issue attachments, Issue comments, Issue labels
|
|
588
|
+
- Comment reactions
|
|
589
|
+
- Projects, Project updates
|
|
590
|
+
- Documents
|
|
591
|
+
- Initiatives, Initiative Updates
|
|
592
|
+
- Cycles
|
|
593
|
+
- Customers, Customer Requests
|
|
594
|
+
- Users
|
|
595
|
+
- Issue SLA
|
|
596
|
+
- OAuthApp revoked
|
|
597
|
+
|
|
598
|
+
### Configuration
|
|
599
|
+
|
|
600
|
+
Webhooks require admin permissions. Configure via:
|
|
601
|
+
|
|
602
|
+
- Linear Settings: `https://linear.app/settings/api`
|
|
603
|
+
- GraphQL API mutations
|
|
604
|
+
|
|
605
|
+
**Create Webhook via GraphQL**:
|
|
606
|
+
|
|
607
|
+
```graphql
|
|
608
|
+
mutation {
|
|
609
|
+
webhookCreate(
|
|
610
|
+
input: {
|
|
611
|
+
url: "https://your-server.com/webhook"
|
|
612
|
+
teamId: "team-id"
|
|
613
|
+
resourceTypes: ["Issue", "Comment"]
|
|
614
|
+
}
|
|
615
|
+
) {
|
|
616
|
+
success
|
|
617
|
+
webhook {
|
|
618
|
+
id
|
|
619
|
+
secret
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### Payload Structure
|
|
626
|
+
|
|
627
|
+
**HTTP Headers**:
|
|
628
|
+
|
|
629
|
+
- `Linear-Delivery`: UUID identifying the payload
|
|
630
|
+
- `Linear-Event`: Entity type (Issue, Comment, etc.)
|
|
631
|
+
- `Linear-Signature`: HMAC-SHA256 signature
|
|
632
|
+
- `User-Agent`: `Linear-Webhook`
|
|
633
|
+
|
|
634
|
+
**Body Fields**:
|
|
635
|
+
|
|
636
|
+
```json
|
|
637
|
+
{
|
|
638
|
+
"action": "create | update | remove",
|
|
639
|
+
"type": "Issue",
|
|
640
|
+
"actor": { "id": "user-id", "name": "User Name" },
|
|
641
|
+
"createdAt": "2026-01-21T10:00:00.000Z",
|
|
642
|
+
"data": {
|
|
643
|
+
/* serialized entity */
|
|
644
|
+
},
|
|
645
|
+
"url": "https://linear.app/team/issue/BLA-123",
|
|
646
|
+
"updatedFrom": {
|
|
647
|
+
/* previous values for updates */
|
|
648
|
+
},
|
|
649
|
+
"webhookTimestamp": 1705831200000,
|
|
650
|
+
"webhookId": "webhook-id"
|
|
651
|
+
}
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Security Verification
|
|
655
|
+
|
|
656
|
+
```typescript
|
|
657
|
+
const crypto = require("node:crypto");
|
|
658
|
+
const { createHmac } = require("node:crypto");
|
|
659
|
+
|
|
660
|
+
// Verify signature
|
|
661
|
+
const signature = createHmac("sha256", WEBHOOK_SECRET)
|
|
662
|
+
.update(rawBody)
|
|
663
|
+
.digest("hex");
|
|
664
|
+
|
|
665
|
+
if (signature !== request.headers.get("linear-signature")) {
|
|
666
|
+
return new Response(null, { status: 400 });
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Check timestamp (prevent replay attacks)
|
|
670
|
+
if (Math.abs(Date.now() - payload.webhookTimestamp) > 60000) {
|
|
671
|
+
return new Response(null, { status: 401 });
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return new Response(null, { status: 200 });
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
**IP Allowlist** (for firewall rules):
|
|
678
|
+
|
|
679
|
+
- 35.231.147.226
|
|
680
|
+
- 35.243.134.228
|
|
681
|
+
- (and 4 additional IPs - check Linear docs for current list)
|
|
682
|
+
|
|
683
|
+
### Retry Behavior
|
|
684
|
+
|
|
685
|
+
- Endpoint must return HTTP 200 within 5 seconds
|
|
686
|
+
- Failed deliveries retry up to 3 times: 1 minute, 1 hour, 6 hours
|
|
687
|
+
- Unresponsive webhooks may be auto-disabled
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
## CLI Tools
|
|
692
|
+
|
|
693
|
+
### schpet/linear-cli (Recommended)
|
|
694
|
+
|
|
695
|
+
Interactive CLI for managing Linear issues from the terminal.
|
|
696
|
+
|
|
697
|
+
**Installation**:
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
# Homebrew
|
|
701
|
+
brew install schpet/tap/linear
|
|
702
|
+
|
|
703
|
+
# Deno
|
|
704
|
+
deno install -A --reload -f -g -n linear jsr:@schpet/linear-cli
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
**Setup**:
|
|
708
|
+
|
|
709
|
+
```bash
|
|
710
|
+
export LINEAR_API_KEY="your-api-key"
|
|
711
|
+
linear config # Creates .linear.toml in repo
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
**Key Commands**:
|
|
715
|
+
|
|
716
|
+
```bash
|
|
717
|
+
# View issue details
|
|
718
|
+
linear issue view BLA-123
|
|
719
|
+
|
|
720
|
+
# List your issues
|
|
721
|
+
linear issue list
|
|
722
|
+
|
|
723
|
+
# Start working on issue (creates branch, marks as started)
|
|
724
|
+
linear issue start BLA-123
|
|
725
|
+
|
|
726
|
+
# Create GitHub PR with issue details
|
|
727
|
+
linear issue pr
|
|
728
|
+
|
|
729
|
+
# List and add comments
|
|
730
|
+
linear comment list BLA-123
|
|
731
|
+
linear comment add BLA-123 "Your comment here"
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
**Features**:
|
|
735
|
+
|
|
736
|
+
- Works with Git and Jujutsu (jj) VCS
|
|
737
|
+
- Includes Claude Code skill for AI assistance
|
|
738
|
+
- Auto-detects current issue from branch name
|
|
739
|
+
|
|
740
|
+
### Linearis (by Carlo Zottmann)
|
|
741
|
+
|
|
742
|
+
CLI optimized for LLM agents with JSON output.
|
|
743
|
+
|
|
744
|
+
**Key Features**:
|
|
745
|
+
|
|
746
|
+
- JSON output for structured data
|
|
747
|
+
- Smart ID resolution
|
|
748
|
+
- Optimized GraphQL queries
|
|
749
|
+
- Designed for agent integration
|
|
750
|
+
|
|
751
|
+
### linear-cli (Rust)
|
|
752
|
+
|
|
753
|
+
Fast CLI built with Rust (released January 2026).
|
|
754
|
+
|
|
755
|
+
**Features**:
|
|
756
|
+
|
|
757
|
+
- Full API coverage (projects, issues, labels, teams, users, cycles, comments, documents)
|
|
758
|
+
- Git integration for branch checkout and PR linking
|
|
759
|
+
- Jujutsu (jj) first-class support
|
|
760
|
+
- Interactive TUI mode
|
|
761
|
+
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
## Integration Platforms (2026)
|
|
765
|
+
|
|
766
|
+
### n8n
|
|
767
|
+
|
|
768
|
+
Open-source workflow automation with deep Linear integration.
|
|
769
|
+
|
|
770
|
+
**Linear Triggers**:
|
|
771
|
+
|
|
772
|
+
- Issue Created/Updated/Deleted
|
|
773
|
+
- Comment Added
|
|
774
|
+
- Project Updated
|
|
775
|
+
|
|
776
|
+
**Linear Actions**:
|
|
777
|
+
|
|
778
|
+
- Create/Update/Delete Issues
|
|
779
|
+
- Add Comments
|
|
780
|
+
- Update Issue Status
|
|
781
|
+
- Assign Issues
|
|
782
|
+
|
|
783
|
+
**Example n8n Workflow** (webhook to Linear):
|
|
784
|
+
|
|
785
|
+
```json
|
|
786
|
+
{
|
|
787
|
+
"nodes": [
|
|
788
|
+
{
|
|
789
|
+
"name": "Webhook",
|
|
790
|
+
"type": "n8n-nodes-base.webhook",
|
|
791
|
+
"parameters": {
|
|
792
|
+
"path": "github-issue",
|
|
793
|
+
"httpMethod": "POST"
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
"name": "Linear",
|
|
798
|
+
"type": "n8n-nodes-base.linear",
|
|
799
|
+
"parameters": {
|
|
800
|
+
"operation": "create",
|
|
801
|
+
"teamId": "={{ $env.LINEAR_TEAM_ID }}",
|
|
802
|
+
"title": "={{ $json.issue.title }}",
|
|
803
|
+
"description": "={{ $json.issue.body }}"
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
]
|
|
807
|
+
}
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
### Zapier
|
|
811
|
+
|
|
812
|
+
8,000+ app integrations with simple trigger-action model.
|
|
813
|
+
|
|
814
|
+
**Linear Triggers**:
|
|
815
|
+
|
|
816
|
+
- New Issue
|
|
817
|
+
- Issue Updated
|
|
818
|
+
- New Comment
|
|
819
|
+
|
|
820
|
+
**Linear Actions**:
|
|
821
|
+
|
|
822
|
+
- Create Issue
|
|
823
|
+
- Update Issue
|
|
824
|
+
- Create Comment
|
|
825
|
+
|
|
826
|
+
### Make (formerly Integromat)
|
|
827
|
+
|
|
828
|
+
Visual workflow builder with branching logic.
|
|
829
|
+
|
|
830
|
+
**Linear Module**:
|
|
831
|
+
|
|
832
|
+
- ~2,400 integrations
|
|
833
|
+
- Deeper actions per integration than Zapier
|
|
834
|
+
- Cost-effective for high-volume workflows
|
|
835
|
+
|
|
836
|
+
---
|
|
837
|
+
|
|
838
|
+
## Best Practices for AI/Automation Workflows
|
|
839
|
+
|
|
840
|
+
### 1. Use Webhooks, Not Polling
|
|
841
|
+
|
|
842
|
+
```typescript
|
|
843
|
+
// DO NOT do this
|
|
844
|
+
setInterval(async () => {
|
|
845
|
+
const issues = await client.issues();
|
|
846
|
+
// Process issues...
|
|
847
|
+
}, 60000);
|
|
848
|
+
|
|
849
|
+
// DO use webhooks
|
|
850
|
+
app.post("/linear-webhook", (req, res) => {
|
|
851
|
+
const { action, data } = req.body;
|
|
852
|
+
// React to changes in real-time
|
|
853
|
+
res.status(200).send();
|
|
854
|
+
});
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
### 2. Implement Proper Error Handling
|
|
858
|
+
|
|
859
|
+
```typescript
|
|
860
|
+
import { parseLinearError } from "@linear/sdk";
|
|
861
|
+
|
|
862
|
+
try {
|
|
863
|
+
const issue = await client.createIssue({ title, teamId });
|
|
864
|
+
} catch (error) {
|
|
865
|
+
const linearError = parseLinearError(error);
|
|
866
|
+
if (linearError?.type === "RATELIMITED") {
|
|
867
|
+
// Back off and retry
|
|
868
|
+
await sleep(60000);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
### 3. Cache Team and State IDs
|
|
874
|
+
|
|
875
|
+
```typescript
|
|
876
|
+
// Fetch once at startup
|
|
877
|
+
const teams = await client.teams();
|
|
878
|
+
const teamMap = new Map(teams.nodes.map((t) => [t.name, t.id]));
|
|
879
|
+
|
|
880
|
+
const states = await client.workflowStates();
|
|
881
|
+
const stateMap = new Map(states.nodes.map((s) => [s.name, s.id]));
|
|
882
|
+
|
|
883
|
+
// Use cached IDs
|
|
884
|
+
const todoStateId = stateMap.get("Todo");
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
### 4. Use Filtering in Queries
|
|
888
|
+
|
|
889
|
+
```graphql
|
|
890
|
+
# Instead of fetching all issues and filtering
|
|
891
|
+
query {
|
|
892
|
+
issues(
|
|
893
|
+
filter: {
|
|
894
|
+
state: { name: { eq: "In Progress" } }
|
|
895
|
+
assignee: { id: { eq: "user-id" } }
|
|
896
|
+
}
|
|
897
|
+
) {
|
|
898
|
+
nodes {
|
|
899
|
+
id
|
|
900
|
+
title
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
---
|
|
907
|
+
|
|
908
|
+
## API Explorer
|
|
909
|
+
|
|
910
|
+
Explore the Linear GraphQL API interactively:
|
|
911
|
+
|
|
912
|
+
- **Apollo Studio**: [https://studio.apollographql.com/public/Linear-API](https://studio.apollographql.com/public/Linear-API)
|
|
913
|
+
- **Linear Developers**: [https://linear.app/developers](https://linear.app/developers)
|
|
914
|
+
|
|
915
|
+
---
|
|
916
|
+
|
|
917
|
+
## Sources
|
|
918
|
+
|
|
919
|
+
- [Linear Developers Portal](https://linear.app/developers)
|
|
920
|
+
- [Linear GraphQL Getting Started](https://linear.app/developers/graphql)
|
|
921
|
+
- [Linear API and Webhooks Documentation](https://linear.app/docs/api-and-webhooks)
|
|
922
|
+
- [Linear MCP Server Documentation](https://linear.app/docs/mcp)
|
|
923
|
+
- [Linear TypeScript SDK on npm](https://www.npmjs.com/package/@linear/sdk)
|
|
924
|
+
- [Linear Pagination Documentation](https://linear.app/developers/pagination)
|
|
925
|
+
- [Linear Rate Limiting Documentation](https://linear.app/developers/rate-limiting)
|
|
926
|
+
- [Linear Webhooks Documentation](https://linear.app/developers/webhooks)
|
|
927
|
+
- [schpet/linear-cli on GitHub](https://github.com/schpet/linear-cli)
|
|
928
|
+
- [jerhadf/linear-mcp-server on GitHub](https://github.com/jerhadf/linear-mcp-server)
|
|
929
|
+
- [n8n Linear Integration](https://n8n.io/integrations/linear/)
|
|
930
|
+
- [Claude Code Remote MCP Support](https://claude.com/blog/claude-code-remote-mcp)
|