feat(mcp): enhance MCP installation with status tracking and custom configs
- Add /mcp-servers/ to .gitignore for MCP server installations - Extend mcp_installations table with status, logs, and validation fields - Refactor MCP install route to support custom configs, enable logs, and async installation - Improve MCPSyncService with promise-based syncing to prevent concurrent operations This update improves MCP management by adding robust installation tracking, custom configuration support, and better error handling for a more reliable user experience.
This commit is contained in:
1 parent
1042f2136b
commit
f19bf10ef3
35 files changed
+4743
-429
No files matched your search
@@ -167,61 +167,72 @@ export class MCPCacheRepository {
|
||||
*/
|
||||
static search(params: MCPSearchParams): MCPCacheItem[] {
|
||||
try {
|
||||
let query = "SELECT * FROM mcp_marketplace_cache WHERE 1=1";
|
||||
let query: string;
|
||||
const queryParams: any[] = [];
|
||||
|
||||
// Filtro por categoria
|
||||
if (params.category) {
|
||||
query += " AND (category = ? OR subfield = ?)";
|
||||
queryParams.push(params.category, params.category);
|
||||
}
|
||||
|
||||
// Filtro por busca textual
|
||||
if (params.query) {
|
||||
query +=
|
||||
" AND (content_name LIKE ? OR description LIKE ? OR content_tag_list LIKE ?)";
|
||||
const searchTerm = `%${params.query}%`;
|
||||
queryParams.push(searchTerm, searchTerm, searchTerm);
|
||||
// Usar FTS5 para busca textual
|
||||
query = `
|
||||
SELECT c.* FROM mcp_marketplace_cache c
|
||||
INNER JOIN mcp_search_fts f ON c.rowid = f.rowid
|
||||
WHERE mcp_search_fts MATCH ?
|
||||
`;
|
||||
|
||||
// Escapar caracteres especiais e adicionar wildcard
|
||||
const searchTerm = params.query.replace(/[^a-zA-Z0-9\s]/g, " ").trim();
|
||||
queryParams.push(`${searchTerm}*`); // Prefix search
|
||||
|
||||
// Filtro de categoria (se houver)
|
||||
if (params.category) {
|
||||
query += " AND (c.category = ? OR c.subfield = ?)";
|
||||
queryParams.push(params.category, params.category);
|
||||
}
|
||||
|
||||
// Ordenar por relevância FTS + rating
|
||||
query += " ORDER BY f.rank, c.rating DESC";
|
||||
} else {
|
||||
// Query sem busca textual (usar índices normais)
|
||||
query = "SELECT * FROM mcp_marketplace_cache WHERE 1=1";
|
||||
|
||||
if (params.category) {
|
||||
query += " AND (category = ? OR subfield = ?)";
|
||||
queryParams.push(params.category, params.category);
|
||||
}
|
||||
|
||||
// Ordenação por índice apropriado
|
||||
const order = params.order || "desc";
|
||||
let orderClause = "";
|
||||
|
||||
switch (params.sortBy) {
|
||||
case "rating":
|
||||
orderClause = `ORDER BY rating ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "downloads":
|
||||
orderClause = `ORDER BY review_cnt ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "name":
|
||||
orderClause = `ORDER BY content_name ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "recent":
|
||||
orderClause = `ORDER BY updated_at ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "total_ratings":
|
||||
orderClause = `ORDER BY review_cnt ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "updated_at":
|
||||
orderClause = `ORDER BY updated_at ${order.toUpperCase()}`;
|
||||
break;
|
||||
default:
|
||||
orderClause = `ORDER BY rating DESC`; // Padrão
|
||||
}
|
||||
|
||||
query += ` ${orderClause}`;
|
||||
}
|
||||
|
||||
// Ordenação dinâmica
|
||||
const order = params.order || "desc"; // Padrão descrescente
|
||||
let orderClause = "";
|
||||
|
||||
switch (params.sortBy) {
|
||||
case "rating":
|
||||
orderClause = `ORDER BY rating ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "downloads":
|
||||
orderClause = `ORDER BY review_cnt ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "name":
|
||||
orderClause = `ORDER BY content_name ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "recent":
|
||||
orderClause = `ORDER BY updated_at ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "total_ratings":
|
||||
orderClause = `ORDER BY review_cnt ${order.toUpperCase()}`;
|
||||
break;
|
||||
case "updated_at":
|
||||
orderClause = `ORDER BY updated_at ${order.toUpperCase()}`;
|
||||
break;
|
||||
default:
|
||||
orderClause = `ORDER BY rating DESC`; // Padrão
|
||||
}
|
||||
|
||||
query += ` ${orderClause}`;
|
||||
|
||||
// Paginação
|
||||
if (params.limit) {
|
||||
query += " LIMIT ?";
|
||||
queryParams.push(params.limit);
|
||||
|
||||
if (params.offset) {
|
||||
query += " OFFSET ?";
|
||||
queryParams.push(params.offset);
|
||||
}
|
||||
query += " LIMIT ? OFFSET ?";
|
||||
queryParams.push(params.limit, params.offset || 0);
|
||||
}
|
||||
|
||||
const stmt = db.prepare(query);
|
||||
@@ -479,4 +490,55 @@ export class MCPCacheRepository {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscar MCP por owner e repo
|
||||
*/
|
||||
static findByOwnerRepo(owner: string, repo: string): MCPCacheItem | null {
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
SELECT * FROM mcp_marketplace_cache
|
||||
WHERE owner = ? AND repo = ?
|
||||
`);
|
||||
const result = stmt.get(owner, repo) as MCPCacheItem | undefined;
|
||||
return result || null;
|
||||
} catch (error) {
|
||||
console.error("Error finding MCP by owner/repo:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscar MCP por nome
|
||||
*/
|
||||
static findByName(name: string): MCPCacheItem | null {
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
SELECT * FROM mcp_marketplace_cache
|
||||
WHERE content_name = ? OR repo = ?
|
||||
`);
|
||||
const result = stmt.get(name, name) as MCPCacheItem | undefined;
|
||||
return result || null;
|
||||
} catch (error) {
|
||||
console.error("Error finding MCP by name:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscar MCP por ID
|
||||
*/
|
||||
static findById(id: string): MCPCacheItem | null {
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
SELECT * FROM mcp_marketplace_cache
|
||||
WHERE id = ?
|
||||
`);
|
||||
const result = stmt.get(id) as MCPCacheItem | undefined;
|
||||
return result || null;
|
||||
} catch (error) {
|
||||
console.error("Error finding MCP by ID:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user