feat: MCP Server para control de impresoras
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 2m8s

- Endpoint HTTP JSON-RPC en /api/mcp
- 6 tools: list_templates, list_printers, print_template, print_raw, create_template, update_template
- Guia de formato para impresora TM-U220
- Protegido por Authentik forward auth
This commit is contained in:
2025-11-25 12:41:49 -06:00
parent 583c29cd96
commit 0e86f9d7a9
5 changed files with 1206 additions and 17 deletions

View File

@@ -0,0 +1,115 @@
// MCP Server Endpoint - JSON-RPC 2.0 over HTTP
// Protocolo MCP para agentes de IA
import { MCP_TOOLS, handleToolCall } from '../../utils/mcp'
interface JsonRpcRequest {
jsonrpc: '2.0'
id: string | number
method: string
params?: any
}
interface JsonRpcResponse {
jsonrpc: '2.0'
id: string | number | null
result?: any
error?: {
code: number
message: string
data?: any
}
}
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event) as JsonRpcRequest
// Validar JSON-RPC
if (body.jsonrpc !== '2.0') {
return createJsonRpcError(body.id, -32600, 'Invalid Request: jsonrpc must be "2.0"')
}
if (!body.method) {
return createJsonRpcError(body.id, -32600, 'Invalid Request: method is required')
}
// Manejar métodos MCP
switch (body.method) {
case 'initialize': {
// Handshake inicial del protocolo MCP
return createJsonRpcResponse(body.id, {
protocolVersion: '2024-11-05',
capabilities: {
tools: {}
},
serverInfo: {
name: 'printercentral-mcp',
version: '1.0.0'
}
})
}
case 'initialized': {
// Notificación de que el cliente está listo
return createJsonRpcResponse(body.id, {})
}
case 'tools/list': {
// Listar todas las tools disponibles
return createJsonRpcResponse(body.id, {
tools: MCP_TOOLS
})
}
case 'tools/call': {
// Ejecutar una tool
const { name, arguments: args } = body.params || {}
if (!name) {
return createJsonRpcError(body.id, -32602, 'Invalid params: tool name is required')
}
// Verificar que la tool existe
const tool = MCP_TOOLS.find(t => t.name === name)
if (!tool) {
return createJsonRpcError(body.id, -32602, `Tool not found: ${name}`)
}
// Ejecutar la tool
const result = await handleToolCall(name, args || {})
return createJsonRpcResponse(body.id, result)
}
case 'ping': {
return createJsonRpcResponse(body.id, {})
}
default:
return createJsonRpcError(body.id, -32601, `Method not found: ${body.method}`)
}
} catch (err: any) {
console.error('MCP Error:', err)
return createJsonRpcError(null, -32603, `Internal error: ${err.message}`)
}
})
function createJsonRpcResponse(id: string | number | null, result: any): JsonRpcResponse {
return {
jsonrpc: '2.0',
id: id ?? null,
result
}
}
function createJsonRpcError(id: string | number | null, code: number, message: string, data?: any): JsonRpcResponse {
return {
jsonrpc: '2.0',
id: id ?? null,
error: {
code,
message,
...(data && { data })
}
}
}