A Claude Code plugin that installs the Linear MCP server and adds hooks to prevent stale ticket updates through hash validation.
This plugin ensures data integrity when working with Linear issues by:
- Tracking reads: When you fetch a Linear issue, a hash of its content is saved
- Validating updates: Before updating an issue, the plugin verifies it was previously fetched
- Preventing stale writes: If you try to update an issue without fetching it first, the update is blocked
This prevents accidentally overwriting changes made by teammates or external integrations.
See Installation Guide for all installation methods.
# Via marketplace (recommended)
# Follow marketplace setup: ../../docs/manual-installation.md
# Or via GitHub
claude plugins install github:nsheaps/ai-mktpl/plugins/linear-mcp-sync
# Or locally for testing
cc --plugin-dir /path/to/plugins/linear-mcp-syncAfter installation, you need to:
-
Install Linear MCP Server:
claude mcp add linear --scope user -- npx -y mcp-remote https://mcp.linear.app/sse
-
Hooks are automatically configured by the plugin
When you fetch a Linear issue using any "get" or read operation:
- The hook captures the API response
- Computes a SHA256 hash of the response data
- Stores the hash with a timestamp in a session-specific file
When you attempt to update a Linear issue:
- The hook extracts the issue ID from the update request
- Checks if that issue was previously fetched in this session
- If not fetched: Blocks the update and displays an error message
- If fetched: Allows the update to proceed
# This will FAIL - issue not fetched first
Claude: Update issue LIN-123 status to "In Progress"
> Error: Cannot update issue LIN-123: This issue has not been fetched
> in the current session. Please read the issue first...
# Correct workflow
Claude: Get details of issue LIN-123
> [Issue details displayed, hash saved]
Claude: Update issue LIN-123 status to "In Progress"
> [Update succeeds]
The default matchers cover common Linear MCP tool patterns:
| Hook Type | Matcher Pattern | Description |
|---|---|---|
| PostToolUse | mcp__linear__.*(get|Get|issue$|Issue$) |
Matches read operations |
| PreToolUse | mcp__linear__.*(update|Update|create|Create) |
Matches write operations |
You can customize these patterns in your settings.json if the Linear MCP tool names differ.
Hashes are stored in session-specific files at:
$TMPDIR/linear-mcp-hashes/<session_id>.json(or/tmp/linear-mcp-hashes/if TMPDIR is not set)
This ensures hashes are isolated per session and automatically cleaned up.
This is the expected behavior! The plugin is working correctly. Fetch the issue first:
Claude: Get issue LIN-123
Then retry your update.
- Verify hooks are in your settings.json
- Check the matcher patterns match your Linear MCP tool names
- Ensure hook scripts are executable:
chmod +x hooks/*.sh - Check Claude Code logs for hook errors
On first use, Linear MCP will prompt for OAuth authentication. Follow the browser prompts to authorize access to your Linear workspace.
- Claude Code CLI installed
- Node.js and npm (for mcp-remote)
- jq (for JSON processing in hooks)
- A Linear account and workspace
linear-mcp-sync/
├── .claude-plugin/
│ └── plugin.json # Plugin metadata
├── hooks/
│ ├── linear-hash-save.sh # PostToolUse: Save hash after reads
│ └── linear-hash-check.sh # PreToolUse: Validate before updates
├── scripts/
│ └── install.sh # Installation script
├── settings-fragment.json # Hook configuration template
└── README.md # This file
- Hashes are stored locally in temp directories
- Session files are automatically cleaned up on system restart
- No sensitive data (tokens, issue content) is stored in hash files
- OAuth tokens are managed by the Linear MCP server, not this plugin
Issues and pull requests welcome at: https://github.com/nsheaps/ai-mktpl
MIT License - See repository for details.