Borrowing it
Nothing to install: this file belongs to bakissation/mcp-google-multi. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/bakissation/mcp-google-multi/dev/CLAUDE.mdgit clone --depth 1 https://github.com/bakissation/mcp-google-multiWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/instructions/bakissation/mcp-google-multi/claude-md)<a href="https://agentmods.dev/instructions/bakissation/mcp-google-multi/claude-md"><img src="https://agentmods.dev/badge/instructions/bakissation/mcp-google-multi/claude-md/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/instructions/bakissation/mcp-google-multi/claude-md"><img src="https://agentmods.dev/badge/instructions/bakissation/mcp-google-multi/claude-md.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.06159 | $0.06159 |
| Opus 5.5 | $0.02464 | $0.02464 |
| Sonnet 5.5 | $0.01232 | $0.01232 |
| Haiku 4.5 | $0.00616 | $0.00616 |
Grade A, and why
mcp-google-multi CLAUDE.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 140 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Working on mcp-google-multi
Conventions for AI assistants modifying this codebase. v6 is user-OAuth only: stdio by default, optional Streamable HTTP (MCP_TRANSPORT=http|both) behind a built-in OAuth 2.1 authorization server; one owner identity context per transport, with seams (hint provider, boot gates, tenant purge) a multi-tenant host can fill. User-facing rationale for the big mechanisms (discover-first, fan-out, trimming, write-control, escape hatch) lives in docs/features.md; implementation rationale too long for a code comment (Windows rename retry, GET/HEAD body stripping, admin-scope gating) lives in docs/internals.md. Keep both in sync when behavior changes — comments stay one-line and point there.
Project shape
src/index.ts— entry.main()dispatches the CLI commands (auth,migrate-tokens,migrate-config,doctor,reset,metrics,write-client-config,account export|import,config check), else resolves the transport (src/http-config.ts), the master key and usage metrics, then builds oneMcpServer+ identity context + registry per transport: stdio, and/or HTTP (forcescuratedmode, mounts the OAuth AS, refuses to boot withoutMCP_OWNER_EMAILSunless multi-tenant boot gates are installed). Each registry'sinstallListHandler()runs before connect.src/compose.ts—buildRegistry(server, ctx, mode?, metrics?)registers every enabled service (the curatedSERVICEStable plusGENERATED_SERVICES, gates insrc/services.ts, all filtered byGOOGLE_TOOLSETS), fails fast ifregistry.services()is empty (BEFORE meta tools register — escape tools would mask an empty service set), thenregisterDiscoverTools()+registerEscapeTools()+registerAccountTools()+registerDiagnoseTool(), plusregisterAccountWizardTools()for the owner context only.requestHooksFor()builds the per-request arg-normalization / unknown-arg / validation-envelope hooks both transports share. No import-time side effects.src/registry.ts—ToolRegistrywraps the MCP server: records aToolEntryper tool (name, service, cud, description, inputShape, annotations, clientMeta?, meta, generated, irreversible, requiredScopes?), derivescud(read/create/update/delete) from the tool name viainferCud, enforces write-control by wrapping every CUD handler, injects computed annotations (readOnlyHint/destructiveHint;anthropic/requiresUserInteractiononIRREVERSIBLE_TOOLS), and owns discover-first visibility: all tools register eagerly (always callable — graceful dispatch), but the customtools/listhandler advertises perGOOGLE_DISCOVERYmode (lazydefault = meta +reveal()ed services;curated= + all curated;eager= everything;generatedprovenance on ToolEntry from the explicit-cud marker; tools no catalog bundle can authorize are never advertised).discover_all/discover_resetmetas toggle a runtime lazy→curated overlay (expand()/collapse(), both firetools/list_changed; collapse also clears reveals — a client mishandling a shrinking list degrades collapse to a session no-op, zero correctness impact).hideServices(services)keeps whole services out oftools/listwhatever the mode or a later reveal (hidden, not unregistered: still callable by name and listed by{service}_discover; meta tools never hidden; each call replaces the earlier set) for a host that serves one registry per identity. ThehttpConfirmfield (HttpConfirm, seesrc/http-confirm.ts) decides how an escape-hatch write is confirmed over HTTP.installListHandler()must run after registration, before connect. Service files callserver.registerTool(...)—serveris aToolRegistry.src/discover.ts—registerDiscoverTools(): one eager{service}_discovermeta-tool per service; returns the catalog (registry.catalog), reveals the service, triggerstools/list_changed. Never emittool_referencecontent blocks or top-leveldefer_loadingfields — strict SDK clients reject/strip them (a client-side constraint, independent of the server SDK version).src/toolsets.ts—GOOGLE_TOOLSETSparsing (all| CSV of service names).src/discovery-client.ts— runtime Google API Discovery:loadMethodIndex(api)fetcheshttps://www.googleapis.com/discovery/v1/apis/{id}/{version}/reston demand, disk-caches 7 days (DISCOVERY_CACHE_PATH), stale-if-offline;cudFromMethod(HTTP verb → cud, POST read-verbs like batchGet → read),expandPath({param} + {+param} templates),searchMethods. Deps injectable for tests — never hit the network in unit tests.src/tools/google-api.ts—registerEscapeTools(): eagergoogle_api_search+google_api_call. The call tool enforces write-control ITSELF (its registry cud is read, so the wrapper doesn't gate it) viaisAllowedon the method's derived cud — keep that check when touching this file.src/fanout.ts— cross-account fan-out:parseAccountSelector("*"| CSV | single),runFanout(bounded 5, per-account isolation, merged{results, partial}envelope with parsed payloads; never embed raw JSON strings),fanoutAccountField(union schema: a live*-or-alias check | CSV regex; the set is read at parse time). Wired inregistry.ts: read tools only, never meta (google_api_callinfers cud=read but executes writes), neverFANOUT_EXCLUDE(read tools that write local files). Fan-out wraps the raw handler INNERMOST so compaction runs once on the merged envelope.src/tools/accounts-tool.ts— eageraccount_listmeta tool +deriveAccountHealth(pure, deps-injectable). Reads the context's token store throughaccountHealthDepsFor(ctx.tokenStore)— NEVERgetClient(would attach refresh listeners).readTokenthrows on decrypt failure (only returns null when missing) — keep the per-account try/catch. Never output token values.src/trim.ts— response trimming:compactResult(registry re-serializes every JSON text output compactly;GOOGLE_TRIM=offopts out — compaction only, never the caps),capText(paging caps with truncated/totalChars),sliceClean(permanent caps — drops a trailing lone surrogate). Fat readers own their caps:drive_readmaxChars/offset, gmail reads 50k body cap +fullparam,calendar_list_eventsANDcalendar_list_instanceslist-modeformatEvent(e, {full:false}). New fat-payload tools should reuse these helpers.src/write-control.ts—resolvePolicy()(env → policy) +isAllowed()(deny-by-default verdict) +denyReason()/writeDisabledResult()+describePolicy()(config checkrendering) +IRREVERSIBLE_TOOLS.src/outbound-allowlist.ts— opt-inGOOGLE_OUTBOUND_ALLOWLISTrecipient gate (Gmail recipients, Calendar attendees, Drive grantees, escape-hatch bodies); off when unset.src/token-store.ts— encrypted token store (AES-256-GCM, key fromresolveMasterKey());readToken/writeToken/updateToken/hasTokenover the owner dir,createTokenStore(dir, {tenantId?})for any other. Themigrate-tokensCLI lives insrc/migrate-tokens.ts.src/master-key.ts—MASTER_KEYandMCP_JWT_KEYresolution (see Auth / tokens).src/auth.ts— OAuth flow + per-account scope resolution: each account'sscopeProfile(from the AccountSet) selects bundles from the catalog;getOptionalBundles()returns the UNION across accounts (drives service registration), authz stays per-account; legacyGOOGLE_OPTIONAL_SCOPESacts as an implicit global profile (warns).src/scope-catalog.ts— the ONE bundle catalog (scopes + description + risk + workspaceOnly; keys are frozen public API, renames via BUNDLE_ALIASES only); unknown bundle names fail E_UNKNOWN_BUNDLE with a did-you-mean hint.src/client.ts—makeGetClient(contextKey, deps)builds a context's client factory;getClientis the owner's. Fresh OAuth2Client per call from the encrypted token (concurrent calls for one alias share the in-flight build); itstokenslistener re-encrypts on refresh (updateToken).CuratedToolDeps(getClientFn,localFiles) is the injection surface for curated tool files.src/accounts.ts—resolveAccounts()builds theAccountSet(registry): whole-registry env override viaGOOGLE_ACCOUNTS, elseconfig.json;getAccountSet()is the live accessor (dispatch-time readers use it, never a captured snapshot);invalidateAccountSet()/isAccountSetStale()back the reload path. Token dir defaults to~/.config/mcp-google-multi/tokens(overrideTOKEN_STORE_PATH).src/config-file.ts—config.jsonzod-strict schema (secrets-shaped keys fail), version gate,mutateConfigFileread-latest-under-lock writer.src/fs-atomic.ts— path-keyed hardlink lock + atomic write (generalized from the token store; token writes delegate to it).src/identity.ts—buildIdentityContext(env, {transport}): the frozen forward-compat seam{subject, accounts, policy, getClient, tokenStore}(subjectis'owner'in the free core);buildRegistry(server, ctx)consumes it.index.tsbuilds one owner context per transport;isOwnerContext()gates host-disk tools and the account wizard.src/migrate-config.ts—migrate-configCLI: env ->config.jsonaccounts (idempotent, never edits env).src/tools/_errors.ts—mapGoogleErrortyped taxonomy +handleGoogleApiErrorresult wrapper; each service file defines its ownhandle<Service>Errorshim over it (optionally with a service-specific 403 hint).src/tools/_coerce.ts—coerceArray/coerceJson/coerceBooleanfor string-encoded client args.src/scope-observability.ts— the #114 three-state classifier (callable / requestable_not_granted / not_requestable{add_bundle|account_type|unknown_scope}): joins a method's required scopes (escape hatch: runtime Discovery; generated tools: baked+interned at gen time onApiMethodRef.scopes) against the account's GRANTED token scopes, enrichesinsufficient_scopehints with copy-pasteable remediation and an honestretriable.account_list's scopes block is the compact profile∪granted report; the registered-tool universe is doctor's. Also exportsaccountScopeSets(granted and profile scope sets for one account;ScopeSetDepsreads a custom token store) andsummarizeToolScopes(how many registered tools an account can call and which bundle unlocks the rest), behind theScopesline ofdoctorandconfig check.src/executor.ts—executeApiMethod: the shared REST executor for generated tools andgoogle_api_call(100k-char response cap).src/arg-normalize.ts/src/arg-strict.ts— transport-level argument handling: snake_case→camelCase key rename (GOOGLE_ARG_NORMALIZE, on by default), unknown-argument screening (GOOGLE_ARG_UNKNOWN=reject|warn|off, defaultreject), andwithValidationEnvelope(SDK schema-validation prose → JSON error envelope).src/http-config.ts—MCP_TRANSPORT(stdiodefault |http|both),MCP_HTTP_HOST/MCP_HTTP_PORT(127.0.0.1:4243),MCP_PUBLIC_URL,MCP_ALLOWED_ORIGINS; canonicalizes the advertised resource URI exactly once.src/http-transport.ts—HttpTransportHost: node:http server, Host/Origin guard, stateless per-request/mcpdispatch, mounted AS routes. Stateless HTTP cannot pushtools/list_changed, so it forcescuratedmode.src/http-confirm.ts:HttpConfirm(the registry'shttpConfirmfield): how an escape-hatch write that needs a human is confirmed over stateless HTTP, where the server cannot ask mid-call. 2026-07-28 revision: an SDKinputRequiredresult (elicit keyconfirm, signedrequestStatebound to the call hash and the subject), served by the second server a lane builds throughServerTarget.modern; the client repeats the call with its answer. 2025 revision, only withMCP_HTTP_CONFIRM_TOKEN(orServerTarget.confirmToken): refusalconfirmation_requiredwith asummaryand a single-useconfirmToken(ConfirmTokens, signed withMCP_CONFIRM_KEY, expiryMCP_CONFIRM_TTL_SECONDS); the repeat call carries it outside the tool schema, and a changed, reused or expired token isconfirmation_invalid. stdio keeps live elicitation. User doc:docs/configuration.md; rationale:docs/internals.md.src/oauth-as.ts—buildAuthServer(): built-in OAuth 2.1 authorization + resource server. Mints its own audience-bound HS256 token for the MCP client, gates on an owner Google login (MCP_OWNER_EMAILS; those Google tokens are discarded), keeps per-alias Google tokens separate, and issues signedalias_reauthlinks.src/mcp-token.ts— JWT/state/code signing, replay guard, rotated refresh store, keyed byMCP_JWT_KEY.src/cimd-cache.ts+src/ssrf-guard.ts— client-ID metadata document fetch (HTTPS only, private ranges blocked, capped, cached).src/oauth-consent.ts— loopback consent on an ephemeral port, shared byauth --accountand the wizard.src/reauth-hint.ts— re-auth hint: the CLI command over stdio, a signed link over HTTP.src/hint-provider.ts— optional process-global remediation-hint provider (setHintProvider/hints()), keyed byHintCasefacts. A single-owner process never installs one, so every call site keeps its literal.src/boot-gates.ts/src/tenant-purge.ts— multi-tenant boot gates and token-purge primitives; the free core never installs or calls them.src/doctor.ts—runDiagnostics(): one engine, two skins (doctorCLI,diagnosetool); also theresetCLI.src/api-probe.ts— doctor's live per-service API-enablement probe.src/tools/account-wizard.ts— elicitation-drivenaccount_add/account_reauth/account_write_config(cud=read viaCUD_OVERRIDES, gated byanthropic/requiresUserInteraction); owner context only.src/client-config.ts— MCP-client detection + idempotent config entry (write-client-configCLI); never inlines secrets.src/setup-prompt.ts— thesetupMCP prompt (Google Cloud Console walkthrough).src/usage-metrics.ts/src/metrics-tap.ts/src/metrics-cli.ts— local usage metrics, off by default (GOOGLE_USAGE_METRICS,USAGE_METRICS_PATH); zero egress (import set allowlisted intests/usage-metrics.test.ts), no identity dimensions (it counts protocol revisions asprotoand clients as[email protected]asclients, nothing else about a caller);metricsCLI reads the local files. User doc:docs/usage-metrics.md.src/registry-transfer.ts—account export/account import: passphrase-encrypted bundle of config + still-encrypted token files (neverMASTER_KEYor the client secret); refuses a tenant-namespaced store.src/env-load.ts(.envloading, real env wins),src/net-tuning.ts(raises Node's happy-eyeballs connect timeout),src/open-url.ts(best-effort browser launch).- Public API: the
exportsmap inpackage.jsonis the supported surface for hosts that embed the core (MIGRATION-v6.mdlists each subpath);tests/exports-map.test.tspins it. A module a host needs must be declared there, and a deep import intodist/outside the map is unsupported.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago Changed · +2 lines · +544 tokens per session b55e24765c87
- 24d ago Changed · +15 lines · +1,562 tokens per session e4be61d66f29
- 1mo ago Changed · +13 tokens per session cbb48f39241b
- 1mo ago Changed · +1 lines · +103 tokens per session 675006babc70
- 1mo ago Changed · +2 lines · +127 tokens per session d8c20478506c
- 1mo ago Changed · +14 tokens per session 7f7d5c02142f
- 1mo ago Changed · +32 tokens per session 68e471818e0e
- 1mo ago Changed · +8 lines · +816 tokens per session 947a032787b3
- 2mo ago First seen · 112 lines · 2,948 tokens per session scan A b36d366afcc9
mcp-google-multi CLAUDE.md is an instructions file published in the GitHub repository bakissation/mcp-google-multi (21 stars, last pushed 2d ago), licensed MIT. It adds 6,159 tokens to every session, about $0.0246 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
mcp-google-multi CLAUDE.md compared with instructions from other repositories
| Mod | Type | Stars | Last push | Licence | Scan | Tokens | Works with |
|---|---|---|---|---|---|---|---|
| mcp-google-multi CLAUDE.mdbakissation/mcp-google-multi | Instructions file | 21 | 2d ago | MIT | A | 6,159 | Claude Code |
| vscode buildNext.instructions.mdmicrosoft/vscode | Instructions file | 195k | yesterday | MIT | A | 9,719 | GitHub Copilot |
| next.js AGENTS.mdvercel/next.js | Instructions file | 143k | yesterday | MIT | A | 7,461 | Codex, OpenCode |
| langchain AGENTS.mdlangchain-ai/langchain | Instructions file | 149k | yesterday | MIT | A | 4,680 | Codex, OpenCode |
| vscode oss-third-party-notices.instructions.mdmicrosoft/vscode | Instructions file | 195k | yesterday | MIT | A | 5,516 | GitHub Copilot |
| vscode copilot-instructions.mdmicrosoft/vscode | Instructions file | 195k | yesterday | MIT | A | 3,093 | GitHub Copilot |
| deepseek-harness AGENTS.mddeepseek-ai/deepseek-harness | Instructions file | 274k | 2d ago | MIT | A | 4,313 | Codex, OpenCode |