linear-cache-mcp
v0.1.3
Published
Cache-first Linear MCP server for agent workflows.
Maintainers
Readme
Linear Cache MCP
Cache-first MCP server for Linear. Reduces API usage by serving reads from a local JSON cache, tracks a request budget, and provides write-through mutation tools for coding agent workflows.
Why this exists
Linear's API has rate limits. Coding agents that query Linear for every read can exhaust them quickly. This server keeps a local mirror of your team's issues and projects, serves reads from cache when fresh, and only calls the Linear API for writes or when the cache is stale.
Quick start
npx -y linear-cache-mcpThis auto-installs and runs the server. No clone required.
Development / local clone
git clone https://github.com/ch-raph/linear-cache-mcp.git
cd linear-cache-mcp/packages/linear-cache-mcp
npm install
npm startConfigure
Set Linear auth using one of these methods. The server needs LINEAR_API_KEY for live sync/write operations. Cache reads work without it.
Option A: .env file (recommended for development)
cp .env.example .envEdit .env:
LINEAR_API_KEY=lin_api_your_key_here
LINEAR_TEAM_ID=your-linear-team-idOption B: Environment variables
export LINEAR_API_KEY="lin_api_..."
export LINEAR_TEAM_ID="your-linear-team-id"Option C: MCP client config
Pass secrets through your MCP host's env config:
{
"mcpServers": {
"linear-cache": {
"command": "npx",
"args": ["-y", "linear-cache-mcp"],
"env": {
"LINEAR_API_KEY": "${LINEAR_API_KEY}",
"LINEAR_TEAM_ID": "your-team-id"
}
}
}
}Ready-to-copy templates in examples/.
Smoke test
npx -y linear-cache-mcp --stdio-smokeOutputs cache status and budget without starting the server.
Troubleshooting
Pi says Connection closed
First verify the package entrypoint starts:
npx -y linear-cache-mcp --stdio-smokeExpected result: JSON containing "ok": true. If that works, restart Pi or run /mcp reconnect linear-cache so pi-mcp-adapter reloads .mcp.json.
No Linear project documentation appears
This server currently exposes Linear Issues, Projects, and Project Updates. Use:
linear_cache_list_projectsto find a projectlinear_cache_list_project_updatesto read cached project updateslinear_cache_list_project_updateswithliveRefresh: truefor a targeted live fetch
It does not currently expose Linear's separate Docs/Documents objects. If your project documentation lives in Linear Docs rather than Project Updates, this package will need an additional docs tool.
Pi Coding Agent Integration
Pi connects via pi-mcp-adapter.
1. Install the adapter (once per machine)
pi install npm:pi-mcp-adapter2. Create .mcp.json in your project root
{
"settings": { "toolPrefix": "none" },
"mcpServers": {
"linear-cache": {
"command": "npx",
"args": ["-y", "linear-cache-mcp"],
"env": {
"LINEAR_API_KEY": "${LINEAR_API_KEY}",
"LINEAR_TEAM_ID": "your-team-id"
},
"directTools": true,
"lifecycle": "lazy"
}
}
}For development against a local clone, replace npx with node and the path to server.mjs.
3. Set your API key
export LINEAR_API_KEY="lin_api_..."4. Gitignore the config (it contains secrets)
echo ".mcp.json" >> .gitignore5. Add the agent skill (optional)
cp -r skills/linear-ops .agents/skills/linear-ops/6. Restart Pi
All 13 linear_cache_* tools appear. Test with linear_cache_status.
Tools
All 13 tools — clean names with toolPrefix: "none":
Read (cache-only, 0 API cost)
linear_cache_status— cache freshness, file counts, budget modelinear_cache_budget_status— current-hour request usagelinear_cache_search_issues— search by text, status, label, assignee, projectlinear_cache_get_issue— get by ID (optionallyliveRefresh: true)linear_cache_list_projects— list/search projectslinear_cache_list_project_updates— list project updates
Write / Sync (calls Linear API)
linear_cache_sync_incremental— sync since last update (budget-gated)linear_cache_sync_full— full reconciliation (budget-gated)linear_cache_create_issuelinear_cache_update_issuelinear_cache_move_issuelinear_cache_comment_issuelinear_cache_create_project_update
Agent workflow
- Cache-first reads —
linear_cache_search_issues,linear_cache_get_issuecost nothing - Check budget —
linear_cache_budget_statusbefore live calls - Live-fetch before writes — use
liveRefresh: trueonlinear_cache_get_issuebefore mutating - Sync when stale —
linear_cache_sync_incrementalif cache >2 hours old - Write-through — cache auto-patched after mutations
Budget thresholds
| Requests/hour | Mode | |---|---| | <900 | Normal | | 900–1200 | Avoid broad refreshes | | 1200–1400 | Targeted reads/writes only | | >1400 | Ask before any Linear call |
Write safety
Write tools live-fetch relevant entities, perform the mutation, then refresh/patch the cache and append request ledger entries.
Project Update tools accept either projectId or exact projectName. Exact-name lookup uses cached projects and rejects missing or ambiguous names. Optional Project Update health values are onTrack, atRisk, or offTrack.
If LINEAR_API_KEY is missing, read-only cache tools still work; live sync and writes return clear errors.
Local state
Cache stored in .agent/linear-cache/ (auto-created):
manifest.json— sync metadata, freshness trackinglatest/issues.json— cached issueslatest/projects.json— cached projectslatest/project_updates.json— cached project updatesrequest-ledger.jsonl— local API request accounting
Source layout
src/server.mjs— executable entrypointsrc/config.mjs— paths, Linear endpoint, defaults, budget thresholdssrc/cache-store.mjs— JSON cache files, manifest, entity patchingsrc/ledger.mjs— request ledger and hourly budgetsrc/linear-client.mjs— Linear GraphQL wrappersrc/normalizers.mjs— issue/project/project-update normalizationsrc/issue-service.mjs— issue cache search, live fetch, sync, write-throughsrc/project-service.mjs— project cache search and syncsrc/project-update-service.mjs— Project Update cache, refresh, creationsrc/tools.mjs— MCP tool registration
