hornerosssp
v0.11.0
Published
SDK and CLI for HornerosSSP - integrate MCPs into any app
Downloads
1,435
Maintainers
Readme
HornerosSSP SDK
SDK oficial para integrar HornerosSSP en tu aplicacion. Permite conectar usuarios de tu app a integraciones como Kommo CRM, Chatwoot, NotebookLM, MercadoPago, TiendaNube, Correo Argentino y ARCA.
Instalacion
npm install hornerossspInicio Rapido
import { HornerosSSP } from "hornerosssp";
// Inicializar cliente con tu API key
const client = new HornerosSSP({
apiKey: "hsp_tu_api_key_aqui"
});
// Listar integraciones disponibles
const mcps = await client.mcps.list();
// [{ slug: "kommo-mcp", name: "Kommo CRM", ... }, ...]
// Crear conexion para un usuario de tu app
const conn = await client.connections.initiate({
mcpSlug: "kommo-mcp",
entityId: "user_123", // ID del usuario en TU app
credentials: {
access_token: "token_del_usuario",
base_domain: "empresa.kommo.com"
}
});
// Ejecutar herramienta
const result = await client.tools.execute({
mcpSlug: "kommo-mcp",
entityId: "user_123",
toolName: "get_leads",
arguments: { limit: 10 }
});Conceptos Clave
API Key
Tu API key (hsp_xxx) identifica a tu aplicacion. Obtenla desde el dashboard de HornerosSSP.
Entity ID
El entityId es el identificador del usuario final en TU aplicacion. Cada usuario puede tener sus propias conexiones a diferentes integraciones.
Conexiones
Una conexion almacena las credenciales de un usuario para una integracion especifica. Por ejemplo, si el usuario "user_123" conecta su cuenta de Kommo, las credenciales se guardan asociadas a ese entity.
API Reference
Listar MCPs Disponibles
const mcps = await client.mcps.list();Retorna todas las integraciones disponibles. No requiere configuracion previa.
Respuesta:
[
{
slug: "kommo-mcp",
name: "Kommo CRM",
description: "Gestiona leads, contactos y mensajes...",
requiredCredentials: ["access_token", "base_domain"],
toolCount: 11,
category: "CRM"
},
// ...
]Obtener Detalle de un MCP
const mcp = await client.mcps.get("kommo-mcp");Respuesta:
{
slug: "kommo-mcp",
name: "Kommo CRM",
description: "...",
requiredCredentials: ["access_token", "base_domain"],
tools: [
{ name: "get_leads", description: "Obtiene lista de leads" },
// ...
]
}Crear Conexion
const conn = await client.connections.initiate({
mcpSlug: "kommo-mcp", // Requerido: slug del MCP
entityId: "user_123", // Requerido: ID del usuario en tu app
credentials: { // Requerido: credenciales del usuario
access_token: "xxx",
base_domain: "empresa.kommo.com"
},
appName: "Mi App" // Opcional: nombre descriptivo
});Respuesta:
{
id: "conn_abc123",
mcpSlug: "kommo-mcp",
entityId: "user_123",
mcpUrl: "https://hornerosssp.com/api/mcp/kommo-mcp/conn_abc123",
token: "tok_xxxxx", // Solo se muestra una vez
status: "active"
}Listar Conexiones
// Todas las conexiones
const connections = await client.connections.list();
// Filtrar por entity
const userConns = await client.connections.list("user_123");
// Filtrar por entity y MCP
const specific = await client.connections.list("user_123", "kommo-mcp");Buscar Conexion por Entity
const conn = await client.connections.getByEntity("user_123", "kommo-mcp");
if (conn) {
// El usuario ya tiene conexion
}Revocar Conexion
await client.connections.revoke("conn_abc123");Ejecutar Herramienta
Hay dos formas de identificar la conexion:
Opcion 1: Por entityId (recomendado)
const result = await client.tools.execute({
mcpSlug: "kommo-mcp",
entityId: "user_123", // Busca la conexion automaticamente
toolName: "get_leads",
arguments: { limit: 10 }
});Opcion 2: Por connectionId
const result = await client.tools.execute({
mcpSlug: "kommo-mcp",
connectionId: "conn_abc123",
toolName: "get_leads",
arguments: { limit: 10 }
});Respuesta:
{
content: [
{ type: "text", text: "[{\"id\": 1, \"name\": \"Lead 1\"}, ...]" }
],
isError: false
}Listar Herramientas de un MCP
const tools = await client.tools.list("kommo-mcp");
// [{ name: "get_leads", description: "...", inputSchema: {...} }, ...]Conexiones OAuth (Kommo, Google, etc.)
Para MCPs que soportan OAuth (como Kommo), puedes permitir que tus usuarios conecten sus propias cuentas sin que tengas que pedirles tokens manualmente.
Flujo OAuth
- Tu creas UNA integracion OAuth en el servicio (ej: Kommo)
- Multiples usuarios de tu app pueden conectar sus propias cuentas usando tus credenciales OAuth
- Cada usuario tiene su propia conexion con sus propios tokens
Es decir: con un solo client_id/client_secret, puedes conectar muchas cuentas de usuarios diferentes.
Configuracion Previa (IMPORTANTE)
Antes de usar OAuth, debes configurar el Redirect URI en tu integracion:
https://hornerossp.vercel.app/api/v1/oauth/callbackPara Kommo:
- Ve a Settings → Integrations → Tu Integracion
- En "Redirect URI", agrega:
https://hornerossp.vercel.app/api/v1/oauth/callback - Guarda los cambios
Para Google (NotebookLM):
- Ve a Google Cloud Console → APIs & Services → Credentials
- En tu OAuth Client, agrega el URI de redireccion autorizado
- Guarda los cambios
Ejemplo OAuth con Kommo
// 1. Obtener info de campos requeridos (opcional pero util)
const info = await client.connections.getOAuthInfo("kommo-mcp");
console.log(info.fields.initiationData.required);
// [{ name: "subdomain", description: "Solo el subdominio, ej: 'miempresa'" }]
// 2. Iniciar flujo OAuth
const oauth = await client.connections.initiateOAuth({
mcpSlug: "kommo-mcp",
entityId: "user_123", // El usuario en TU app
authConfig: {
client_id: "tu_kommo_client_id",
client_secret: "tu_kommo_client_secret",
},
initiationData: {
subdomain: "miempresa" // SOLO el subdominio, no la URL completa
}
});
// 3. Redirigir al usuario al popup de autorizacion
window.open(oauth.redirectUrl, '_blank', 'width=600,height=700');
// 4. Escuchar cuando el usuario complete la autorizacion
window.addEventListener('message', (event) => {
if (event.data?.type === 'hornerossp-oauth-callback') {
if (event.data.success) {
console.log('Conectado!', event.data.connectionId);
// Ahora puedes usar client.tools.execute() con este usuario
} else {
console.error('Error:', event.data.error);
}
}
});Campo subdomain para Kommo
El campo subdomain debe contener SOLO el subdominio, no la URL completa:
| Tu cuenta Kommo | Valor correcto de subdomain |
|-----------------|----------------------------|
| miempresa.kommo.com | miempresa |
| ventas.kommo.com | ventas |
| https://demo.kommo.com | demo |
❌ Incorrecto: https://miempresa.kommo.com, miempresa.kommo.com
✅ Correcto: miempresa
Integraciones Disponibles
| MCP | Descripcion | Auth | Credenciales |
|-----|-------------|------|--------------|
| kommo-mcp | CRM Kommo | OAuth2 / Token | subdomain (OAuth) o access_token, base_domain |
| chatwoot-mcp | Soporte Chatwoot | API Key | chatwoot_url, api_token, account_id |
| notebooklm-mcp | Google NotebookLM | OAuth2 | Google OAuth |
| mercadopago-mcp | Pagos MercadoPago | Bearer | access_token |
| tiendanube-mcp | E-commerce TiendaNube | Bearer | access_token, store_id |
| correoargentino-mcp | Envios Correo Argentino | API Key | api_key, environment |
| arca-mcp | Facturacion AFIP | Certificate | cuit, certificate, private_key, environment |
Ejemplo Completo
import { HornerosSSP } from "hornerosssp";
const client = new HornerosSSP({ apiKey: process.env.HORNEROS_API_KEY });
async function connectUserToKommo(userId: string, kommoToken: string, domain: string) {
// Verificar si ya existe conexion
const existing = await client.connections.getByEntity(userId, "kommo-mcp");
if (existing) {
console.log("Usuario ya conectado a Kommo");
return existing;
}
// Crear nueva conexion
const conn = await client.connections.initiate({
mcpSlug: "kommo-mcp",
entityId: userId,
credentials: {
access_token: kommoToken,
base_domain: domain
}
});
console.log("Conexion creada:", conn.id);
return conn;
}
async function getLeadsForUser(userId: string) {
const result = await client.tools.execute({
mcpSlug: "kommo-mcp",
entityId: userId,
toolName: "get_leads",
arguments: { limit: 50 }
});
const leads = JSON.parse(result.content[0].text);
return leads;
}
// Uso
await connectUserToKommo("user_123", "kommo_token", "empresa.kommo.com");
const leads = await getLeadsForUser("user_123");
console.log(`Found ${leads.length} leads`);Manejo de Errores
import { HornerosError, HORNEROS_SDK_ERROR_CODES } from "hornerosssp";
try {
await client.tools.execute({...});
} catch (error) {
if (error instanceof HornerosError) {
switch (error.errorCode) {
case HORNEROS_SDK_ERROR_CODES.COMMON.CONNECTION_NOT_FOUND:
console.log("El usuario no tiene conexion. Crear una primero.");
break;
case HORNEROS_SDK_ERROR_CODES.COMMON.TOOL_NOT_FOUND:
console.log("Herramienta no existe");
break;
case HORNEROS_SDK_ERROR_CODES.COMMON.RATE_LIMITED:
console.log("Limite de requests alcanzado");
break;
default:
console.log("Error:", error.message);
}
}
}Variables de Entorno
El SDK puede leer configuracion de variables de entorno:
HORNEROS_API_KEY=hsp_xxx # API key
HORNEROS_BASE_URL=https://... # URL base (opcional)// Si las variables estan configuradas, no necesitas pasarlas
const client = new HornerosSSP();TypeScript
El SDK incluye tipos TypeScript completos:
import type {
McpInfo,
McpDetail,
ConnectionInfo,
ToolDefinition,
ToolResult,
InitiateConnectionParams,
ExecuteToolParams
} from "hornerosssp";