Saltar al contenido principal
Página traducida

Esta página se tradujo del inglés con ayuda de IA. Si hay diferencias entre ambas, la versión en inglés es la referencia.

mcp

Comando que se usa para iniciar StackQL como servidor Model Context Protocol (MCP), lo que permite a los agentes y asistentes de IA interactuar con la infraestructura en la nube mediante las capacidades de consulta de StackQL.

¿Qué es MCP?

El Model Context Protocol (MCP) es un protocolo abierto que estandariza la forma en que las aplicaciones de IA interactúan con fuentes de datos y herramientas externas. Al ejecutar StackQL como servidor MCP, puede permitir que los agentes de IA (Claude, Cursor, Continue, agentes personalizados, etc.) consulten y gestionen infraestructura en la nube en varios providers mediante lenguaje natural.


Sintaxis​

stackql mcp [flags] para un servidor MCP independiente.

stackql srv [flags] para ejecutar el servidor MCP junto con el servidor del protocolo de red de PostgreSQL en el mismo proceso.


Modos de despliegue​

El servidor MCP de StackQL se puede desplegar en tres configuraciones distintas para adaptarse a diferentes requisitos de arquitectura. Los ejemplos siguientes activan explícitamente el servicio sin autenticación con "allow_unauthenticated": true, lo que resulta adecuado para el desarrollo local; para cualquier servidor al que pueda acceder otro proceso u otro host, configure en su lugar un token bearer (consulte Autenticación de clientes HTTP).

1. Servidor MCP independiente​

Ejecute StackQL como servidor MCP dedicado en un puerto especificado.

stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true}}'

Caso de uso: cuando solo necesita acceso mediante el protocolo MCP y no requiere compatibilidad con el protocolo de red de PostgreSQL.

2. Servidor MCP + PostgreSQL (en memoria)​

Ejecute los servidores MCP y PostgreSQL simultáneamente, con comunicación en memoria entre ambos.

stackql srv \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true}}' \
--pgsrv.port 5665

Caso de uso: cuando necesita tanto acceso mediante el protocolo MCP para agentes de IA como el protocolo de red de PostgreSQL para clientes de bases de datos tradicionales, con el máximo rendimiento gracias a la comunicación en memoria.

3. Servidor MCP + PostgreSQL (proxy inverso)​

Ejecute ambos servidores con comunicación basada en TCP, lo que admite despliegues distribuidos y cifrado TLS.

stackql srv \
--mcp.server.type=reverse_proxy \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9004", "allow_unauthenticated": true}, "backend": {"dsn": "postgres://stackql:stackql@127.0.0.1:5446?default_query_exec_mode=simple_protocol"}}' \
--pgsrv.port 5446

Con cifrado TLS:

stackql srv \
--mcp.server.type=reverse_proxy \
--mcp.config '{"server": {"tls_cert_file": "/path/to/server_cert.pem", "tls_key_file": "/path/to/server_key.pem", "transport": "http", "address": "127.0.0.1:9004", "auth_token_env_var": "STACKQL_MCP_TOKEN"}, "backend": {"dsn": "postgres://stackql:stackql@127.0.0.1:5446?default_query_exec_mode=simple_protocol"}}' \
--pgsrv.port 5446

TLS cifra el transporte pero no autentica al cliente, por lo que este ejemplo también requiere el token bearer almacenado en STACKQL_MCP_TOKEN.

Caso de uso: cuando necesita separar las cargas de trabajo de MCP y PostgreSQL en procesos o hosts distintos, o cuando requiere cifrado TLS para el endpoint MCP.


Opciones de configuración​

Tipo de servidor MCP​

TipoDescripción
httpModo de servidor HTTP directo - el motor de StackQL atiende las solicitudes MCP dentro del propio proceso.
reverse_proxyModo de proxy inverso - las solicitudes MCP se envían a un servidor PostgreSQL subyacente mediante el DSN configurado. Se usa con stackql srv.
stdioTransporte de entrada/salida estándar - el servidor lee las solicitudes de stdin y escribe las respuestas en stdout. Lo usan los clientes MCP integrados en editores (Claude Desktop, Cursor, etc.).

Formato del log de MCP​

La opción --mcp.log.format selecciona la codificación del log de auditoría: jsonl (valor predeterminado) u otel (registros de log OTLP/JSON de OpenTelemetry). Tiene prioridad sobre server.audit.format en el objeto de configuración. Consulte Formato del log.

Versión del protocolo MCP​

La opción --mcp.protocol.version establece la revisión del protocolo más reciente que anuncia el servidor: auto (valor predeterminado, todas las revisiones admitidas), 2026-07-28 (solo sin sesión) o una revisión anterior como 2025-11-25 (esa revisión y las anteriores). Tiene prioridad sobre server.protocol_version en el objeto de configuración. Consulte Fijar la revisión.

Objeto de configuración de MCP​

La opción --mcp.config acepta un objeto JSON con la siguiente estructura.

Configuración del servidor​
CampoDescripciónObligatorio
server.transportProtocolo de transporte - http o stdio.Sí
server.addressDirección y puerto a los que se vincula el servidor MCP (p. ej., 127.0.0.1:9912). Solo para el transporte HTTP.Para http
server.tls_cert_fileRuta del archivo de certificado TLS para HTTPS.No
server.tls_key_fileRuta del archivo de clave privada TLS para HTTPS.No
server.auth_token_env_varNombre de una variable de entorno que contiene un token bearer precompartido. Cuando se establece, toda solicitud HTTP debe incluir Authorization: Bearer <token>; el servidor se niega a iniciar si la variable no está definida o está vacía. Consulte Autenticación de clientes HTTP.Este campo o allow_unauthenticated, para http
server.allow_unauthenticatedActivación explícita para servir el transporte HTTP sin autenticación de clientes. Valor predeterminado: false.Este campo o auth_token_env_var, para http
server.modeContrato de seguridad que controla las mutaciones y las operaciones de ciclo de vida. Uno de read_only, safe (valor predeterminado), delete_safe, full_access. Consulte Modos del servidor.No
server.read_onlyAlias booleano heredado de mode: read_only. Cuando se establecen ambos campos, prevalece mode.No
server.statelessSirve Streamable HTTP sin sesiones (sin Mcp-Session-Id), que es como se sirve la revisión 2026-07-28 del protocolo por HTTP. Valor predeterminado: false. Se ignora para stdio. Consulte Compatibilidad con revisiones del protocolo.No
server.protocol_versionRevisión del protocolo más reciente que se anuncia: auto (valor predeterminado), 2026-07-28 o una revisión anterior como 2025-11-25. 2026-07-28 implica stateless para Streamable HTTP. Consulte Fijar la revisión.No
server.auditConfiguración del subsistema de auditoría, incluido audit.format (jsonl u otel). Consulte Log de auditoría.No
Configuración del backend (solo en modo de proxy inverso)​
CampoDescripciónObligatorio
backend.dsnCadena de conexión de PostgreSQL para el servidor StackQL de backend.Sí (para reverse_proxy)

información

El DSN del backend debe incluir el parámetro default_query_exec_mode=simple_protocol para una compatibilidad óptima.

Listas de permitidos​
CampoDescripción
enabled_toolsArray de nombres de herramientas que el servidor tiene permitido publicar. Cuando se omite o está vacío, se registran todas las herramientas incorporadas. Se usa para exponer un subconjunto reducido (p. ej., un servidor de inventario de solo lectura).
enabled_promptsArray de nombres de prompts. La misma semántica que enabled_tools, pero para la superficie de prompts.

Ejemplo - un servidor que publica solo server_info y list_providers:

{
"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true},
"enabled_tools": ["server_info", "list_providers"]
}

Compatibilidad con revisiones del protocolo​

La revisión 2026-07-28 del protocolo, server.stateless y el formato otel del log de auditoría están disponibles a partir de StackQL v0.11.660. server.protocol_version y la opción --mcp.protocol.version están disponibles a partir de StackQL v0.12.732.

El servidor habla todas las revisiones del Model Context Protocol admitidas por el Go MCP SDK y negocia con cada cliente, de modo que una flota de clientes heterogéneos funciona con un solo servidor.

RevisiónCiclo de vidaSolicitud de aprobación (safe / delete_safe)
2026-07-28 (anunciada)Sin handshake: server/discover y, después, cada solicitud lleva io.modelcontextprotocol/protocolVersion e io.modelcontextprotocol/clientCapabilities en _meta (además de los encabezados Mcp-Protocol-Version, Mcp-Method y Mcp-Name en HTTP).Resultado input_required, que el cliente reintenta con inputResponses (SEP-2322).
2025-11-25, 2025-06-18Handshake initialize / notifications/initialized.Solicitud elicitation/create iniciada por el servidor.
2025-03-26, 2024-11-05Igual que arriba.Igual que arriba.

stdio sirve todas las revisiones en un solo proceso: la primera solicitud de un cliente 2026-07-28 se sirve sin handshake y el initialize de un cliente anterior sigue funcionando. No hay nada que configurar para Claude Desktop, los lanzadores de npm / PyPI ni la imagen de Docker.

Streamable HTTP usa de forma predeterminada el modelo con estado, de una sesión por cliente (Mcp-Session-Id), que el SDK sirve para las revisiones hasta 2025-11-25. Una solicitud 2026-07-28 se responde con el error JSON-RPC -32022 (versión del protocolo no admitida; un HTTP 400 simple en las versiones hasta v0.12.718) cuyo data.supported enumera las revisiones con handshake, y server/discover anuncia lo mismo, de modo que el cliente negocia una revisión inferior y las integraciones HTTP existentes conservan sus sesiones y sus solicitudes de aprobación sin cambios. Establezca server.stateless (o fije la revisión en 2026-07-28, más abajo) para servir 2026-07-28 de forma nativa por HTTP:

stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true, "stateless": true}}'

Un servidor sin sesión no emite ningún Mcp-Session-Id, responde a GET y DELETE con 405 (no hay ninguna sesión que cerrar), mantiene tools/list, prompts/list y resources/list invariantes respecto a la conexión y realiza el ciclo de aprobación mediante input_required. Sigue aceptando el initialize de un cliente anterior y le sirve lecturas, pero no puede conservar la capacidad de elicitación que ese cliente declaró en la inicialización (cada solicitud obtiene una sesión efímera), por lo que los clientes anteriores no pueden aprobar escrituras sujetas a aprobación en un servidor sin sesión. Elija stateless para hosts de la revisión actual y el valor predeterminado para una flota que todavía incluya clientes anteriores.

El servidor no mantiene ningún estado entre llamadas: el modo, la auditoría y las credenciales de los providers son configuración a nivel de proceso, por lo que nada tiene que trasladarse a identificadores explícitos.

Fijar la revisión​

De forma predeterminada, el servidor anuncia todas las revisiones admitidas y negocia con cada cliente. La opción --mcp.protocol.version, o server.protocol_version en el objeto de configuración (prevalece la opción), establece la revisión más reciente que se anuncia:

# sessionless only; stateless Streamable HTTP is implied
stackql mcp \
--mcp.server.type=http \
--mcp.protocol.version=2026-07-28 \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true}}'

# handshake lifecycle only
stackql mcp --mcp.server.type=stdio --mcp.protocol.version=2025-11-25
ValorAnunciadoEfecto
auto (valor predeterminado) o ausenteTodas las revisiones admitidas.Negociación como se describe arriba: la revisión más alta que hablan ambas partes.
2026-07-28Solo 2026-07-28.Solo sin sesión, y stateless queda implícito para Streamable HTTP. El initialize de un cliente anterior se responde con 2025-11-25, la señal para que ese cliente se desconecte en lugar de interpretar la respuesta como el nuevo ciclo de vida.
2025-11-25 (o cualquier revisión anterior)Esa revisión y todas las anteriores.Solo ciclo de vida con handshake: una solicitud 2026-07-28 recibe el error JSON-RPC -32022 con data.supported, que enumera las revisiones anunciadas, para que el cliente pueda renegociar. Los clientes anteriores con handshake conservan su propia revisión.

Cualquier otro valor no supera la validación de la configuración al iniciar, y el error indica los valores válidos.

Límites del transporte​

Los cuerpos de las solicitudes de Streamable HTTP están limitados a 4 MiB (HTTP 413 por encima de ese tamaño), el JSON anidado a más de 1000 niveles de profundidad se rechaza antes de analizarlo y una sola trama de stdio está limitada a 8 MiB. Ninguno de estos límites es configurable; todos están muy por encima de cualquier instrucción SQL que acepte el servidor.


(Re)carga de credenciales (--env.file + reload_credentials)​

nota

--env.file y la herramienta reload_credentials están disponibles en las versiones de StackQL posteriores a v0.10.542.

El bloque de entorno de un proceso queda determinado en el momento de su creación. Esto plantea dos problemas para los servidores MCP:

  • Un servidor MCP stdio iniciado por un cliente de escritorio (Claude Desktop, Cursor, etc.) sin las variables de entorno de credenciales nunca puede verlas - el cliente pasa su propio entorno al subproceso.
  • Las credenciales de corta duración que se rotan nunca llegan a una sesión de servidor de larga duración.

La opción --env.file resuelve ambos problemas al designar un archivo de estilo dotenv que actúa como almacén de credenciales mutable:

stackql mcp --mcp.server.type=stdio --env.file /path/to/stackql-credentials.env

Semántica de la carga​

El archivo se carga en el entorno del proceso al iniciar, para todos los puntos de entrada (exec, shell, srv, registry, mcp):

  • Cuando la opción está vacía o no se establece, no ocurre nada - las credenciales se resuelven de forma diferida desde el entorno del proceso en el momento de la solicitud, exactamente el comportamiento histórico.
  • Si no existe ningún archivo en la ruta indicada, se tolera y no ocurre nada (el archivo puede crearse más tarde).
  • Un archivo mal formado o ilegible es un error fatal al iniciar.
  • Solo se establecen las claves con valores no vacíos; las variables de entorno del proceso existentes sí se sobrescriben (el archivo es la fuente de verdad); nunca se elimina ninguna variable.
  • La opción solo se admite en la línea de comandos - no se lee de .stackqlrc.

El formato del archivo es un KEY=VALUE por línea. Se toleran los comentarios con #, las líneas en blanco, un prefijo export opcional, comillas simples o dobles opcionales alrededor del valor y los finales de línea CRLF:

# stackql-credentials.env
export OKTA_SECRET_KEY="00abc...xyz"
STACKQL_GITHUB_USERNAME=myuser
STACKQL_GITHUB_PASSWORD='ghp_mytoken'

reload_credentials​

La herramienta reload_credentials vuelve a cargar el archivo de --env.file en el entorno del proceso en mitad de la sesión y, a continuación, informa del estado de resolución de las credenciales por provider. Los valores de los secretos nunca se devuelven, se escriben en logs ni se auditan - solo nombres y estados. Sin --env.file configurado, la herramienta se reduce a un mero sondeo de estado.

Cuando una consulta falla en la resolución de credenciales, el error MCP incluye una indicación que dirige al agente a llamar a reload_credentials y reintentar, de modo que los clientes agénticos se recuperan por sí solos: escriba la credencial en el archivo, pida al agente que recargue y la consulta fallida se completa correctamente al reintentarla - sin necesidad de reiniciar el servidor.

reload_credentials no se admite en el modo de backend reverse_proxy - las consultas se ejecutan en el proceso del servidor stackql remoto, por lo que la herramienta devuelve un error que indica al usuario que recargue en el servidor subyacente.

Windows y Claude Desktop​

setx escribe en el registro, no en los procesos en ejecución, y Claude Desktop pasa su propio entorno (obsoleto) a los subprocesos MCP - por eso los cambios de credenciales normalmente requieren reiniciar Claude Desktop por completo. Con --env.file, el archivo de credenciales se puede crear o rotar en cualquier momento y reload_credentials lo recoge sin ningún reinicio. Consulte Usar StackQL con Claude Desktop para ver una configuración completa de ejemplo.


Autenticación de clientes HTTP​

nota

server.auth_token_env_var y server.allow_unauthenticated están disponibles a partir de StackQL v0.12.742.

El transporte HTTP requiere autenticación de clientes. server.auth_token_env_var indica el nombre de una variable de entorno que contiene un token bearer precompartido; cada solicitud debe incluir Authorization: Bearer <token> o se responde con 401. El token se lee del entorno, por lo que nunca aparece en --mcp.config ni en los argumentos del proceso.

export STACKQL_MCP_TOKEN="$(openssl rand -hex 32)"

stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "auth_token_env_var": "STACKQL_MCP_TOKEN"}}'
Autenticación del servidor obligatoria

Servir sin token requiere una activación explícita: establezca "allow_unauthenticated": true en server. Si no se indica ninguna de las dos claves, el servidor termina al iniciar con un mensaje que nombra ambas; también termina si la variable del token no está definida o está vacía. A partir de la versión v0.12.742, debe agregar auth_token_env_var o "allow_unauthenticated": true a server cuando use el transporte http.

TLS (tls_cert_file / tls_key_file) cifra el transporte pero no autentica al cliente; combínelo con un token para cualquier listener que no sea de loopback. Las solicitudes de navegador entre orígenes (un Origin que no coincide o un Sec-Fetch-Site entre sitios) se rechazan con 403 independientemente de la autenticación. El cliente stackql_mcp_client incluido no envía ningún encabezado Authorization, por lo que un servidor al que se conecte debe activar explícitamente el servicio sin autenticación.

A partir de v1.0, iniciar el servidor con --access.config sustituye el control por token compartido por la autenticación por llamador: cada solicitud HTTPS se verifica con el esquema configurado (JWT, bearer estático o TLS mutuo) y se autoriza según las reglas de la política. En ese caso el TLS del servidor es obligatorio, la autenticación local_os se rechaza por HTTP y una solicitud sin credenciales nunca recurre al token del entorno del servidor. La gestión de accesos no está disponible con el tipo de servidor reverse_proxy.


Modos del servidor​

server.mode elige uno de cuatro contratos de seguridad. Los cuatro permiten SELECT y las lecturas de metadatos; se diferencian en cómo tratan las mutaciones y las operaciones de ciclo de vida.

ModoSELECT / metadatosINSERT / UPDATE / REPLACEDELETEEXEC (ciclo de vida)
read_onlypermitirrechazarrechazarrechazar
safe (valor predeterminado)permitirrequiere aprobaciónrequiere aprobaciónrequiere aprobación
delete_safepermitirpermitirrequiere aprobaciónrequiere aprobación
full_accesspermitirpermitirpermitirpermitir

Rechazar devuelve un error al cliente de inmediato.

Requiere aprobación usa el flujo de elicitación de MCP, cuya forma depende de la revisión del protocolo negociada:

  • Si el cliente anunció la capacidad de elicitación (en la inicialización, o en las capacidades del cliente de _meta de cada solicitud en 2026-07-28), el servidor pide al usuario que apruebe la acción con un mensaje breve (nombre de la herramienta, clase de consulta, SQL). En 2026-07-28 la solicitud de aprobación se devuelve como un resultado input_required que lleva una solicitud de entrada elicitation/create con el id stackql_approval, y el cliente reintenta la llamada con la respuesta en inputResponses; en las revisiones anteriores es el propio servidor quien envía la solicitud elicitation/create en mitad de la llamada. El usuario acepta, rechaza o cancela.
  • Si el cliente no anunció la elicitación, la herramienta se rechaza con un mensaje que explica la carencia y remite al operador al modo full_access.

La aprobación la responde el cliente, por lo que protege frente a un agente que actúe sin su usuario, no frente a un llamador que no sea de confianza. Combine el transporte HTTP con la autenticación de clientes cuando los llamadores no sean de confianza.

El modo es global para cada servidor. No se puede anular por herramienta.

A partir de v1.0, run_select_query rechaza INSERT, UPDATE, REPLACE, DELETE y EXEC en todos los modos, incluido full_access; el error indica run_mutation_query o run_lifecycle_operation. Cada herramienta lleva además un title y las cuatro indicaciones de comportamiento de MCP como booleanos explícitos (readOnlyHint, destructiveHint, idempotentHint, openWorldHint), derivadas de la misma clasificación que aplica el control de políticas. openWorldHint es true para list_registry, pull_provider, run_select_query, run_mutation_query y run_lifecycle_operation, que acceden a endpoints del registro o de los providers, y false para las herramientas que solo leen el estado local. Las indicaciones son orientativas para la experiencia de usuario del cliente; la aplicación sigue correspondiendo al control de políticas.

Control de la carga útil

A partir de la versión v0.12.742, una carga útil que contiene varias instrucciones queda controlada por su instrucción con más privilegios en todos los modos, de modo que SELECT 1; DELETE ... se trata como un DELETE y el registro de auditoría lleva query_class mutation_delete. validate_select_query acepta exactamente una instrucción.

Cambio de comportamiento del modo predeterminado​

Las versiones anteriores aplicaban la seguridad únicamente mediante una sola opción read_only: true/false cuyo valor predeterminado era "sin aplicación". El valor predeterminado actual (mode: safe) hace que las mutaciones requieran la aprobación del usuario sin configuración adicional. Los operadores que usen un cliente con capacidad de elicitación (Claude Desktop, Cursor, Continue, etc.) verán una solicitud de aprobación por mutación. Los operadores que ejecuten automatización, o el cliente stackql_mcp_client incluido (que no anuncia la elicitación), deben activar explícitamente mode: full_access para ejecutar mutaciones y operaciones de ciclo de vida.

La clave heredada read_only: true de JSON / YAML se sigue aceptando por compatibilidad con versiones anteriores y se trata como equivalente a mode: read_only.

Ejemplos​

# Read-only: SELECTs proceed; mutations and lifecycle refused immediately.
stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true, "mode": "read_only"}}'

# Delete-safe: INSERT/UPDATE proceed; DELETE and EXEC need approval.
stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true, "mode": "delete_safe"}}'

# Full access: everything proceeds without prompting. Use only with trusted
# clients and operators.
stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true, "mode": "full_access"}}'

Log de auditoría​

Cada llamada a una herramienta escribe un registro en el destino de auditoría configurado, como JSONL de forma predeterminada o como registros de log de OpenTelemetry (consulte Formato del log). La auditoría está habilitada de forma predeterminada. La auditoría responde a "¿qué hizo el agente?", no a "¿qué vio el agente?" - las filas de resultados de las instrucciones SELECT no se registran de forma intencionada, en ninguno de los dos formatos.

Qué se registra​

CampoDescripción
timestampHora de reloj al inicio de la llamada (RFC3339).
toolNombre de la herramienta (p. ej., run_select_query).
modeModo del servidor vigente en el momento de la llamada.
decisionallow / refuse_immediate / needs_approval_accepted / needs_approval_declined / needs_approval_cancelled / needs_approval_unavailable.
query_classselect / mutation_create / mutation_delete / lifecycle / unknown. Para una carga útil que contiene varias instrucciones, la clase de la que tiene más privilegios.
sqlCadena SQL para las herramientas de consulta (run_select_query, run_mutation_query, run_lifecycle_operation, validate_select_query).
argsCampos de jerarquía para las herramientas de metadatos (list_*, describe_method); SQL + row_limit para las herramientas de consulta.
duration_msDuración en tiempo de reloj del control + el manejador.
errorMensaje de error si la herramienta produjo un error o fue rechazada.

Las filas de resultados de las instrucciones SELECT se excluyen deliberadamente - pueden ser muy grandes y contener datos sensibles.

Destino de archivo​

El único destino que se incluye actualmente es file. Un objeto JSON por línea, con fsync después de cada registro y rotación al estilo de lumberjack por tamaño / antigüedad / número de copias de seguridad.

stackql mcp \
--mcp.server.type=http \
--mcp.config '{
"server": {
"transport": "http",
"address": "127.0.0.1:9912",
"allow_unauthenticated": true,
"audit": {
"file": {
"path": "/var/log/stackql-mcp.log",
"max_size_mb": 100,
"max_backups": 5,
"max_age_days": 30
}
}
}
}'

Hay dos formas de especificar la ubicación:

  • audit.file.path - una ruta de archivo completa (absoluta o relativa al cwd).
  • audit.file.dir - un directorio; el destino elige dentro de él el nombre base stackql_mcp_server_<RFC3339-utc-second>.log.

Cuando no se establece ninguna de las dos en mcp.config, el servidor MCP usa el cwd como valor predeterminado de dir, de modo que los operadores existentes ven el mismo comportamiento que antes. El propio paquete genérico de destinos subyacente se niega a elegir un directorio de forma silenciosa - la decisión de "dónde se escriben los logs" la toma siempre el llamador.

La ruta absoluta resuelta se escribe en stderr al iniciar como sink file: /path/to/file.log.

Formato del log​

El flujo de auditoría tiene dos codificaciones, que se escriben en el mismo destino de archivo:

stackql mcp --mcp.server.type=stdio --mcp.log.format=jsonl # default, unchanged
stackql mcp --mcp.server.type=stdio --mcp.log.format=otel # OTLP/JSON log records

La opción tiene prioridad sobre server.audit.format en mcp.config ("audit": {"format": "otel"}). jsonl es compatible byte a byte con los registros descritos arriba. otel escribe un objeto LogsData de OTLP/JSON por línea, la forma que el receptor otlp_json_file del OpenTelemetry Collector ingiere tal cual (verificado con otelcol-contrib 0.160.0), de modo que el flujo llega a cualquier pipeline de OTLP sin ningún procesador de transformación:

receivers:
otlp_json_file:
include: [/var/log/stackql-mcp.log]
exporters:
debug: {}
service:
pipelines:
logs:
receivers: [otlp_json_file]
exporters: [debug]

Cada llamada a una herramienta produce un registro de log; una llamada que pasó por el control de aprobación produce un segundo registro para la decisión de elicitación. Los registros de una misma llamada comparten gen_ai.tool.call.id y un id de traza. Se respeta un traceparent de W3C proporcionado por el llamador en params._meta; en caso contrario, se genera un id de traza por sesión MCP para que los registros de una sesión de agente se correlacionen.

El conjunto de atributos emitido es una interfaz versionada: el ámbito de instrumentación es github.com/stackql/stackql/pkg/mcp_server/audit en la versión 1.0.0, y schemaUrl fija las convenciones estables en https://opentelemetry.io/schemas/1.44.0. Los atributos gen_ai.* y mcp.* siguen las convenciones semánticas de GenAI y MCP, que están en estado Development; la versión del ámbito se incrementa cuando el conjunto cambia.

AtributoRegistroValor
service.name, service.versionrecursostackql, la versión de StackQL
gen_ai.operation.namellamada a herramientaexecute_tool
mcp.method.nameambostools/call en el registro de la llamada a la herramienta, elicitation/create en el registro de la decisión
gen_ai.tool.nameambosNombre de la herramienta
gen_ai.tool.call.idambosSe genera por llamada, compartido por ambos registros
mcp.protocol.versionambosRevisión negociada
mcp.session.idambosId de sesión (ausente en las solicitudes HTTP sin sesión)
stackql.modeambosModo del servidor
stackql.decisionambosEl valor de decision de la tabla anterior
stackql.queryllamada a herramientaSQL literal, para las herramientas de consulta
stackql.query_classllamada a herramientaEl valor de query_class
stackql.providerllamada a herramientaProvider, para las herramientas de metadatos
stackql.query.sourcellamada a herramientaId de la entrada de Query Library, cuando se proporciona
stackql.duration_msllamada a herramientaDuración en tiempo de reloj
stackql.rows_returnedllamada a herramientaNúmero de filas, para las herramientas que devuelven filas
error.type, error.messagellamada a herramientaEn caso de fallo: la decisión de rechazo, o tool_error una vez superado el control

El cuerpo es execute_tool <tool> / elicitation <tool>; la gravedad es INFO, o ERROR cuando la llamada falló o fue rechazada. El contrato de ocultación es idéntico en ambos formatos: los valores de los resultados nunca se serializan, solo la instrucción que los produjo.

Modos de fallo​

Cuando el destino devuelve un error, el comportamiento de la respuesta depende de audit.failure_mode.

failure_modeEfecto
strict (valor predeterminado)La llamada a la herramienta devuelve el error de auditoría al cliente aunque la herramienta subyacente se haya ejecutado correctamente. Es intencionado: es mejor una respuesta ambigua para el cliente que un DELETE no detectado.
strict_mutationsLas lecturas de SELECT / metadatos continúan con una nota en stderr; las mutaciones y las operaciones de ciclo de vida muestran el error de auditoría.
best_effortSiempre escribe en stderr y continúa.

Secuencia​

La escritura de auditoría se produce después de que la herramienta se ejecute (o de que el control la rechace) pero antes de que la respuesta vuelva al cliente. En modo estricto, un fallo de escritura de auditoría en un DELETE correcto significa que la fila ya no existe pero el cliente recibe un error - es así por diseño, para que ninguna mutación pase sin auditar.

Deshabilitar la auditoría​

Para deshabilitar la auditoría por completo (el comportamiento anterior a PR2):

stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true, "audit": {"disabled": true}}}'

Herramientas MCP disponibles​

Cuando se ejecuta como servidor MCP, StackQL expone las siguientes herramientas, sujetas a la lista de permitidos enabled_tools configurada. Cada una devuelve tanto una vista de texto renderizada (para el LLM) como una carga útil estructurada con tipos (para clientes programáticos). El renderizado de texto predeterminado es una tabla markdown para resultados uniformes de varias filas o un bloque KV de markdown para resultados dispersos / de un solo registro. Las herramientas con argumentos aceptan un format opcional (markdown o json) que anula ese valor; en caso contrario, se usa la configuración de renderizado del servidor. Las entradas siguientes enumeran los argumentos específicos de cada tarea; ? marca las entradas opcionales.

Haga clic en el nombre de cualquier herramienta para ver una página de referencia completa, con las entradas, el comportamiento de control y un prompt de ejemplo.

HerramientaRenderizadorDescripciónEntradas
server_infoKVIdentidad y runtime del servidor: versión de stackql, motor SQL subyacente, ubicación del registro de providers, modo, indicador de solo lectura. Llámela una vez al inicio de la sesión.ninguna
list_providersTablaProviders ya descargados en la caché local - la cima de la jerarquía.ninguna
list_servicesTablaServicios de un provider.provider
list_resourcesTablaRecursos de un provider.service.provider, service
list_methodsTablaMétodos de acceso (operaciones HTTP) de un recurso, con el verbo SQL al que corresponde cada uno y sus parámetros obligatorios. Llámela antes de escribir cualquier consulta - aquí es donde se deducen los parámetros WHERE obligatorios.provider, service, resource
describe_methodKVContrato de E/S completo de un método (siempre EXTENDED): entradas obligatorias y opcionales, y los campos de salida a los que puede hacer referencia un SELECT.provider, service, resource, method
query_library_searchTablaBusca plantillas de consulta seleccionadas a partir de una intención en lenguaje natural. De solo lectura; las entradas de mutación requieren activación explícita y se excluyen en el modo read_only.intent, provider?, service?, tags?, include_mutations?, limit?
query_library_getKVRecupera una plantilla y sus declaraciones de parámetros. Con params no vacío, valida los valores y devuelve el SQL renderizado más next_tool, sin ejecutarlo.id, params?
validate_select_queryKVAnaliza y planifica un único SELECT sin ejecutarlo. Devuelve {valid, errors}. Solo SELECT; exactamente una instrucción.sql
run_select_queryTablaEjecuta un SELECT. Devuelve {rows}. Solo lecturas.sql, row_limit?
run_mutation_queryKVEjecuta INSERT/UPDATE/REPLACE/DELETE en el provider. Efectos secundarios reales. Devuelve {messages, timestamp}. Controlada por el modo del servidor.sql
run_lifecycle_operationKVEjecuta una operación de ciclo de vida EXEC de stackql. Devuelve {messages, timestamp}. Controlada por el modo del servidor.sql
list_registryTablaProviders (y sus versiones) disponibles en el registro configurado. Distinta de list_providers, que enumera solo los providers ya descargados.provider?
pull_providerKVInstala un único provider del registro en la caché local. Solo afecta al estado de la caché local - sin efecto en el plano de control ni en el plano de datos de la nube.provider, version?
reload_credentialsTablaVuelve a cargar las credenciales del archivo dotenv de --env.file en el entorno del proceso e informa del estado de resolución por provider (ok, unresolved, not_checked). Nunca devuelve valores de secretos. Permitida en todos los modos.provider?

Consulte query_library_search antes de escribir SQL desde cero y, después, use query_library_get para inspeccionar y renderizar una plantilla que coincida. Las herramientas de consulta también aceptan un source opcional que contiene el ID de la entrada de la biblioteca solo con fines de atribución; la ejecución sigue sujeta al modo del servidor y a la política de aprobación habituales.

nota

describe_resource se retiró en StackQL v0.12.732; los clientes MCP, los prompts o las instrucciones de agentes que la llamaban deben llamar en su lugar a list_methods seguida de describe_method. Un recurso no tiene una única lista de campos, porque cada método de acceso devuelve su propia forma, de modo que los nombres de las columnas provienen de describe_method para el método al que se dirige una consulta. La instrucción SQL DESCRIBE no cambia.

Prompts MCP disponibles​

Se publica un prompt estático.

PromptDescripción
write_safe_selectOrientación para escribir consultas SELECT seguras sobre recursos de stackql. Explica cómo usar SHOW METHODS IN <provider>.<service>.<resource> para descubrir el método de lectura adecuado y los parámetros WHERE obligatorios.

Opciones​

OpciónDescripción
--mcp.server.typeTipo de servidor MCP: http, stdio o reverse_proxy (este último se usa con stackql srv).
--mcp.configObjeto de configuración JSON para el servidor MCP. También se acepta YAML.
--mcp.protocol.versionRevisión del protocolo más reciente que se anuncia: auto (valor predeterminado), 2026-07-28 o una revisión anterior como 2025-11-25. Consulte Fijar la revisión.
--env.fileArchivo de credenciales de estilo dotenv que se carga al iniciar y que la herramienta reload_credentials vuelve a cargar bajo demanda. Consulte (Re)carga de credenciales.
--pgsrv.portPuerto TCP del servidor del protocolo de red de PostgreSQL (se usa con stackql srv).
-H, --helpMuestra la información de ayuda.
-v, --verboseEjecuta en modo detallado con salida adicional.

   

consulte Opciones globales para ver opciones adicionales

información

Debe establecer las variables de entorno necesarias para la autenticación de los providers antes de iniciar el servidor MCP, o designar un archivo de credenciales de estilo dotenv con --env.file. Para obtener más información, consulte Usar un provider.


Ejemplos​

Servidor MCP independiente básico​

Inicie un servidor MCP independiente con autenticación de providers y un token bearer para sus clientes:

export GOOGLE_CREDENTIALS=$(cat /path/to/google-credentials.json)
export STACKQL_MCP_TOKEN="$(openssl rand -hex 32)"

stackql mcp \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "auth_token_env_var": "STACKQL_MCP_TOKEN"}}' \
--registry='{"url": "https://registry.stackql.io/providers"}' \
--auth='{"google": {"type": "service_account", "credentialsfilepath": "/path/to/google-credentials.json"}}'

Servidor MCP con servidor PostgreSQL (en memoria)​

Ejecute los servidores MCP y PostgreSQL para disponer de acceso con ambos protocolos:

export GOOGLE_CREDENTIALS=$(cat /path/to/google-credentials.json)

stackql srv \
--mcp.server.type=http \
--mcp.config '{"server": {"transport": "http", "address": "127.0.0.1:9912", "allow_unauthenticated": true}}' \
--pgsrv.port 5665 \
--registry='{"url": "https://registry.stackql.io/providers"}' \
--auth='{"google": {"type": "service_account", "credentialsfilepath": "/path/to/google-credentials.json"}}'

Servidor de inventario de solo lectura con auditoría en una ruta conocida​

Útil para un agente de exploración de inventario que nunca debe realizar mutaciones:

stackql mcp \
--mcp.server.type=http \
--mcp.config '{
"server": {
"transport": "http",
"address": "127.0.0.1:9912",
"allow_unauthenticated": true,
"mode": "read_only",
"audit": {"file": {"path": "/var/log/stackql-mcp-audit.log"}}
}
}' \
--registry='{"url": "https://registry.stackql.io/providers"}' \
--auth='{"google": {"type": "service_account", "credentialsfilepath": "/path/to/google-credentials.json"}}'

Servidor de automatización con acceso completo​

Para pipelines de automatización de confianza que necesitan mutaciones y no pueden responder a solicitudes de elicitación. El pipeline presenta el token bearer almacenado en STACKQL_MCP_TOKEN:

stackql mcp \
--mcp.server.type=http \
--mcp.config '{
"server": {
"transport": "http",
"address": "127.0.0.1:9912",
"auth_token_env_var": "STACKQL_MCP_TOKEN",
"mode": "full_access"
}
}' \
--registry='{"url": "https://registry.stackql.io/providers"}' \
--auth='{"google": {"type": "service_account", "credentialsfilepath": "/path/to/google-credentials.json"}}'

Servidor MCP seguro con TLS​

Inicie un servidor MCP con cifrado TLS en modo de proxy inverso:

Primero, genere los certificados TLS (autofirmados para desarrollo):

openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -days 365 -nodes

A continuación, inicie el servidor:

stackql srv \
--mcp.server.type=reverse_proxy \
--mcp.config '{
"server": {
"tls_cert_file": "server_cert.pem",
"tls_key_file": "server_key.pem",
"transport": "http",
"address": "127.0.0.1:9004",
"auth_token_env_var": "STACKQL_MCP_TOKEN"
},
"backend": {
"dsn": "postgres://stackql:stackql@127.0.0.1:5446?default_query_exec_mode=simple_protocol"
}
}' \
--pgsrv.port 5446 \
--registry='{"url": "https://registry.stackql.io/providers"}' \
--auth='{"google": {"type": "service_account", "credentialsfilepath": "/path/to/google-credentials.json"}}'

Probar el servidor MCP​

El repositorio incluye un cliente MCP de desarrollo (stackql_mcp_client) para scripts y pruebas de regresión. Compílelo con:

python cicd/python/build.py --build-mcp-client

Esto genera ./build/stackql_mcp_client.

Tenga en cuenta que stackql_mcp_client no envía ningún encabezado Authorization, por lo que el servidor al que se dirige debe establecer "allow_unauthenticated": true (como hacen los ejemplos anteriores); un servidor protegido con token le responde con 401. Además, no anuncia la capacidad de elicitación de MCP - está pensado para scripts no interactivos. Con un servidor safe o delete_safe recibirá el rechazo "client does not support elicitation" en las llamadas de mutación y de ciclo de vida. Para pruebas interactivas con solicitudes de elicitación, use un cliente MCP integrado en un editor (Claude Desktop, Cursor, Continue).

# List all available tools
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912

# Server identity, mode, audit / registry context
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action server_info

# Re-source the --env.file credentials file and report per-provider
# credential status - a good first diagnostic when queries fail on auth
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action reload_credentials

# List providers already pulled into the local cache
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action list_providers

# List providers (and versions) available in the registry
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action list_registry

# Install a provider from the registry into the local cache
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action pull_provider \
--exec.args '{"provider": "kafka"}'

# List services for a provider
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action list_services \
--exec.args '{"provider": "google"}'

# List access methods for a resource (this is how an agent finds required
# WHERE parameters before writing a query)
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action list_methods \
--exec.args '{"provider": "google", "service": "compute", "resource": "networks"}'

# Validate a SELECT without executing
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action validate_select_query \
--exec.args '{"sql": "select name from google.compute.networks where project = '"'"'my-project'"'"';"}'

# Execute a SELECT
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action run_select_query \
--exec.args '{"sql": "select name from google.compute.networks where project = '"'"'my-project'"'"';"}'

# Mutation - succeeds only against a full_access server, or against
# delete_safe (for INSERT/UPDATE) or safe with an elicitation-capable client.
./build/stackql_mcp_client exec \
--client-type=http \
--url=http://127.0.0.1:9912 \
--exec.action run_mutation_query \
--exec.args '{"sql": "delete from google.compute.firewalls where project = '"'"'my-project'"'"' and firewall = '"'"'old-rule'"'"';"}'

Respuestas de ejemplo​

server_info (con un servidor en el modo predeterminado):

{
"version": "0.10.444",
"commit": "abc1234",
"build_date": "2026-05-16T10:47:33Z",
"platform": "linux/amd64",
"transport": "http",
"sql_backend": "sqlite3",
"provider_registry": "https://registry.stackql.io/providers",
"mode": "safe",
"is_read_only": false
}

run_select_query:

{
"rows": [
{"name": "default"},
{"name": "pathfinders-test-01"},
{"name": "returning-test-03"}
]
}

run_mutation_query (con un servidor full_access):

{
"messages": ["The operation was despatched successfully"],
"timestamp": "2026-05-16T10:47:33+10:00 AEST"
}

Línea de ejemplo del log de auditoría para la misma mutación:

{"timestamp":"2026-05-16T00:47:33Z","tool":"run_mutation_query","mode":"full_access","decision":"allow","query_class":"mutation_delete","sql":"delete from google.compute.firewalls where project = 'my-project' and firewall = 'old-rule';","args":{"sql":"delete from google.compute.firewalls where project = 'my-project' and firewall = 'old-rule';","row_limit":0},"duration_ms":42}

Integración con asistentes de IA​

Para integrar el servidor MCP de StackQL con un asistente de IA, registre stackql como servidor MCP en la configuración del asistente. La mayoría de los clientes MCP integrados en editores ejecutan el servidor por stdio; para ellos, use --mcp.server.type=stdio y el asistente inicia el proceso directamente. Los agentes independientes que hablan HTTP pueden conectarse a un proceso stackql mcp --mcp.server.type=http de larga duración.

Para Claude Desktop - incluida la ficha del Anthropic Connector Directory (el método de instalación recomendado), el MCP Bundle descargable (.mcpb) y la configuración manual - consulte Usar StackQL con Claude Desktop.

nota

Las ubicaciones de los archivos de configuración varían según el sistema operativo y el asistente de IA. Consulte la documentación de su asistente de IA para conocer la ruta y el formato correctos.


Consideraciones de arquitectura​

Al elegir un modo de despliegue, tenga en cuenta:

  1. Independiente (stackql mcp): la configuración más sencilla, ideal para el desarrollo y para clientes integrados en editores por stdio.
  2. Servidor dual en memoria (stackql srv con mcp.server.type=http): un solo proceso sirve tanto el protocolo MCP como el protocolo de red de PostgreSQL. El mejor rendimiento, adecuado para la mayoría de los despliegues de producción.
  3. Proxy inverso (stackql srv con mcp.server.type=reverse_proxy):
    • permite separar las cargas de trabajo entre procesos o hosts
    • admite cifrado TLS para endpoints MCP seguros
    • permite escalar de forma independiente las interfaces MCP y PostgreSQL
    • ofrece flexibilidad para la integración con CA empresariales (nota: la compatibilidad con CA empresariales es experimental)

Y, por separado, en cuanto a la seguridad:

  • Empiece con el valor predeterminado mode: safe. Los clientes con capacidad de elicitación (Claude Desktop, Cursor, Continue) pedirán confirmación al usuario antes de cualquier mutación.
  • Fije mode: read_only para agentes de inventario o de análisis que nunca deben escribir.
  • Fije mode: delete_safe cuando quiera libertad para crear y actualizar pero desee la intervención de una persona en las operaciones destructivas.
  • Reserve mode: full_access para pipelines de automatización de confianza, y solo junto con un log de auditoría que alguien revise.
  • Establezca server.auth_token_env_var en cualquier listener HTTP al que puedan acceder otros procesos o hosts; allow_unauthenticated es para el desarrollo local. TLS por sí solo no autentica a los clientes.
precaución

Al usar TLS con autoridades de certificación (CA) empresariales, puede ser necesaria configuración adicional. Esta funcionalidad es experimental y puede requerir ajustes en función de su implementación de CA específica.


Lecturas adicionales​

  • La referencia para desarrolladores del paquete es el README de pkg/mcp_server del repositorio de stackql.
  • El documento técnico dirigido a colaboradores está en docs/mcp.md en el repositorio de stackql e incluye respuestas de ejemplo completas para cada herramienta.