shared-skill-mcp
shared-skill-mcp
Un servidor MCP alojado en AWS para conectores personalizados de claude.ai, pensado para albergar más de una herramienta con el tiempo: no se limita a la herramienta de consulta de Google Sheets con la que empezó. Una capa de autenticación Cognito compartida (inicio de sesión con Google) + una puerta de enlace de Bedrock AgentCore Gateway (el servidor MCP real) + una Lambda por herramienta.
Especificación completa, diagrama de arquitectura e historia por fases de la herramienta original query_sheet: Reel AI Workers''/skills-spec/sheet-gviz/sheet-gviz.md`.
Estado (2026-08-24)
Operativo y confirmado end-to-end, incluido un conector real de claude.ai que completa el inicio de sesión con Google y llama a la herramienta — no solo curl.
Elemento | Valor |
URL del servidor MCP (Gateway) |
|
Dominio Cognito |
|
ID del User Pool |
|
Cuenta de AWS |
|
Obtén los valores actuales (incluidos los secretos) en cualquier momento:
AWS_PROFILE=<your profile> terraform -chdir=terraform output
AWS_PROFILE=<your profile> terraform -chdir=terraform output -raw cognito_client_secretHerramientas expuestas hoy: query_sheet — ejecuta una consulta de [gviz](https://console.cloud.google.com/chart-interactive/querylanguage) (tipo SQL: select/where/group by/pivot/order by`) contra una hoja de cálculo de Google.
Related MCP server: Google Workspace MCP
Arquitectura
claude.ai connector
│ OAuth 2.1 (real Google login, via Cognito's Hosted UI)
▼
Cognito User Pool ──federates to──> Google (login only)
│ issues an access token (no "aud" claim — see gotcha below)
▼
AgentCore Gateway (CUSTOM_JWT authorizer, matches by client_id)
│ invokes under its own service role
▼
Lambda tool target (gateway-tool-handler.mjs) ──> gviz.js ──> Google Sheets APIExisten dos clientes OAuth de Google y deben seguir siendo distintos: uno que Cognito usa para el inicio de sesión (identidad federada) y otro que gviz.js usa para leer hojas de cálculo (una credencial de servicio, basada en token de refresco, nunca usada de forma interactiva). Se evitó deliberadamente reutilizar uno para ambas cosas; véase el enfoque de "dos identidades" del documento de especificación.
Cómo llegó este repositorio a su estado actual (leer antes de cambiar la configuración de autenticación)
La primera versión funcional usaba un servidor HTTP de URL de Función Lambda hecho a mano como servidor MCP, con la propia Lambda que verificaba los JWTS de Cognito y servía manualmente la metadata de descubrimiento OAuth (RFC 9728 y RFC 8414). Funcionaba con curl y un flujo de OAuth de Postman — ronda completa, inicio de sesión real de Google, datos reales de usuarios — pero el conector real de claude.ai fallaba en silencio cada vez (Couldn't connect / Authorization failed), sin ninguna señal de por qué: los registros de Lambda mostraban que claude.ai obtenía una vez la metadata de descubrimiento y luego se quedaba en silencio — sin intercambio de tokens, sin error, nada.
La teoría de trabajo era que los tokens de acceso de Cognito no incluyen la reclamación procesable aud (una limitación conocida y real de Cognito) que muestra la la especificación MCP espera que el parámetro resource que envía el cliente se refleje en esa reclamación tendría el resultado esperado. Poco después, evidencia reciente y con datos de otro lugar del ecosistema parecía confirmarla como la respuesta. Resultó ser una falso rastro: una referencia de proyecto distinto (misma persona, otro repositorio) demostró que los conectores Cognito + claude.ai funcionan bien, usando Bedrock Core Gateway delante de Cognito como capa intermedia en lugar de un servidor hecho a mano, con el autorizador CUSTOM_JWT que identifica por allowed_clients (según el client_id de Cognito) y no por aud. La causa real original de la falla nunca se determinó con total certeza — probablemente algo en la implementación hecha a mano de JSON-RPC / descubrimiento que no encajaba exactamente con lo que espera el cliente de claude.ai, a pesar de pasar todas las pruebas manuales hechas.
Lección para la próxima vez: una servidor MCP escrito a mano que sea conforme a la especificación y que pase las pruebas curl y Postman no es una prueba de que funciona con el cliente real de claude.ai — los dos pueden divergir de forma que no generan ninguna señal de error. Mejor prefijos la implementación propia AWS de servidor MCP (AgentCore Gateway) que reimplementar MCP + descubrimiento OAuth a manos, aunque eso implante un servicio AWS más que aprender y una superficie de proveedor Terraform hoy más tosca (consulta "contratiempos" más abajo).
El servidor MCP de URL de Función Lambda hecho a mano (sheets-gviz-mcp Lambda, módulos/mcp-lambda, src/lambda-handler.mjs, src/auth.mjs) fue dado de baja una vez que Gateway se confirmó funcionando — se eliminó con Terraform (sin impacto en el User Pool/dominio/cliente de aplicación Cognito que siguen vivos y que la ruta Gateway reúsa tal cual) y se eliminó del repositorio. Queda en historial de git por si el razonamiento o el código vuelven a ser útiles.
Contratiempos encontrados en el camino (corregidos en el código; conviene saberlo antes de tocar esto de nuevo)
Capa de Sheets/gviz (src/gviz.js):
El token OAuth necesita
..tanto los scopinggviz.../auth/spreadsheetscomo.../auth/spreadsheets.readonly; con soloreadonlyobtienes un401` que se ve como página HTML de login, no como un error claro.El endpoint
/tqde gviz necesita el segmento/a/<domain>/incluso con autenticación OAuthdocs.google.com/a/google.com/spreadsheets/d/<id>/gviz/tq. Configurable conGVIZ_DOMAIN_SEGMENTsigoogle.comno funciona para el dominio de tu cuenta.Pasa siempre
headers=1(hardcodeado enquerySheets). Sin él, la auto-detección de la fila de cabecera puede fallar y silenciar/doblar filas de datos reales encols[].labelcomo una sola cadena enorme, perdiéndolas por completo.
Capa AWS/Terraform:
4. Los cambios de políticas IAM de identidad pueden tardar decenas de segundos o varios minutos en aplicarse de verdad, incluso después de que PICAR y simulate-principal-policy los confirmen correctos de inmediato. No es esperar que un plan/apply recién ejecutado devuelva un 403 justo después de dar un nuevo permiso — no es señal de error, solo vuelve a intentarlo tras a little.
5. Los archivos ESM .js necesitan su propio package.json ({"type": "module"}) si se comprimen sin la raíz del "root" del repositorio — gviz.js usa export/imports y solo se resuelve como ESM porque ese archivo está junto a él en el zip de cada Lambda (src/package.json).
6. Los recursos aws_bedrockagentcore_* de Terraform son recientes y están todavía evolucionando - comprueba la estructura real de los argumentos contra el esquema del propio proveedor (terraform providers schema -json) más que confiar en documentación o posts de blogs, que siempre van retrasaturados. Requiere proveedor >= 6.0.
7. El autorizador CUSTOM_JWT de AgentCore Gateway identifica a los llamadores mediante allowed_clients (el client_id de Cognito), no mediante allowed_audience — esto es lo que lo hace funcionar con los tokens de acceso no estándar (sin aud) de Cognito sin ninguna capa adicional de acuñación de tokens.
Configuración
1. Verificar que la credencial de Sheets funciona (standalone, sin AWS)
cp .env.example .env # fill in GOOGLE_CLIENT_ID/SECRET/REFRESH_TOKEN, SPREADSHEET_ID
node scripts/phase1-test.mjs "select *"Se sabe que funciona cuando: imprime {colunas, filas} para una consulta real. Si falla, el problema es del lado de Google (alces, compartir, API no habilitada) — la forma más barata de detectarlo antes de tocar AWS.
2. Desplegar Cognito + Gateway + la Lambda de la herramienta
Necesita credenciales AWS con los permisos de terraform/iam-policy.json, además de un segundo cliente OAuth de Google (aplicación Web, separado del que lee Sheets) para el inicio de sesión Cognito. Su URI de redirección necesita el dominio de Cognito, que aún no existe — quiere romper ese círculo con un primer despliegue parcial:
scripts/tf.sh apply -target=module.auth.aws_cognito_user_pool.this \
-target=module.auth.aws_cognito_user_pool_domain.thisCrea el cliente OAuth de Google con el redirect URI https://<esa-salida-dominio>/oauth2/idpresponse, completa GOOGLE_LOGIN_CLIENT_ID / GOOGLE_LOGIN_CLIENT_SECRET en .env, y luego:
scripts/tf.sh applyCLAUDE_OAUTH_REDIRECT_URI no necesita configurarse — por defecto es https://claude.ai/api/mcp/auth_callback, confirmado como funciona con conectores reales.
3. Añadir como conector en claude.ai
Configuración → Connectors → Add custom connector:
Server URL: la salida
gateway_urlAdvanced settings → OAuth Client ID/Secret: las salidas
cognito_client_id/cognito_client_secret
Debe activar un inicio de sesión real de Google through la UI de ofrecida de Cognito (Hosted UI), y después dejar que Claude llame query_sheet (visible en el chat como bloque de herramientas).
Añadir una nueva herramienta
Escribe un handler Lambda que use el contrato de Lambda "objetivo" de AgentCore —
eventplano = los argumentos de la herramienta, sin envoltura JSON-RPC (Gateway gestiona el contexto MCP). Vea el patrón ensrc/gateway-tool-handler.mjs.Añade un bloque
module "..." { source = "./modules/gateway-tool-lambda" ... }enmain.tf.Añade un bloque
aws_bedrockagentcore_gateway_targetpara él — ya sea extiendemodules/agentcore-gatewaypara que acepte una lista de targets, o añade el recurso directo enmain.tfapuntado amodule.gateway.gateway_id.
No hace falta nuevo cliente OAuth, nuevo dominio Cognito, ni nueva Gateway — todo lo que hay en module.auth y module.gateway es compartido.
Estructura
src/
gviz.js Sheets-reading logic — token refresh, gviz query, response
parsing. Host-agnostic; used by gateway-tool-handler.mjs.
gateway-tool-handler.mjs AgentCore Gateway Lambda-target contract for query_sheet —
flat event-in/JSON-out, no JSON-RPC framing (Gateway
handles MCP protocol translation itself).
package.json {"type": "module"} — required for gviz.js's ESM syntax to
resolve once zipped alone, without the repo root's
package.json alongside it.
scripts/
phase1-test.mjs Standalone local proof the Sheets credential + gviz query
round-trip works, no AWS involved.
tf.sh Wraps `terraform` with GOOGLE_*/Cognito vars sourced from
.env — use this instead of calling terraform directly.
terraform/
main.tf Root — provider, variables, the shared auth module, the
claude.ai connector's Cognito app client, the Gateway, and
the query_sheet tool Lambda.
modules/mcp-auth/ Cognito User Pool + Google identity provider + Hosted UI
domain. Shared — instantiate once per AWS account.
modules/agentcore-gateway/ The Gateway (CUSTOM_JWT authorizer) + the query_sheet
Gateway Target. Extend for more targets, or add more
gateways for a genuinely separate trust boundary.
modules/gateway-tool-lambda/ A standalone tool Lambda for a Gateway target — no
Function URL, no public permissions, no own Cognito
client. Gateway is the only caller, via its service role.
iam-policy.json Deploy-time IAM policy for whatever AWS identity runs
scripts/tf.sh. Broad on bedrock-agentcore:* deliberately —
that service/provider surface is new and evolving.This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceMCP server for Google Drive, Docs, and Sheets — built for Claude Code. Gives Claude Code direct read/write access to Google Sheets (cell-level edits, formatting, structure), Google Docs (insert, replace, append), and Drive (search).521MIT
- FlicenseNot gradedqualityDmaintenanceEnables interaction with Google Sheets, Docs, Slides, and Drive through a remote MCP server hosted on Cloudflare Workers, with OAuth authentication and Claude-native connect.
- FlicenseNot gradedqualityDmaintenanceMCP server for Claude Desktop that provides tools to read/write Google Sheets, manage Gmail, schedule Google Calendar events, and run queries on Neon Postgres databases.
- AlicenseBqualityCmaintenanceMCP server that gives Claude full read-write access to Google Drive, Docs, Sheets, and Slides using your own Google OAuth credentials and hosted server.25MIT
Related MCP Connectors
Hosted Amazon Seller Central and Amazon Ads MCP server for Claude, ChatGPT, Cursor, and agents.
Hosted Amazon Seller and Vendor MCP server for Claude, ChatGPT, Cursor, Codex, Gemini, Copilot.
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/amar-p6/shared-skill-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server