Skip to main content
Glama
amar-p6

shared-skill-mcp

by amar-p6

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)

https://sheets-gviz-gateway-63psdjvcgs.gateway.bedrock-agentcore.eu-west-1.amazonaws.com/mcp

Домен Cognito

sheets-gviz-b24dc744.auth.eu-west-1.amazoncognito.com

ID пользовательского пула

eu-west-1_sfGqYcC0a

Аккаунт AWS

423566941862, eu-west-1

Актуальные значения (включая секреты) можно получить в любой момент:

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):

  1. OAuth-токену нужны две области — .../auth/spreadsheets и .../auth/spreadsheets.readonly; одного readonly даст 401, который похожа на HTML-страницу входа, а не на нормальную ошибку.

  2. У gviz эндпоинт /tq требует сегмент пути /a/<domain>/, даже для OAuth-доступа (bearer): docs.google.com/a/google.com/spreadsheets/d/<id>/gviz/tq. Это настраивается через GVIZ_DOMAIN_SEGMENT, если google.com не подходит для твоего домена учетной- эки-записи.

  3. Всегда передавай 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 apply

CLAUDE_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).

Добавление нового инструмента

  1. Напишите Lambda-handler, следуя контракту AgentCore Lambda-target: плоское событие event = аргументы инструмента, без JSON-RPC-обёртки (Gateway сам занимается MCP-фреймлей). Пример паттерна — src/gateway-tool-handler.mjs.

  2. Добавьте блок module "..." { source = "./modules/gateway-tool-lambda" ... } в файл main.tf.

  3. Добавьте для него ресурс 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.
F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP 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).
    52
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP 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.

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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