Skip to main content
Glama
amar-p6

shared-skill-mcp

by amar-p6

shared-skill-mcp

claude.ai のカスタムコネクタ向けの AWS ホスティング MCP サーバーです。時間経過に複数のツールを保持できるように構築されており、最初に実装した Google Sheets クエリツールに限定されるものではありません。共有の Cognito 認証層(Google ログイン)+ 1 つの Bedrock AgentCore Gateway(実際の MCP サーバー)+ ツールごとの 1 つの Lambda で構成されています。

元の query_sheet ツールの完全な仕様、アーキテクチャ図、フェーズごとの履歴は、Reel AI Workers/skills-spec/sheet-gviz/sheet-gviz.md にあります。

スタータス (2026-08-24)

本番稼働しており、エンドツーエンドの動作確認済みです。実さい claude.ai コネクタが Google ログインを完了してツールを呼び出するところまで含んでおり、単な る curl だけではありません。

項目

MCP サーバー URL(Gateway)

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

Cognito ドメイン

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

ユーザープール ID

eu-west-1_sfGnYcC0a

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 クライアントは 2 つあり、常に別々のままにしなければなりません。1 つは Cognito、もう 1 つは Cognito(フェ她已经)。 gviz.js が Sheets を読むために使う1つ(サービス認証情報、リフレッシュトークンベース、インタラクティブには使わない)。両方に1つを再利用することは意図的に避けています — 仕様書の「2つのアイデンティティ」という考え方を参照してください。

このリポジトリができた経緯(認証設定を変更する前に読んでおく価値あり)

最初に動作したバージョンでは、手作りの Lambda Function URL を MCP サーバーとして使っていました。Lambda 自身が Cognito JWT を検証し、OAuth ディスカバリメタデータ(RFC 9728 / RFC 8414)を手動で配信ししていました。curl と手動の Postman OAuth フローでは動いていました — 完全なラウンドトリップ、実際の Google ログイン、実際の Sheet データ — しかし、claude.ai の実際のコネクタクライアントは、毎回それに対して静かに失敗していました(Couldn't connect / Authorization failed)。理由は何も分かりませんでした。Lambda のログには、claude.ai が discovery メタデータを一度取得した後、沈黙する姿が残っていました — トークン交換もエラーも何もありません。

当時の作業仮説は、Cognito の access tokenには aud クレームが無い(既知の Cognito の制約であり、実トークンをデコードして確認した)こと、そして MCP 仕様では、クライアントが送信する resource パラメータがそのクレームに反映されると想定していることでした。周辺エコシステムの別のところからの、最近出た信頼できるような証拠が、これを 正解 のように見せていました。しかし実際にはそれは false でした。同じ人物の別プロジェクトにあった実際の reference実装により、Cognito + claude.ai のコネクタは、手作りサーバの代わりに Bedrock AgentCore Gateway を Cognito の front に配置し、その CUSTOM_JWT オーソライザが allowed_audience でなく allowed_clients(CogniTo の client_id)で照合することで問題なく動くことを実証できました。最初の失敗の真の根本原因は決定的には分かっていません — おそらく、自作の JSON-RPC/discovery 実装が、claude.ai のクライアントが期待するものと「マニュアルテストは全て通るが」微妙に合っていなかったのだと思われます。

教訓: curl とPostmanのテストを通過したような custom made MCP server は、claude.ai の実際のクライアントで動く保証にはなりません。両者はエラーサインを一切出さずに divergence することができます。MCP + OAuth discovery を手作りで再実装するよりも、AWS 自身の MCP サーバ実装(AgentCore Gateway)を選ぶべきです。たとえそれで追加のAWSサービスを学ぶことになり、現在のTerraform provider の粗さに悩まされても(後述の注意点)。

自作の Function URL サーバー(sheets-gviz-mcp Lambda、modules/mcp-lambdasrc/lambda-handler.mjssrc/auth.mjs)は、Gateway が動作を確認できた後に廃止しました。Terraform で撤去(現存する Cognito User Pool ドメイン、アプリクライアントには無影響。Gateway 経路はそのまま再利用)し、リポジトリからも削除しました。この思考がまた必要になった時のために、git 履歴には残っています。

これまでの落とし穴(コードでは修正済み、再び触れる前に知っておくとよい)

Sheets/gviz レイヤーsrc/gviz.js):

  1. OAuth トークンには .../auth/spreadsheets.../auth/spreadsheets.readonly の両方のスコープが必要です。readonly だけだと 401 が返り、実際のエラーではなくHTML のログインページのように見えます。

  2. gviz の /tq エンドポイントは、OAuth Bearer認証でも /a/<domain>/ のパスセグメントが必要です — docs.google.com/a/google.com/spreadsheets/d/<id>/gviz/tq。自分のアカウントのドメインで google.com が使えない場合は、GVIZ_DOMAIN_SEGMENT で設定できます。

  3. 常に headers=1 を渡してください(querySheet 内にハードコード済み)。これがないと、gviz のヘッダー行自動検出が誤って、実際のデータ行を cols[].label に 1 つの巨大な文字列として包み込み、データを完全に失ってしまうことがあります。

AWS/Terraform レイヤー: 4. IAM アイデンティティポリシーの変更は、aws iam simulate-principal-policy が即座に正しいと返しても、実際に反映されるまで数十秒から数分かかる場合があります。新しいアクションを付与した直後の新しい plan/apply は一度だけ 403 が出ることが想定されます。これは何かが間違っているという意味ではなく、しばらく待って再試行してください。 5. ESM の .js ファイルは、リポジトリ直root の package.json なしで zip 化される場合、自分自身の package.json{"type": "module"})が必要です。gviz.jsexport/import を使っており、それらすべてのLambdaのzip内にそのファイルが(src/package.json)並んでいるからこそESMとして解決されます。 6. aws_bedrockagentcore_* Terraform リソースは最近のもので、まだ変化の途中です。ドキュメントやブログではなく(遅れることがある)、provider自身のスキーマ(terraform providers schema -json)で実際の引数型を確認してください。provider は >= 6.0 が必要です。 7. AgentCore Gateway の CUSTOM_JWT オーソライザは、呼び出し元を allowed_audience ではなく allowed_clients(Cognito の client_id)で照合します。これによって、Cognito の非標準(aud がない)アクセストークンでも余分なトークン minting 層を使わずに動作します。 8. 稼働中の Terraform リソースをモジュールにまとめ直すのは、破壊リスクがあります。Phase 4→モジュールのリファクタリングと、後に行ったFunction URLの廃止のどちらも、毎回の apply の前に terraform state mv と、実際の plan 確認(残すべきものを0破壊)を行いました。claude.ai がすでに認証情報を持っているアプリクライアントは、このように2回移動しましたが、破壊・再作成は一度もされませんでした。

セットアップ

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)と、Cognito ログイン用の2つ目の Google OAuth クライアント(Webアプリ、Sheets 読み取り用とは別)が必要です。そのリダイレクトURIには Cognito のドメインが必要です。しかし、そのドメインはまだ存在しません。まず部分apply でこの卵が先か鶏が先か問題を解消します:

scripts/tf.sh apply -target=module.auth.aws_cognito_user_pool.this \
  -target=module.auth.aws_cognito_user_pool_domain.this

リダイレクトURI を https://<that domain output>/oauth2/idpresponse にして Google OAuth クライアントを作成し、.envGOOGLE_LOGIN_CLIENT_ID / GOOGLE_LOGIN_CLIENT_SECRET を記入します。次に:

scripts/tf.sh apply

CLAUDE_OAUTH_REDIRECT_URI を設定する必要はありません — デフォルトが https://claude.ai/api/mcp/auth_callback で、実際のコネクタで動作確認済みです。

3. claude.ai のコネクタとして追加する

設定 → Connectors → Add custom connector:

  • Server URL: gateway_url 出力

  • Advanced settings → OAuth Client ID/Secret: cognito_client_id / cognito_client_secret 出力

Cognito の Hosted UI 経由で実際の Google ログインが実行され、その後 Claude が query_sheet を呼び出せるようになります(チャット内で tool-use ブロックとして表示されます)。

新しいツールを追加する

  1. AgentCore Lambda-target の契約に従った Lambda ハンドラを書くこと。フラットな event = ツールの引数で、JSON-RPC ラッピングはありません(Gateway が MCP フレームを処理します)。パターンは src/gateway-tool-handler.mjs を参照。

  2. main.tfmodule "..." { source = "./modules/gateway-tool-lambda" ... } ブロックを追加する。

  3. そのために aws_bedrockagentcore_gateway_target ブロックを追加する — modules/agentcore-gateway をターゲットのリストを受け取るように拡張するか、main.tf に直接 module.gateway.gateway_id を指すようにリソースを追加します。

新しい Google OAuth クライアント、新しい Cognito ドメイン、新しい Gateway は必要ありません — module.authmodule.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