shared-skill-mcp
shared-skill-mcp
Развёрнутое в AWS описание сервера MCP для пользовательских коннекторов claude.ai, думать о котором как об MCP-сервере, рассчитанном на то, чтобы со временем содержать более одного инструмента, — не только инструмент запросов к Google Sheets, с которого он начинался. Один общий слой аутентификации Cognito (вход через Google) + один Bedrock AgentCore Gateway (собственно MCP-сервер) + одна Lambda на инструмент.
Полная спецификация, схема архитектуры и поэтапная история исходного инструмента query_sheet: Reel AI Workers/skills-spec/sheet-gviz/sheet-gviz.md.
Статус (2026-08-24)
Работает в проде и подтверждённо работает «от и до» — включая реальный коннектор claude.ai, который выполнил вход через Google и вызвал инструмент, а не просто curl.
Параметр | Значение |
URL MCP-сервера (Gateway) |
|
Домен Cognito |
|
ID пользовательского пула |
|
Аккаунт AWS |
|
Актуальные значения (включая секреты) можно получить в любой момент:
AWS_PROFILE=<your profile> terraform -chdir=terraform output
AWS_PROFILE=<your profile> terraform -chdir=terraform output -raw cognito_client_secretСейчас доступен инструмент: query_sheet — выполняет
gviz
запрос (SQL-подобный: select/where/group by/pivot/order by) к Google
Sheets.
Related MCP server: Google Workspace MCP
Архитектура
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 APIЕсть два клиента Google OAuth-приложений, которые должны оставаться разными: один используется Cognito для входа (федеративная идентичность), другой — gviz.js для чтения таблиц (сервисные учётные данные на базе refresh-токена, для интерактивного режима не применяются). Использовать один и тот же клиент для обеих целей намеренно избегали — см. концепцию «two identities» (двух идентичностей) из документа спецификации.
Как этот репозиторий пришёл к текущему виду (стоит прочитать перед изменением настройки auth)
Первая рабочая версия использовала самодельный Лямбда-шлюз Function URL как MCP-сервер, где сама Lambda проверяла JWT Cognito и вручную отдавала discovery-метаданные OAuth (RFC 9728 / RFC 8414). Она работала по curl и ручному OAuth-сценарию в Postman — полный круговой путь: реальный вход Google, реальные данные таблицы, — но фактический клиент-коннектор claude.ai при обращении к этому серверу каждый раз молча отваливался (Couldn't connect / Authorization failed), не давая ни намёка на причину: в логах Lambda было видно, что claude.ai один раз запрашивает discovery-метаданные, а потом замирает — ни обмена токеном, ни ошибки, ничего.
Рабочая гипотеза в тот момент: access-токены Cognito не содержат claim aud (известное реальное ограничение Cognito — подтверждено декодированием настоящего токена), а спецификация MCP ожидает, что параметр resource, отправляемый клиентом, будет отражён в этом claim. Недавние, выглядевшие правдоподобно факты из других мест экосистема, казалось, подтверждали: это тот самый ответ. Оно оказалось ложным следом — рабочий эталон из внешнего проекта (тот же человек, другой репозиторий) доказал, что связка Cognito + коннектор claude.ai работает прекрасно, если перед Cognito, а не самодельным сервером, стоит Bedrock AgentCore Gateway, и его авторизатор CUSTOM_JWT сопоставляет вызывающих по allowed_clients (это client_id Cognito), a (а не) не по aud. Настоящая причина исходного сбоя так и не была однозначно установлена — вероятнее всего, что-то в самодельной реализации JSON-RPC/discovery не вполне совпадало с тем, чего ждёт клиент claude.ai, несмотря на прохождение всех проверок вручную, которые ему устроили.
Урок на будущее: самодельный MCP-сервер, который выглядит соответствующим спецификации и проходит тесты curl и Postman, еще не доказывает, что он работает с настоящим клиентом claude.ai, — они могут расходиться так, что не дают ни одной сигнальной ошибки. Ставьте собственную реализацию MCP-сервера от AWS (AgentCore Gateway) вместо ручной реализации MCP + OAuth discovery, даже если ради этого придётся освоить ещё один AWS-старвис и иметь дело с более шероховатой Terraform-поверхностью провайдера (см. грабли ниже).
Самодельный сервер на Function URL (sheets-gviz-mcp на Lambda, modules/mcp-lambda, src/lambda-handler.mjs, src/auth.mjs) был выведен из эксплуатации, как только Gateway подтвердил работу: снёсен через Terraform (ноль влияния на остающийся живым Cognito User Pool/domain/app client, который путь Gateway использует как есть) и удалён из репозитория. Он в истории git, если решения и код снова понадобятся.
Попутные грабли (мелочи уже исправлены в коде, но знать о них стоит, прежде чем снова всё это трогать)
Слой Sheets/gviz (src/gviz.js):
OAuth-токену нужны две области —
.../auth/spreadsheetsи.../auth/spreadsheets.readonly; одногоreadonlyдаст 401, который похожа на HTML-страницу входа, а не на нормальную ошибку.У gviz эндпоинт
/tqтребует сегмент пути/a/<domain>/, даже для OAuth-доступа (bearer):docs.google.com/a/google.com/spreadsheets/d/<id>/gviz/tq. Это настраивается черезGVIZ_DOMAIN_SEGMENT, еслиgoogle.comне подходит для твоего домена учетной- эки-записи.Всегда передавай
headers=1(жёстко зашито вquerySheet). Без него автоопределение строки заголовков у gviz может ошибиться и молча сложить реальные строки данных вcols[].labelодной огромной строкой, полностью потеряв их.
AWS/Terraform-слой:
4. Изменения identity-политик IAM могут реально вступать в силу в течение десятков секунд или даже нескольких минут, даже если после это сразу aws iam simulate-principal-policy подтверждает их корректность. Ожидай: свежий plan/apply после того, как дали новое действие, вернёт 403, — это нормально; просто подожди немного и повтори.
5. ESM-файлам .js нужен собственный package.json ({"type": "module"}), если из катают без корневого package.json из репозитория. gviz.js использует export/import и распознается как ESM только потому, что этот package.json находится рядом с ним в zip-архиве каждого Lambda (src/package.json).
6. Terraform-ресурсы aws_bedrockagentcore_* — недавние и текучие; сверь фактическую форму аргументов сную схему самого провайдера, абез доверяя устаревающим статьям и докам (terraform providers schema -json). Нужен провайдер >= 6.0.
7. Авторизатор CUSTOM_JWT у шлюза AgentCore Gateway сопоризует вызывающих по allowed_clients (то есть client_id Cognito), а не по allowed_audience — именно это позволяет ему работать со средствами нестандартными (без aud) токенами Cognito без дополнительного слоя создания токенов.
8. Упаковка существующих живых Terraform-ресурсов в модули была рискованной: и рефакторинг фазы 4 в модули, и последующий вывод Function URL из эксплуатации делались через terraform state mv и реальную проверку plan (0 destroy на всё, что должно остаться) перед каждым apply. Так app client, для которого у claude.ai уже есть учётные данные, перемещался дважды и никогда при этом ломался / не пересоздавался.
Setup
1. Доказать, что учётные данные для Sheets работают (автономно, без AWS)
cp .env.example .env # fill in GOOGLE_CLIENT_ID/SECRET/REFRESH_TOKEN, SPREADSHEET_ID
node scripts/phase1-test.mjs "select *"Готово, когда: выведет {columns, rows} для реального запроса. Ошибки тут — со стороны Google (области доступа, шаринг, незапущенный Sheets API), и это самое дешёвое место, чтобы поймать их перед работой с AWS.
2. Деплой Cognito + Gateway + Lambda инструмента
Нужны AWS-креды с разрешениями из terraform/iam-policy.json и второй ГмGoogle OAuth-клиент (веб-приложение, отдельный от того, ЭМ-файл от Google Sheets, для логина через Cognito). Его redirect URI должен ссылаться на домен Cognito, которого ещё нет. Разорви этот курице-и-яйцо-цикл сначала частичным apply:
scripts/tf.sh apply -target=module.auth.aws_cognito_user_pool.this \
-target=module.auth.aws_cognito_user_pool_domain.thisСоздайте Google OAuth-клиент с redirect URI
https://<field from the output>/oauth2/idpresponse, наполните
GOOGLE_LOGIN_CLIENT_ID/GOOGLE_LOGIN_CLIENT_SECRET в .env, а затем:
scripts/tf.sh applyCLAUDE_OAUTH_REDIRECT_URI настраивать не нужно — по умолчанию это
https://claude.ai/api/mcp/auth_callback, и рабоспособность с реальным коннектором подтверждена.
3. Добавить его как коннектор в claude.ai
Настройки → Коннекторы → Добавить пользовательский коннектор:
URL сервера: output
gateway_urlДополнительно → OAuth Client ID/Secret: outputs
cognito_client_id/cognito_client_secret
Он должен спровоцировать настоящий вход через Google Cognito Hosted UI и затем дать Claude вызывать query_sheet (в чате видно как блок tool-use).
Добавление нового инструмента
Напишите Lambda-handler, следуя контракту AgentCore Lambda-target: плоское событие
event= аргументы инструмента, без JSON-RPC-обёртки (Gateway сам занимается MCP-фреймлей). Пример паттерна —src/gateway-tool-handler.mjs.Добавьте блок
module "..." { source = "./modules/gateway-tool-lambda" ... }в файлmain.tf.Добавьте для него ресурс
aws_bedrockagentcore_gateway_target— либо расширьтеmodules/agentcore-gateway, чтобы он принимал список таргетов, либо добавь ресурс прямо вmain.tf, указавmodule.gateway.gateway_id.
Новый Google OAuth-клиент, домен Cognito и новог Gateway не узнат — всё в module.auth и module.gateway является общим.
Структура
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