#!/usr/bin/env bun
/**
* Self MCP Server - Core
*
* Lógica compartilhada do MCP Server.
* Usado por server.js (stdio) e server-http.js (HTTP/SSE).
*
* Suporta tanto uso local (singleton) quanto multi-tenant (instância injetada)
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js'
import defaultDb, { createDbFunctions } from './db/index.js'
import { toolDefinitions, executeTool, createToolExecutor } from './tools/index.js'
import { resourceDefinitions, readResource, createResourceReader } from './resources/index.js'
import { promptDefinitions, getPrompt } from './prompts/index.js'
/**
* Cria e configura o servidor MCP com todos os handlers
* @param {Object} options - Opções de configuração
* @param {Database} options.dbInstance - Instância do SQLite database (opcional - usa singleton se não fornecido)
* @returns {Server} Servidor MCP configurado
*/
export function createMcpServer(options = {}) {
// Determina qual instância de db usar
let db
let executeToolFn
let readResourceFn
if (options.dbInstance) {
// Multi-tenant: cria funções usando a instância fornecida
db = createDbFunctions(options.dbInstance)
executeToolFn = createToolExecutor(db)
readResourceFn = createResourceReader(db)
} else {
// Local: usa singleton
db = defaultDb
executeToolFn = executeTool
readResourceFn = readResource
}
const server = new Server(
{
name: 'self-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
resources: {},
prompts: {},
},
}
)
// ============================================
// TOOLS
// ============================================
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: toolDefinitions,
}
})
server.setRequestHandler(CallToolRequestSchema, async request => {
const { name, arguments: args } = request.params
try {
return await executeToolFn(name, args || {})
} catch (error) {
return {
content: [
{
type: 'text',
text: `❌ Erro ao executar tool ${name}: ${error.message}`,
},
],
isError: true,
}
}
})
// ============================================
// RESOURCES
// ============================================
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: resourceDefinitions,
}
})
server.setRequestHandler(ReadResourceRequestSchema, async request => {
const { uri } = request.params
try {
return readResourceFn(uri)
} catch (error) {
throw new Error(`Erro ao ler resource ${uri}: ${error.message}`)
}
})
// ============================================
// PROMPTS
// ============================================
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return {
prompts: promptDefinitions,
}
})
server.setRequestHandler(GetPromptRequestSchema, async request => {
const { name, arguments: args } = request.params
try {
return getPrompt(name, args || {})
} catch (error) {
throw new Error(`Erro ao obter prompt ${name}: ${error.message}`)
}
})
return server
}
export default { createMcpServer }