@fastmcp-me/mcp-sqlew
Version:
MCP server for efficient context sharing between Claude Code sub-agents with 96% token reduction via action-based tools
192 lines • 7.62 kB
JavaScript
/**
* Constraint management tools for MCP Shared Context Server
* Handles constraint tracking with priority, layer assignment, and tags
*/
import { getDatabase, getOrCreateAgent, getLayerId, transaction, getOrCreateTag } from '../database.js';
import { STRING_TO_PRIORITY, DEFAULT_PRIORITY, SQLITE_TRUE, SQLITE_FALSE } from '../constants.js';
/**
* Validate constraint category (must be one of predefined)
* Categories: performance, architecture, security
*/
function validateCategory(category) {
const validCategories = ['performance', 'architecture', 'security'];
if (!validCategories.includes(category)) {
throw new Error(`Invalid category. Must be one of: ${validCategories.join(', ')}`);
}
}
/**
* Get or create constraint category ID
* Uses INSERT OR IGNORE for idempotent operation
*/
function getOrCreateCategoryId(db, category) {
// Insert if doesn't exist
db.prepare('INSERT OR IGNORE INTO m_constraint_categories (name) VALUES (?)').run(category);
// Get the ID
const result = db.prepare('SELECT id FROM m_constraint_categories WHERE name = ?').get(category);
if (!result) {
throw new Error(`Failed to get or create category: ${category}`);
}
return result.id;
}
/**
* Add a constraint with priority, layer, and tags
*
* @param params - Constraint parameters
* @returns Constraint ID and timestamp
*/
export function addConstraint(params) {
const db = getDatabase();
try {
// Validate required parameters
if (!params.category || !params.constraint_text) {
throw new Error('category and constraint_text are required');
}
// Validate category
validateCategory(params.category);
// Validate priority if provided
const priorityStr = params.priority || 'medium';
if (!['low', 'medium', 'high', 'critical'].includes(priorityStr)) {
throw new Error('Invalid priority. Must be: low, medium, high, or critical');
}
const priority = STRING_TO_PRIORITY[priorityStr] || DEFAULT_PRIORITY;
// Validate and get layer ID if provided
let layerId = null;
if (params.layer) {
const validLayers = ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'];
if (!validLayers.includes(params.layer)) {
throw new Error(`Invalid layer. Must be one of: ${validLayers.join(', ')}`);
}
layerId = getLayerId(db, params.layer);
if (!layerId) {
throw new Error(`Layer not found: ${params.layer}`);
}
}
// Use transaction for multi-table insert
const result = transaction(db, () => {
// Get or create category
const categoryId = getOrCreateCategoryId(db, params.category);
// Get or create created_by agent
const createdBy = params.created_by || 'system';
const agentId = getOrCreateAgent(db, createdBy);
// Insert constraint
const insertResult = db.prepare(`
INSERT INTO t_constraints (category_id, layer_id, constraint_text, priority, active, created_by, ts)
VALUES (?, ?, ?, ?, ?, ?, unixepoch())
`).run(categoryId, layerId, params.constraint_text, priority, SQLITE_TRUE, agentId);
const constraintId = insertResult.lastInsertRowid;
// Insert m_tags if provided
if (params.tags && params.tags.length > 0) {
const tagStmt = db.prepare('INSERT INTO t_constraint_tags (constraint_id, tag_id) VALUES (?, ?)');
for (const tagName of params.tags) {
const tagId = getOrCreateTag(db, tagName);
tagStmt.run(constraintId, tagId);
}
}
return { constraintId };
});
return {
success: true,
constraint_id: result.constraintId,
};
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to add constraint: ${message}`);
}
}
/**
* Retrieve t_constraints with advanced filtering
* Uses v_tagged_constraints view for token efficiency
*
* @param params - Filter parameters
* @returns Array of t_constraints matching filters
*/
export function getConstraints(params) {
const db = getDatabase();
try {
// Build query conditions
const conditions = [];
const values = [];
// Use v_tagged_constraints view (already filters active=1)
let sql = 'SELECT * FROM v_tagged_constraints WHERE 1=1';
// Filter by category
if (params.category) {
validateCategory(params.category);
conditions.push('category = ?');
values.push(params.category);
}
// Filter by layer
if (params.layer) {
conditions.push('layer = ?');
values.push(params.layer);
}
// Filter by priority
if (params.priority) {
conditions.push('priority = ?');
values.push(params.priority);
}
// Filter by m_tags (OR logic - match ANY tag)
if (params.tags && params.tags.length > 0) {
const tagConditions = params.tags.map(() => 'tags LIKE ?').join(' OR ');
conditions.push(`(${tagConditions})`);
for (const tag of params.tags) {
values.push(`%${tag}%`);
}
}
// Add all conditions to query
if (conditions.length > 0) {
sql += ' AND ' + conditions.join(' AND ');
}
// Note: v_tagged_constraints view already orders by priority DESC, category, ts DESC
// Add limit if provided
const limit = params.limit || 50;
sql += ' LIMIT ?';
values.push(limit);
// Execute query
const rows = db.prepare(sql).all(...values);
// Parse m_tags from comma-separated to array for consistency
const constraints = rows.map(row => ({
...row,
tags: row.tags ? row.tags.split(',') : null,
}));
return {
constraints,
count: constraints.length,
};
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to get constraints: ${message}`);
}
}
/**
* Deactivate a constraint (soft delete)
* Idempotent - deactivating already-inactive constraint is safe
*
* @param params - Constraint ID to deactivate
* @returns Success status
*/
export function deactivateConstraint(params) {
const db = getDatabase();
try {
// Validate constraint_id
if (!params.constraint_id || typeof params.constraint_id !== 'number') {
throw new Error('constraint_id is required and must be a number');
}
// Check if constraint exists
const constraint = db.prepare('SELECT id, active FROM t_constraints WHERE id = ?').get(params.constraint_id);
if (!constraint) {
throw new Error(`Constraint not found: ${params.constraint_id}`);
}
// Update constraint to inactive (idempotent)
db.prepare('UPDATE t_constraints SET active = ? WHERE id = ?').run(SQLITE_FALSE, params.constraint_id);
return {
success: true,
};
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to deactivate constraint: ${message}`);
}
}
//# sourceMappingURL=constraints.js.map