file_release
Release file reservations held by a specified agent. Optionally provide patterns to release only specific files.
Instructions
Release file reservations held by an agent.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| agent | Yes | Agent releasing reservations | |
| patterns | No | Specific patterns to release (omit to release all) |
Implementation Reference
- src/tools/file-reservation.ts:120-172 (handler)Handles the file_release tool: deletes file reservations for a given agent, optionally filtered by specific patterns.
server.tool( "file_release", "Release file reservations held by an agent.", { agent: z.string().max(256).regex(/^[a-zA-Z0-9_.-]+$/).describe("Agent releasing reservations"), patterns: z .array(z.string()) .optional() .describe("Specific patterns to release (omit to release all)"), }, async ({ agent, patterns }) => { const db = getDb(); if (patterns && patterns.length > 0) { const placeholders = patterns.map(() => "?").join(","); const result = db .prepare( `DELETE FROM file_reservations WHERE agent = ? AND pattern IN (${placeholders})` ) .run(agent, ...patterns); return { content: [ { type: "text" as const, text: JSON.stringify({ released: true, count: result.changes, agent, patterns, }), }, ], }; } const result = db .prepare(`DELETE FROM file_reservations WHERE agent = ?`) .run(agent); return { content: [ { type: "text" as const, text: JSON.stringify({ released: true, count: result.changes, agent, }), }, ], }; } ); - Input schema for file_release: requires 'agent' string and optional 'patterns' array of strings.
{ agent: z.string().max(256).regex(/^[a-zA-Z0-9_.-]+$/).describe("Agent releasing reservations"), patterns: z .array(z.string()) .optional() .describe("Specific patterns to release (omit to release all)"), }, - src/tools/file-reservation.ts:120-172 (registration)Registration of the file_release tool on the MCP server via server.tool() call.
server.tool( "file_release", "Release file reservations held by an agent.", { agent: z.string().max(256).regex(/^[a-zA-Z0-9_.-]+$/).describe("Agent releasing reservations"), patterns: z .array(z.string()) .optional() .describe("Specific patterns to release (omit to release all)"), }, async ({ agent, patterns }) => { const db = getDb(); if (patterns && patterns.length > 0) { const placeholders = patterns.map(() => "?").join(","); const result = db .prepare( `DELETE FROM file_reservations WHERE agent = ? AND pattern IN (${placeholders})` ) .run(agent, ...patterns); return { content: [ { type: "text" as const, text: JSON.stringify({ released: true, count: result.changes, agent, patterns, }), }, ], }; } const result = db .prepare(`DELETE FROM file_reservations WHERE agent = ?`) .run(agent); return { content: [ { type: "text" as const, text: JSON.stringify({ released: true, count: result.changes, agent, }), }, ], }; } ); - src/server.ts:12-23 (registration)Top-level registration: registerFileTools (which includes file_release) is called during server creation.
export function createServer(): McpServer { const server = new McpServer({ name: "forgespec-mcp", version: pkg.version, }); registerSddTools(server); registerTaskBoardTools(server); registerFileTools(server); return server; } - src/database/index.ts:32-95 (helper)Database schema definition for the file_reservations table used by file_release to delete records.
function initSchema(db: Database.Database): void { db.exec(` CREATE TABLE IF NOT EXISTS contracts ( id TEXT PRIMARY KEY, phase TEXT NOT NULL, change_name TEXT NOT NULL, project TEXT NOT NULL, status TEXT NOT NULL, confidence REAL NOT NULL, executive_summary TEXT NOT NULL, data TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS boards ( id TEXT PRIMARY KEY, project TEXT NOT NULL, name TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS tasks ( id TEXT PRIMARY KEY, board_id TEXT NOT NULL REFERENCES boards(id) ON DELETE CASCADE, title TEXT NOT NULL, description TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'backlog', priority TEXT NOT NULL DEFAULT 'p2', assignee TEXT, spec_ref TEXT, acceptance_criteria TEXT NOT NULL DEFAULT '', dependencies TEXT NOT NULL DEFAULT '[]', notes TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), claimed_at TEXT, completed_at TEXT ); CREATE TABLE IF NOT EXISTS file_reservations ( id TEXT PRIMARY KEY, pattern TEXT NOT NULL, agent TEXT NOT NULL, expires_at TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE INDEX IF NOT EXISTS idx_tasks_board ON tasks(board_id); CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status); CREATE INDEX IF NOT EXISTS idx_contracts_project ON contracts(project); CREATE INDEX IF NOT EXISTS idx_reservations_agent ON file_reservations(agent); CREATE TABLE IF NOT EXISTS audit_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TEXT DEFAULT (datetime('now')), action TEXT NOT NULL, entity_type TEXT NOT NULL, entity_id TEXT NOT NULL, agent_name TEXT, details TEXT ); `); }