feat(api): integrate MCP tools support in Ollama chat route
Add support for Model Context Protocol (MCP) tools in the Ollama chat API. Detect model capabilities to use native tools or prompt engineering. Handle tool calls, execute them via MCPExecutor, and inject results back into the conversation for seamless tool-assisted responses. This enhances chat functionality by enabling external tool integration.
This commit is contained in:
1 parent
745746afa9
commit
4739a13458
18 files changed
+1782
-10
No files matched your search
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Repositório para gerenciar MCPs ativos por conversa/usuário
|
||||
*/
|
||||
|
||||
import Database from "better-sqlite3";
|
||||
import path from "path";
|
||||
|
||||
const dbPath = path.join(process.cwd(), "database", "ollahub.db");
|
||||
const db = new Database(dbPath);
|
||||
|
||||
export interface ActiveMCP {
|
||||
id: string;
|
||||
conversation_id: string;
|
||||
mcp_id: string;
|
||||
enabled: boolean;
|
||||
config?: any;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export class MCPActiveRepository {
|
||||
/**
|
||||
* Salvar MCPs ativos para uma conversa
|
||||
* @param conversationId ID da conversa
|
||||
* @param mcpIds Array de IDs de MCPs ativos
|
||||
*/
|
||||
static saveActiveMCPs(conversationId: string, mcpIds: string[]): void {
|
||||
try {
|
||||
// Primeiro, remover todas as entradas antigas da conversa
|
||||
const deleteStmt = db.prepare(
|
||||
"DELETE FROM active_mcps WHERE conversation_id = ?"
|
||||
);
|
||||
deleteStmt.run(conversationId);
|
||||
|
||||
// Inserir novos MCPs ativos
|
||||
const insertStmt = db.prepare(`
|
||||
INSERT INTO active_mcps (conversation_id, mcp_id, enabled, created_at)
|
||||
VALUES (?, ?, 1, CURRENT_TIMESTAMP)
|
||||
`);
|
||||
|
||||
for (const mcpId of mcpIds) {
|
||||
insertStmt.run(conversationId, mcpId);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Saved ${mcpIds.length} active MCPs for conversation ${conversationId}`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error saving active MCPs:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obter MCPs ativos de uma conversa
|
||||
* @param conversationId ID da conversa
|
||||
* @returns Array de IDs de MCPs ativos
|
||||
*/
|
||||
static getActiveMCPs(conversationId: string): string[] {
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
SELECT mcp_id FROM active_mcps
|
||||
WHERE conversation_id = ? AND enabled = 1
|
||||
ORDER BY created_at DESC
|
||||
`);
|
||||
|
||||
const results = stmt.all(conversationId) as { mcp_id: string }[];
|
||||
return results.map((row) => row.mcp_id);
|
||||
} catch (error) {
|
||||
console.error("Error getting active MCPs:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ativar/desativar um MCP específico para uma conversa
|
||||
* @param conversationId ID da conversa
|
||||
* @param mcpId ID do MCP
|
||||
* @param enabled true para ativar, false para desativar
|
||||
*/
|
||||
static toggleMCP(
|
||||
conversationId: string,
|
||||
mcpId: string,
|
||||
enabled: boolean
|
||||
): void {
|
||||
try {
|
||||
// Verificar se já existe
|
||||
const checkStmt = db.prepare(`
|
||||
SELECT id FROM active_mcps
|
||||
WHERE conversation_id = ? AND mcp_id = ?
|
||||
`);
|
||||
const existing = checkStmt.get(conversationId, mcpId);
|
||||
|
||||
if (existing) {
|
||||
// Atualizar
|
||||
const updateStmt = db.prepare(`
|
||||
UPDATE active_mcps SET enabled = ?
|
||||
WHERE conversation_id = ? AND mcp_id = ?
|
||||
`);
|
||||
updateStmt.run(enabled ? 1 : 0, conversationId, mcpId);
|
||||
} else {
|
||||
// Inserir
|
||||
const insertStmt = db.prepare(`
|
||||
INSERT INTO active_mcps (conversation_id, mcp_id, enabled, created_at)
|
||||
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
|
||||
`);
|
||||
insertStmt.run(conversationId, mcpId, enabled ? 1 : 0);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`MCP ${mcpId} ${
|
||||
enabled ? "enabled" : "disabled"
|
||||
} for conversation ${conversationId}`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error toggling MCP:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpar MCPs ativos de uma conversa
|
||||
* @param conversationId ID da conversa
|
||||
*/
|
||||
static clearActiveMCPs(conversationId: string): void {
|
||||
try {
|
||||
const stmt = db.prepare(
|
||||
"DELETE FROM active_mcps WHERE conversation_id = ?"
|
||||
);
|
||||
stmt.run(conversationId);
|
||||
console.log(`Cleared active MCPs for conversation ${conversationId}`);
|
||||
} catch (error) {
|
||||
console.error("Error clearing active MCPs:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obter todas as conversas que usam um MCP específico
|
||||
* @param mcpId ID do MCP
|
||||
* @returns Array de IDs de conversas
|
||||
*/
|
||||
static getConversationsUsingMCP(mcpId: string): string[] {
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
SELECT DISTINCT conversation_id FROM active_mcps
|
||||
WHERE mcp_id = ? AND enabled = 1
|
||||
`);
|
||||
|
||||
const results = stmt.all(mcpId) as { conversation_id: string }[];
|
||||
return results.map((row) => row.conversation_id);
|
||||
} catch (error) {
|
||||
console.error("Error getting conversations using MCP:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,6 +182,38 @@ export class MCPRepository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obter todos os MCPs instalados com informações completas (incluindo status, environment, etc)
|
||||
*/
|
||||
static getAllInstalled(): any[] {
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
SELECT
|
||||
id, owner, repo, name, config, tools,
|
||||
status, status_message,
|
||||
environment_path, executable_command,
|
||||
validation_result, install_logs,
|
||||
installed_at, updated_at
|
||||
FROM mcp_installations
|
||||
ORDER BY installed_at DESC
|
||||
`);
|
||||
const results = stmt.all() as any[];
|
||||
|
||||
return results.map((row) => ({
|
||||
...row,
|
||||
config: row.config ? JSON.parse(row.config) : null,
|
||||
tools: row.tools ? JSON.parse(row.tools) : [],
|
||||
validation_result: row.validation_result
|
||||
? JSON.parse(row.validation_result)
|
||||
: null,
|
||||
install_logs: row.install_logs ? JSON.parse(row.install_logs) : [],
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error("Error getting all installed MCPs:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Atualizar timestamp de um MCP instalado
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user