Skip to main content
Glama
README.md
<div align="center">

  <h1><code> ๐Ÿ” AGNT-LOCK</code></h1>


### The Context Traffic Controller for Multi-Agent Repositories

**Stop AI agents from destroying each other's work.**

[![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Build](https://img.shields.io/badge/Build-Passing-brightgreen.svg)]()
[![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-blue.svg)](https://modelcontextprotocol.io)
[![Node.js](https://img.shields.io/badge/Node.js-โ‰ฅ18-339933.svg)](https://nodejs.org)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6.svg)](https://typescriptlang.org)


[Quick Start](#-quick-start) ยท [How It Works](#-how-it-works) ยท [MCP Config](#-mcp-configuration) ยท [CLI Usage](#-cli-usage) ยท [Contributing](#-contributing)

</div>

---

## ๐Ÿ’ฅ The Problem: Agentic Collision

You're running **multiple AI agents** on the same codebase. Maybe Claude Code is refactoring your auth module while Aider is updating your API routes. Everything seems fine until:

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                                 โ”‚
โ”‚   ๐Ÿค– Agent A (Claude Code)          ๐Ÿค– Agent B (Aider)         โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚   โ”‚ Reading auth.ts...  โ”‚          โ”‚ Reading auth.ts...  โ”‚     โ”‚
โ”‚   โ”‚ Planning refactor   โ”‚          โ”‚ Planning new routes โ”‚     โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚            โ”‚                                โ”‚                   โ”‚
โ”‚            โ–ผ                                โ–ผ                   โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚   โ”‚ Writing auth.ts...  โ”‚          โ”‚ Writing auth.ts...  โ”‚     โ”‚
โ”‚   โ”‚ โœ… Refactor done!   โ”‚          โ”‚ โœ… Routes added!    โ”‚     โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚            โ”‚                                โ”‚                   โ”‚
โ”‚            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                        โ–ผ  โ–ผ                                     โ”‚
โ”‚                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                โ”‚
โ”‚                 โ”‚  ๐Ÿ’€ auth.ts  โ”‚                                โ”‚
โ”‚                 โ”‚  CORRUPTED   โ”‚                                โ”‚
โ”‚                 โ”‚  Build: FAIL โ”‚                                โ”‚
โ”‚                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                โ”‚
โ”‚                                                                 โ”‚
โ”‚   Agent A's refactor is GONE. Agent B overwrote it.            โ”‚
โ”‚   Neither agent knows the other existed.                        โ”‚
โ”‚                                                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

**This is "Agentic Collision"** โ€” and it's the #1 reason multi-agent workflows fail silently.

### What goes wrong:
- ๐Ÿ”„ **Silent overwrites** โ€” Agent B nukes Agent A's changes with zero warning
- ๐Ÿง  **Context loss** โ€” Each agent hallucinates that it's the only one working
- ๐Ÿ” **Infinite loops** โ€” Agents "fix" each other's changes back and forth forever
- ๐Ÿ’€ **Broken builds** โ€” The repo ends up in a state no single agent intended

---

## โœ… The Solution: AGNT-LOCK

AGNT-LOCK is a **lightweight coordination layer** that sits between your AI agents and your repository. It uses the **Model Context Protocol (MCP)** to give every agent awareness of what other agents are doing.

```mermaid
graph TB
    subgraph Agents
        A[๐Ÿค– Claude Code]
        B[๐Ÿค– Roo Code]
        C[๐Ÿค– Aider]
        D[๐Ÿค– Cursor]
    end

    subgraph AGNT-LOCK
        MCP[๐Ÿ” MCP Server]
        SM[๐Ÿ“‹ State Manager]
        IL[๐Ÿ“ Intent Log]
    end

    subgraph Repository
        F1[๐Ÿ“„ auth.ts]
        F2[๐Ÿ“„ routes.ts]
        F3[๐Ÿ“„ config.ts]
    end

    A -->|acquire_lock| MCP
    B -->|acquire_lock| MCP
    C -->|get_repo_state| MCP
    D -->|release_lock| MCP

    MCP --> SM
    SM --> IL
    SM -->|โœ… Grant / ๐Ÿ”’ Block| Agents
    SM -.->|tracks| Repository
```

### How it works:

1. **Before editing**, an agent calls `acquire_lock(filepath, agent_name, intent)`
2. If the file is **free** โ†’ lock is granted, intent is logged
3. If the file is **locked by another agent** โ†’ request is **blocked** with details about who holds it and why
4. **After editing**, the agent calls `release_lock(filepath)` to free the file
5. Any agent can call `get_repo_state()` to see the full coordination map

---

## ๐Ÿš€ Quick Start

### Install

```bash
# Clone the repository
git clone https://github.com/codewithriza/AGNT-LOCK.git
cd AGNT-LOCK

# Install dependencies
npm install

# Build
npm run build
```

### Run as MCP Server

```bash
# Start the MCP server (stdio transport)
node dist/index.js
```

### Install globally (CLI)

```bash
npm install -g .
agnt-lock status
```

---

## โš™๏ธ MCP Configuration

### For Claude Desktop / Claude Code

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "agnt-lock": {
      "command": "node",
      "args": ["/absolute/path/to/AGNT-LOCK/dist/index.js"],
      "env": {}
    }
  }
}
```

### For Cursor

Add to your `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "agnt-lock": {
      "command": "node",
      "args": ["/absolute/path/to/AGNT-LOCK/dist/index.js"]
    }
  }
}
```

### For Roo Code (VS Code)

Add to your MCP settings in Roo Code:

```json
{
  "mcpServers": {
    "agnt-lock": {
      "command": "node",
      "args": ["/absolute/path/to/AGNT-LOCK/dist/index.js"],
      "disabled": false,
      "alwaysAllow": ["acquire_lock", "release_lock", "get_repo_state"]
    }
  }
}
```

> ๐Ÿ’ก **Tip:** Replace `/absolute/path/to/AGNT-LOCK` with the actual path where you cloned the repo.

---

## ๐Ÿ› ๏ธ MCP Tools

AGNT-LOCK exposes **4 tools** via the Model Context Protocol:

| Tool | Description |
|------|-------------|
| `acquire_lock` | Lock a file before editing. Blocks if already locked by another agent. |
| `release_lock` | Release a file lock after editing. Commits intent to session history. |
| `get_repo_state` | Get the full coordination map: active locks, agents, recent activity. |
| `force_release_all` | Emergency reset: force-release all locks in the repository. |

### acquire_lock

```typescript
// Parameters
{
  filepath: "src/auth.ts",        // File to lock
  agent_name: "claude-code",      // Who's locking it
  intent: "Refactoring auth middleware to use JWT"  // Why
}

// Response (success)
{
  "success": true,
  "message": "โœ… Lock acquired on \"src/auth.ts\" by \"claude-code\".",
  "lock": {
    "filepath": "src/auth.ts",
    "agent_name": "claude-code",
    "intent": "Refactoring auth middleware to use JWT",
    "acquired_at": "2026-03-15T10:30:00.000Z",
    "expires_at": "2026-03-15T10:45:00.000Z"
  }
}

// Response (blocked)
{
  "success": false,
  "message": "๐Ÿ”’ BLOCKED: File \"src/auth.ts\" is locked by agent \"aider\"...",
  "blocked_by": { ... }
}
```

### get_repo_state

```
๐Ÿ“Š AGNT-LOCK Repository State
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Session: session_20260315_a3f8k2
Active Locks: 2
Active Agents: claude-code, aider

๐Ÿ”’ Locked Files:
  โ€ข src/auth.ts โ†’ claude-code (intent: "Refactoring auth middleware")
  โ€ข src/routes.ts โ†’ aider (intent: "Adding new API endpoints")

๐Ÿ“ Recent Activity:
  ๐Ÿ” claude-code โ†’ acquire "src/auth.ts"
  ๐Ÿ” aider โ†’ acquire "src/routes.ts"
  ๐Ÿ”“ roo-code โ†’ release "src/config.ts"
```

---

## ๐Ÿ’ป CLI Usage

AGNT-LOCK also includes a CLI for manual coordination and debugging:

```bash
# Check repository coordination state
agnt-lock status

# Manually lock a file
agnt-lock lock src/index.ts my-agent "Updating the main entry point"

# Release a lock
agnt-lock unlock src/index.ts my-agent

# Emergency: release all locks
agnt-lock reset

# Start MCP server from CLI
agnt-lock serve
```

---

## ๐Ÿ“ Project Structure

```
AGNT-LOCK/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ index.ts          # MCP server entry point (stdio transport)
โ”‚   โ”œโ”€โ”€ server.ts         # MCP tool definitions (acquire, release, state)
โ”‚   โ”œโ”€โ”€ state-manager.ts  # Core .agentlock state engine
โ”‚   โ””โ”€โ”€ cli.ts            # Color-coded CLI dashboard
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ state-manager.test.ts  # Vitest unit tests (9 tests)
โ”œโ”€โ”€ website/              # Next.js + Tailwind landing page
โ”‚   โ”œโ”€โ”€ app/
โ”‚   โ”‚   โ”œโ”€โ”€ page.tsx      # Dark-mode landing page
โ”‚   โ”‚   โ”œโ”€โ”€ layout.tsx    # Root layout with metadata
โ”‚   โ”‚   โ””โ”€โ”€ globals.css   # Tailwind + custom styles
โ”‚   โ””โ”€โ”€ package.json
โ”œโ”€โ”€ dist/                 # Compiled JavaScript (after build)
โ”œโ”€โ”€ .agentlock/           # Runtime state directory (auto-created, gitignored)
โ”‚   โ””โ”€โ”€ state.json        # Current locks & intent log
โ”œโ”€โ”€ vitest.config.ts      # Test configuration
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ tsconfig.json
โ”œโ”€โ”€ LICENSE               # MIT
โ””โ”€โ”€ README.md
```

---

## ๐Ÿ”’ How the Lock System Works

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    .agentlock/state.json                      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                              โ”‚
โ”‚  active_locks: {                                             โ”‚
โ”‚    "src/auth.ts": {                                          โ”‚
โ”‚      agent_name: "claude-code",                              โ”‚
โ”‚      intent: "Refactoring auth middleware",                  โ”‚
โ”‚      acquired_at: "2026-03-15T10:30:00Z",                   โ”‚
โ”‚      expires_at: "2026-03-15T10:45:00Z"    โ† Auto-expiry    โ”‚
โ”‚    }                                                         โ”‚
โ”‚  }                                                           โ”‚
โ”‚                                                              โ”‚
โ”‚  intent_log: [                                               โ”‚
โ”‚    { agent: "roo-code", action: "acquire", file: "..." },   โ”‚
โ”‚    { agent: "roo-code", action: "release", file: "..." },   โ”‚
โ”‚    { agent: "claude-code", action: "acquire", file: "..." } โ”‚
โ”‚  ]                          โ†‘ Rolling log (max 500 entries)  โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

### Key Design Decisions:

- **File-level locking** โ€” Granular enough to allow parallel work, broad enough to prevent conflicts
- **15-minute TTL** โ€” Locks auto-expire to prevent deadlocks from crashed agents
- **Intent logging** โ€” Every lock/unlock is logged with *why* the agent needed the file
- **Zero external dependencies** โ€” State is a single JSON file, no database required
- **Ownership verification** โ€” Only the locking agent (or force-release) can unlock a file

---

## ๐Ÿค Contributing

Contributions are welcome! Here's how to get started:

```bash
# Fork and clone
git clone https://github.com/YOUR_USERNAME/AGNT-LOCK.git
cd AGNT-LOCK

# Install dependencies
npm install

# Build
npm run build

# Test the CLI
node dist/cli.js status
```

### Ideas for contributions:
- ๐ŸŒ HTTP/SSE transport (for remote agent coordination)
- ๐Ÿ“Š Web dashboard for visualizing lock state
- ๐Ÿ”” Webhook notifications when locks are contested
- ๐Ÿงช Test suite
- ๐Ÿ“ฆ npm package publishing
- ๐Ÿณ Docker container

---

TDQS

A4.4/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: acquiring, releasing, viewing state, and emergency release. The only potential overlap is between release_lock and force_release_all, but their scopes (single vs. all) and contexts (normal vs. emergency) make them unambiguous.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern: acquire_lock, release_lock, get_repo_state, force_release_all. The verbs and nouns are descriptive and match their functionality, making the set predictable and coherent.

Tool Count5/5

With 4 tools, the server is well-scoped for a lock management purpose. Each tool covers a necessary operation without redundancy, and the count falls comfortably within the ideal 3-15 range.

Completeness4/5

The server covers the full lock lifecycle: acquire, release, query state, and emergency cleanup. The only minor gap is a lack of a per-file lock check endpoint, but get_repo_state provides sufficient visibility into lock status.

Maintenance

ActivityInactive
ResponsivenessNo issues