Explorar documentación

Guía de autoalojamiento de OOMOL OpenConnector

OOMOL OpenConnector es un servicio de conectores de código abierto y autoalojable. Úsalo cuando agentes o herramientas internas necesiten llamar a servicios externos reales mientras las credenciales del proveedor, los permisos y el historial de ejecución permanecen en tu propio entorno. Expone acciones tipadas para servicios como GitHub, Gmail, Notion, Hacker News, Ably, Abstract y A-Leads a través de MCP o HTTP.

Los agentes ven esquemas, ámbitos, estado de ejecución y etiquetas de cuenta seguras; los tokens sin procesar del proveedor, los permisos de acciones y el historial de ejecución permanecen dentro del límite de tu implementación.

Lo que te ofrece

  • Un entorno de ejecución que expone acciones del proveedor a través de MCP, HTTP, OpenAPI y una consola web.
  • Almacenamiento de credenciales para claves de API, credenciales personalizadas, conexiones OAuth2 y proveedores sin autenticación.
  • Esquemas de acciones tipadas para que los agentes puedan descubrir qué pueden llamar antes de llamarlo.
  • Identidad de conexión y ámbitos para que los usuarios y los agentes puedan ver con qué cuenta se ejecutará una acción.
  • Tránsito temporal de archivos para acciones que necesitan URL de archivos.
  • Registros de ejecuciones recientes con resúmenes de entrada redactados y errores del proveedor.
  • Un catálogo de proveedores con ejecutores locales que se cargan solo cuando se usa una acción.

Empieza por elegir dónde ejecutar el entorno de ejecución y, después, configura el almacenamiento, el control de acceso, las conexiones del proveedor y el punto de entrada MCP o HTTP para los agentes.

Elige un destino de implementación

DestinoÚsalo cuandoAlmacenamiento
Docker ComposeQuieres la implementación local o en un solo servidor más rápida.Volumen de Docker montado en /app/data, con SQLite en /app/data/connect.sqlite.
Entorno de ejecución desde el código fuenteEstás desarrollando OOMOL OpenConnector o ejecutores de proveedores../data/connect.sqlite local a menos que se configure OOMOL_CONNECT_DATA_DIR.
Cloudflare WorkersQuieres una implementación de estado de ejecución y metadatos alojada en Cloudflare.D1 para registros del entorno de ejecución y R2 para archivos de tránsito temporales.

Prepara el entorno de ejecución

Antes de implementar, decide estos valores:

ValorPor qué importa
OOMOL_CONNECT_ADMIN_TOKENProtege la consola web, /api y la referencia local de API cuando son accesibles fuera de tu propio shell.
OOMOL_CONNECT_ENCRYPTION_KEYCifra las credenciales de proveedor almacenadas y los secretos de cliente OAuth. Guárdala en tu gestor de secretos.
OOMOL_CONNECT_ORIGINEstablece el origen público usado para las URL de devolución de llamada de OAuth. Obligatorio cuando el navegador llega al entorno de ejecución a través de un túnel, dominio o URL de Worker.
Tokens del entorno de ejecuciónAutentican las llamadas de agentes y clientes a /v1 y /mcp. Créalos desde la pestaña Access de la consola web o desde la API de administración.
Política de accionesLimita qué acciones pueden ejecutarse a través de /v1 y MCP. Usa OOMOL_CONNECT_ALLOWED_ACTIONS y OOMOL_CONNECT_BLOCKED_ACTIONS.

Trata la base de datos del entorno de ejecución como confidencial. Sin OOMOL_CONNECT_ENCRYPTION_KEY, OOMOL OpenConnector sigue funcionando, pero los secretos del proveedor se almacenan en un archivo SQLite local confidencial.

Ejecutar con Docker Compose

Clona el repositorio de OOMOL OpenConnector, entra en el directorio del proyecto e inicia el entorno de ejecución:

git clone https://github.com/oomol-lab/open-connector.git
cd open-connector
docker compose up --build

Abre la consola web:

http://localhost:3000

Abre la referencia de API generada:

http://localhost:3000/docs

Verifica el entorno de ejecución con una acción sin autenticación:

curl -s -X POST http://localhost:3000/v1/actions/hackernews.get_top_stories \
  -H 'content-type: application/json' \
  -d '{"input":{}}'

Docker Compose almacena el estado del entorno de ejecución en el volumen connector-data. El contenedor almacena SQLite en:

/app/data/connect.sqlite

Para una implementación en un servidor privado, establece al menos el token de administración y la clave de cifrado antes de iniciar:

Ejecuta estos ejemplos en Bash. Introduce credenciales reales solo en las solicitudes ocultas; no las pegues en comandos de shell ni en registros de comandos.

(
  set -eu
  read -r -s -p "OOMOL_CONNECT_ADMIN_TOKEN: " OOMOL_CONNECT_ADMIN_TOKEN
  echo
  test -n "$OOMOL_CONNECT_ADMIN_TOKEN"
  export OOMOL_CONNECT_ADMIN_TOKEN
  read -r -s -p "OOMOL_CONNECT_ENCRYPTION_KEY: " OOMOL_CONNECT_ENCRYPTION_KEY
  echo
  test -n "$OOMOL_CONNECT_ENCRYPTION_KEY"
  export OOMOL_CONNECT_ENCRYPTION_KEY
  docker compose up --build
)

Cuando el entorno de ejecución se expone a través de un dominio público o túnel, exige autenticación tanto de administración como del entorno de ejecución y establece el origen público:

(
  set -eu
  export OOMOL_CONNECT_ORIGIN="https://connect.example.com"
  read -r -s -p "OOMOL_CONNECT_ADMIN_TOKEN: " OOMOL_CONNECT_ADMIN_TOKEN
  echo
  test -n "$OOMOL_CONNECT_ADMIN_TOKEN"
  export OOMOL_CONNECT_ADMIN_TOKEN
  read -r -s -p "OOMOL_CONNECT_RUNTIME_TOKEN: " OOMOL_CONNECT_RUNTIME_TOKEN
  echo
  test -n "$OOMOL_CONNECT_RUNTIME_TOKEN"
  export OOMOL_CONNECT_RUNTIME_TOKEN
  read -r -s -p "OOMOL_CONNECT_ENCRYPTION_KEY: " OOMOL_CONNECT_ENCRYPTION_KEY
  echo
  test -n "$OOMOL_CONNECT_ENCRYPTION_KEY"
  export OOMOL_CONNECT_ENCRYPTION_KEY
  docker compose up --build
)

El token del entorno de ejecución proporcionado por el entorno es útil para inicializar una implementación pública. Si prefieres tokens oct_… creados desde la consola, mantén el entorno de ejecución privado mientras creas el primer token y, después, exponlo públicamente.

La imagen de Docker se enlaza a 0.0.0.0 dentro del contenedor. Controla el acceso externo con el firewall de tu host, el proxy inverso o la plataforma de contenedores.

Proteger el acceso de administración y del entorno de ejecución

Los clientes HTTP de administración llaman a /api, /docs o la consola web con:

Authorization: Bearer replace-with-an-admin-token

Crea tokens del entorno de ejecución para agentes y clientes estilo SDK desde la pestaña Access de la consola web. El token se muestra una vez; solo se almacena un hash. Un entorno de ejecución sin tokens debe permanecer en localhost o en una red privada.

También puedes crear uno a través de la API de administración:

Los ejemplos de solicitudes autenticadas requieren Python 3 y curl 7.76.0 o posterior, que admite la opción —fail-with-body usada en todos estos ejemplos. Leen los secretos mediante entradas ocultas y los pasan a curl por la entrada estándar, sin incluir credenciales en los argumentos de línea de comandos ni en el historial del shell.

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("OOMOL_CONNECT_ADMIN_TOKEN: ")
if not token:
    raise SystemExit("A token is required")
payload = {'name': 'Claude Desktop'}
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
config += "data = " + json.dumps(json.dumps(payload)) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'POST', 'http://localhost:3000/api/runtime-tokens', '--header', 'content-type: application/json'],
    input=config, text=True, check=True,
)
PY

Los clientes del entorno de ejecución llaman entonces a /v1 o /mcp con:

Authorization: Bearer oct_...

Para scripts de inicialización y compatibilidad hacia atrás, OOMOL_CONNECT_RUNTIME_TOKEN todavía se acepta:

(
  set -eu
  read -r -s -p "OOMOL_CONNECT_ADMIN_TOKEN: " OOMOL_CONNECT_ADMIN_TOKEN
  echo
  test -n "$OOMOL_CONNECT_ADMIN_TOKEN"
  export OOMOL_CONNECT_ADMIN_TOKEN
  read -r -s -p "OOMOL_CONNECT_RUNTIME_TOKEN: " OOMOL_CONNECT_RUNTIME_TOKEN
  echo
  test -n "$OOMOL_CONNECT_RUNTIME_TOKEN"
  export OOMOL_CONNECT_RUNTIME_TOKEN
  docker compose up --build
)

Limita las acciones que los agentes pueden ejecutar:

OOMOL_CONNECT_ALLOWED_ACTIONS="hackernews.*,github.get_current_user" docker compose up --build

Bloquea acciones específicas incluso cuando una lista de permitidos más amplia las incluya:

OOMOL_CONNECT_ALLOWED_ACTIONS="github.*" \
OOMOL_CONNECT_BLOCKED_ACTIONS="github.delete_repository" \
docker compose up --build

Conectar un proveedor con clave de API

GitHub es un ejemplo compacto de clave de API porque puede usar un token de acceso personal.

Inspecciona el contrato del proveedor:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("OOMOL_CONNECT_ADMIN_TOKEN: ")
if not token:
    raise SystemExit("A token is required")
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'GET', 'http://localhost:3000/api/providers/github'],
    input=config, text=True, check=True,
)
PY

Almacena la conexión predeterminada de GitHub:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("OOMOL_CONNECT_ADMIN_TOKEN: ")
if not token:
    raise SystemExit("A token is required")
payload = {'authType': 'api_key', 'values': {'apiKey': None}}
payload["values"]["apiKey"] = getpass.getpass("GitHub API key: ")
if not payload["values"]["apiKey"]:
    raise SystemExit("An API key is required")
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
config += "data = " + json.dumps(json.dumps(payload)) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'PUT', 'http://localhost:3000/api/connections/github', '--header', 'content-type: application/json'],
    input=config, text=True, check=True,
)
PY

Llama a GitHub a través del entorno de ejecución:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("Runtime token: ")
if not token:
    raise SystemExit("A token is required")
payload = {'input': {}}
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
config += "data = " + json.dumps(json.dumps(payload)) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'POST', 'http://localhost:3000/v1/actions/github.get_current_user', '--header', 'content-type: application/json'],
    input=config, text=True, check=True,
)
PY

Comprueba las conexiones configuradas y la identidad de cuenta segura expuesta a los agentes:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("OOMOL_CONNECT_ADMIN_TOKEN: ")
if not token:
    raise SystemExit("A token is required")
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'GET', 'http://localhost:3000/api/connections'],
    input=config, text=True, check=True,
)
PY

Conexiones con nombre

Añade connectionName cuando el mismo proveedor necesite varias cuentas:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("OOMOL_CONNECT_ADMIN_TOKEN: ")
if not token:
    raise SystemExit("A token is required")
payload = {'authType': 'api_key', 'connectionName': 'work', 'values': {'apiKey': None}}
payload["values"]["apiKey"] = getpass.getpass("GitHub API key: ")
if not payload["values"]["apiKey"]:
    raise SystemExit("An API key is required")
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
config += "data = " + json.dumps(json.dumps(payload)) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'PUT', 'http://localhost:3000/api/connections/github', '--header', 'content-type: application/json'],
    input=config, text=True, check=True,
)
PY

Selecciona esa cuenta durante la ejecución:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("Runtime token: ")
if not token:
    raise SystemExit("A token is required")
payload = {'input': {}}
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
config += "data = " + json.dumps(json.dumps(payload)) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'POST', 'http://localhost:3000/v1/actions/github.get_current_user', '--header', 'x-oo-connector-alias: work', '--header', 'content-type: application/json'],
    input=config, text=True, check=True,
)
PY

También se acepta el parámetro de consulta alias.

Conectar un proveedor OAuth

Los proveedores OAuth usan tu propia aplicación OAuth del proveedor. Primero establece la URL de devolución de llamada en la aplicación OAuth del proveedor. La URL de devolución de llamada es tu origen de OpenConnector más /oauth/callback.

Con el puerto predeterminado, GitHub usa esta URL de devolución de llamada:

http://localhost:3000/oauth/callback

Si expones el entorno de ejecución a través de otro origen, establece OOMOL_CONNECT_ORIGIN antes de iniciar el entorno de ejecución y, después, usa ese origen en la URL de devolución de llamada:

https://connect.example.com/oauth/callback

Pega la URL de devolución de llamada exacta en la aplicación OAuth del proveedor.

Almacena el cliente OAuth desde la consola web:

  1. Abre http://localhost:3000.
  2. Abre la página del proveedor, como GitHub.
  3. Elige Configure OAuth Client o Edit OAuth Client.
  4. Pega el Client ID y el Client Secret de la aplicación del proveedor.
  5. Elige Save OAuth Client.

Si el proveedor necesita campos adicionales de configuración del cliente, rellénalos en el mismo formulario de cliente OAuth. Usa una versión de la consola de OpenConnector que exponga los campos requeridos por ese proveedor antes de continuar.

Después de guardar el cliente OAuth, elige Connect en la página del proveedor. Aprueba la pantalla de autorización del proveedor. Cuando el proveedor redirija de vuelta a OpenConnector, confirma que la página del proveedor muestre la cuenta como conectada.

Dar herramientas a un agente

Para clientes compatibles con MCP, apunta el cliente a:

http://localhost:3000/mcp

El servidor MCP expone herramientas orientadas al descubrimiento:

  • list_apps
  • search_actions
  • get_action_guide
  • execute_action

Previsualiza los metadatos de las herramientas MCP:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("Runtime token: ")
if not token:
    raise SystemExit("A token is required")
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'GET', 'http://localhost:3000/mcp/tools'],
    input=config, text=True, check=True,
)
PY

Para clientes HTTP, usa la API del entorno de ejecución /v1:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("Runtime token: ")
if not token:
    raise SystemExit("A token is required")
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'GET', 'http://localhost:3000/v1/actions'],
    input=config, text=True, check=True,
)
PY

Cada acción tiene una guía local en Markdown con el esquema de entrada, ámbitos, permisos del proveedor, identidad de conexión actual y ejemplos de solicitud:

python3 - <<'PY'
import getpass
import json
import subprocess
import warnings

warnings.simplefilter("error", getpass.GetPassWarning)
token = getpass.getpass("OOMOL_CONNECT_ADMIN_TOKEN: ")
if not token:
    raise SystemExit("A token is required")
config = "header = " + json.dumps("authorization: Bearer " + token) + "\n"
subprocess.run(
    ['curl', '--disable', '--silent', '--show-error', '--fail-with-body', '--config', '-', '--request', 'GET', 'http://localhost:3000/api/actions/github.get_current_user/agent.md'],
    input=config, text=True, check=True,
)
PY

La consola web también puede copiar ejemplos de cURL, TypeScript y prompts de agentes para cada acción.

Ejecutar desde el código fuente

Usa el flujo de trabajo desde el código fuente cuando estés desarrollando OOMOL OpenConnector o ejecutores de proveedores. Usa Node.js 22 o posterior.

git clone https://github.com/oomol-lab/open-connector.git
cd open-connector
npm install
npm run build:web
npm run dev

npm install y npm run dev crean archivos locales generados cuando faltan o están desactualizados.

Al ejecutar desde el código fuente, el estado del entorno de ejecución se almacena en:

./data/connect.sqlite

Usa otro directorio de datos con:

OOMOL_CONNECT_DATA_DIR=/path/to/data npm run dev

Establece las mismas variables de entorno de administración, cifrado, origen, token del entorno de ejecución y política de acciones descritas anteriormente.

Implementar en Cloudflare Workers

Cloudflare Workers es compatible como destino de implementación de metadatos y estado del entorno de ejecución.

Clona el repositorio, crea los recursos de Cloudflare e implementa:

git clone https://github.com/oomol-lab/open-connector.git
cd open-connector
cp wrangler.example.jsonc wrangler.local.jsonc
npm install
npm run generate:catalog
npm run build:web
npx wrangler d1 create oomol-connect
npx wrangler r2 bucket create oomol-connect-transit-files

Antes de implementar, actualiza el archivo ignorado wrangler.local.jsonc con el database_id de D1 devuelto por Cloudflare.

Mantén el Worker privado durante la configuración inicial: en la configuración local de Wrangler, establece workers_dev y preview_urls en false y deja las rutas públicas y los dominios personalizados sin configurar. No permitas el acceso público hasta que se hayan establecido los tres secretos siguientes.

npx wrangler d1 migrations apply oomol-connect --remote --config wrangler.local.jsonc
npm run deploy:cloudflare

Establece secretos con Wrangler:

npx wrangler secret put OOMOL_CONNECT_ADMIN_TOKEN --config wrangler.local.jsonc
npx wrangler secret put OOMOL_CONNECT_RUNTIME_TOKEN --config wrangler.local.jsonc
npx wrangler secret put OOMOL_CONNECT_ENCRYPTION_KEY --config wrangler.local.jsonc

Después de establecer los tres secretos, habilita la ruta pública prevista en la configuración local y vuelve a implementar.

Establece OOMOL_CONNECT_ORIGIN en el origen público del Worker en wrangler.local.jsonc. El token de administración protege la consola y /api; el token del entorno de ejecución protege /v1 y /mcp desde la primera solicitud pública.

Cloudflare usa los mismos nombres de variables de entorno para origen, tokens de autenticación, política de acciones, límites de archivos de tránsito y cifrado de credenciales. PORT, HOST y OOMOL_CONNECT_DATA_DIR son configuraciones locales exclusivas de Node.

El entorno de ejecución del Worker sirve metadatos del catálogo, puntos finales de metadatos /api y /v1, conexiones, tokens del entorno de ejecución, configuración y estado de OAuth, archivos de tránsito respaldados por R2 y el registro generado de ejecutores de acciones de proveedores. Configura una regla de ciclo de vida de R2 para el bucket de tránsito si quieres que los archivos de tránsito expirados no leídos se limpien automáticamente.

Operar la implementación

Mantén estos registros disponibles para soporte y recuperación:

RegistroDónde encontrarlo
Base de datos del entorno de ejecuciónVolumen de Docker, OOMOL_CONNECT_DATA_DIR local o Cloudflare D1.
Archivos de tránsito temporalesOOMOL_CONNECT_DATA_DIR/files para el entorno de ejecución local, o Cloudflare R2.
Token de administración y clave de cifradoTu gestor de secretos. OOMOL OpenConnector no almacena la clave de cifrado por ti.
Prefijo del token del entorno de ejecuciónPestaña Access de la consola web o /api/runtime-tokens. Los tokens completos del entorno de ejecución se muestran solo una vez.
Historial de ejecuciónEjecuciones recientes de la consola web o GET /api/runs.

Para acciones de carga de archivos, los archivos de tránsito locales se almacenan en OOMOL_CONNECT_DATA_DIR/files y se limpian por antigüedad. Ajusta la vida útil y el tamaño de carga con OOMOL_CONNECT_TRANSIT_FILE_TTL_SECONDS y OOMOL_CONNECT_TRANSIT_FILE_MAX_BYTES.

Solución de problemas

SíntomaQué comprobar
La consola web o /api devuelve no autorizado.Envía Authorization: Bearer <admin-token> y confirma que OOMOL_CONNECT_ADMIN_TOKEN coincide con el entorno en ejecución.
/v1 o /mcp devuelve no autorizado.Usa un token del entorno de ejecución creado desde la pestaña Access o POST /api/runtime-tokens. Los tokens de administración son para superficies de administración, no para clientes del entorno de ejecución.
OAuth redirige al host incorrecto.Establece OOMOL_CONNECT_ORIGIN en el origen que los usuarios abren en el navegador, reinicia el entorno de ejecución y, después, usa <openconnector-origin>/oauth/callback en la aplicación del proveedor.
Una acción no encuentra credenciales.Comprueba /api/connections, el x-oo-connector-alias seleccionado y si la conexión sigue disponible.
Una acción está bloqueada.Comprueba OOMOL_CONNECT_ALLOWED_ACTIONS y OOMOL_CONNECT_BLOCKED_ACTIONS. Las acciones bloqueadas prevalecen sobre listas de permitidos más amplias.
Las credenciales del proveedor fallan después de haber funcionado antes.Vuelve a conectar el proveedor si el token expiró y no hay token de actualización disponible, o verifica que la clave de cifrado todavía coincida con los registros almacenados.