cloudpin
This MCP server provides read-only insight into cloud CLI account pinning and can preflight shell commands against cloudpin’s project configuration.
Use
cloudpin_statusto inspect the active accounts for az, aws, gcloud, vercel, gh, kubectl, helm, supabase, and wrangler; see what the project’s.cloudpin.ymlpins, which environment applies, and which agent hooks are installed.Use
cloudpin_checkto evaluate a proposed command without running it, optionally specifyingcwdandshell(bashorpowershell), and get each cloud CLI call’s likely account, verdict (allow, block, or ask), reason, and fix.Both tools are read-only: they do not run commands, switch accounts, or change configuration.
Guards Cloudflare wrangler commands by resolving the active account ID from the project config, environment, credentials, and CLI flags, then comparing it with the pinned account. The MCP server reports the account in use and whether a command would be allowed.
Guards GitHub CLI (gh) commands by checking the active GitHub user and host against pinned values, accounting for hostname/token flags and environment variables. The MCP server reports the current account and whether a command would act on the pinned GitHub account.
Guards Google Cloud (gcloud) commands by checking the active account and project against pinned values, including flags and Cloud SDK environment/configuration. The MCP server reports the account/project in use and whether a command would be allowed.
Guards [helm](/mcp/servers/integrations/helm) commands by checking the Kubernetes API server/context and optional namespace against pinned values, honoring Helm-specific context, API server, namespace, and environment settings. It can report whether a Helm command would target the expected cluster.
Guards kubectl commands by comparing the target cluster API server and optional namespace with pinned values, accounting for kubeconfig, context, cluster, server, and namespace flags. Commands that never reach a cluster are not blocked; the MCP server reports command verdicts.
Guards Supabase CLI commands by checking the project ref and optional organization against pinned values, resolving CLI flags, environment variables, and saved link data. The MCP server reports the project in use and whether a command would be allowed.
Guards Vercel CLI commands by checking the active team ID against the pinned team, accounting for scope/team flags, tokens, and linked project metadata. The MCP server reports the active team and whether a deployment or other command would be allowed.
cloudpin
Pin cloud accounts to a project, and stop any command (yours or your AI agent's) that would run on the wrong one.
az, aws, gcloud, vercel, gh, kubectl, helm, supabase and wrangler act on whichever account, cluster or project you used last. With a work account, a
personal one and a client or two on the same machine, sooner or later something gets deployed to, or deleted
from, the wrong place. Coding agents make it more likely: they run these commands for you and never stop to ask
which account is active. cloudpin checks before the command runs.
Install
pnpm add --global cloudpinOn macOS and Linux, Homebrew works too, from paureis/homebrew-tap (it runs on Homebrew's own Node.js, installed if it isn't there yet):
brew install paureis/tap/cloudpinOn Windows, Scoop works too, from paureis/scoop-bucket.
It installs Scoop's own Node.js (nodejs-lts) if needed, and cloudpin always runs on that one. A global
install (scoop install -g) needs nodejs-lts installed globally too. nodejs-lts puts its folders at the front of
your user PATH, so in new shells node and npm are Scoop's (and npm install --global installs there), ahead of
any other Node.js on your user PATH; one on the system PATH, where the nodejs.org installer puts it, still comes
first. Uninstalling nodejs-lts breaks cloudpin until you run scoop install nodejs-lts again, and Scoop's
no_junction setting isn't supported.
scoop bucket add paureis https://github.com/paureis/scoop-bucket
scoop install paureis/cloudpinnpm install --global cloudpin
yarn global add cloudpin
bun add --global cloudpin
# try it without installing
npx cloudpin --helpRequires Node.js 22 or later. Works on Windows, macOS and Linux. The .cloudpin.yml format is stable from 1.0 on
(see Configuration), and feedback is very welcome.
Latest release: 1.2.1 (2026-10-29): agent hooks now find calls hidden by heredocs in $( ), run-time values,
PowerShell syntax and wrappers such as xargs, sudo, npx or cmd /c, and gcloud checks the impersonated
account; please upgrade. 1.2.0 (2026-10-29) was run it everywhere. A GitHub Action
(paureis/cloudpin-action) checks the accounts before a deploy job, built
on the new cloudpin check --only and --json; Homebrew and Scoop installs; the MCP server for every agent, listed in
the official MCP Registry (docs/mcp.md); Codex and Copilot CLI hooks that PowerShell's execution policy
can't stop on Windows; and fixes to which Vercel team and Wrangler account a command uses. See the
CHANGELOG. 1.1 added the Claude Code plugin, and 1.0 made the .cloudpin.yml format stable.
Related MCP server: @rarecloudio/mcp-server
Quick start
cd your-project
cloudpin init # pin the accounts you are logged into now
cloudpin install-hook claude # protect your AI agent (or codex, cursor, copilot, antigravity, gemini)
echo 'eval "$(cloudpin shell-init bash)"' >> ~/.bashrc # protect your terminalCommit .cloudpin.yml so everyone on the project gets the same protection. cloudpin status shows each CLI's
active account next to what is pinned. To see a block without risking anything, pin a wrong account in a scratch
folder (edit an ID in .cloudpin.yml) and run a read-only command such as gh repo list.
To undo it all: cloudpin uninstall-hook claude, remove the shell-init line from your profile, and delete
.cloudpin.yml. The only other things cloudpin writes are a short-lived identity cache in your user cache folder,
.git/cloudpin-env if you ran cloudpin use, and *.cloudpin-backup copies next to agent settings it edited.
Usage
# Write .cloudpin.yml from the accounts you are logged into now
cloudpin init
# ...or add them as one environment of the file (see Environments)
cloudpin init --env production --protected
# Show the environments, or choose the one to use in this clone
cloudpin use [<env> | --clear]
# Check every pinned account; exit 1 on a mismatch (handy in CI and scripts)
cloudpin check
# Check only these clouds; each must be pinned, installed and logged in to the pinned
# account, so a CLI missing on the runner fails, not skipped. --json prints an overall "result" (match,
# mismatch, unpinned or error) and each cloud's status, reason and fix. Exit codes stay the same.
cloudpin check --only azure,aws [--json]
# See each CLI's active account, what this folder pins, and which agent hooks are installed (--json for tools)
cloudpin status
# Why was a command blocked, or would it be? See the pin, the account it would use, and the verdict, without
# running it. One quoted argument is read as a full line; --agent shows what an agent hook decides; --json for tools.
cloudpin explain -- vercel deploy --prod
cloudpin explain "cd ../web && vercel deploy"
# Something looks off? Check the whole setup and get the fix for each problem; exit 1 if anything fails.
# --json shortens account IDs and hides your home folder, so it is safe to paste in a bug report.
cloudpin doctor [--json]
# Run one command only if it would act on the pinned account; exit 3 if blocked
cloudpin exec -- vercel deploy --prod
# Shell functions that route az, aws, gcloud, vercel, gh, kubectl, helm, supabase and wrangler through cloudpin
cloudpin shell-init bash|zsh|pwsh
# Add or remove the hook in an agent's settings (this project, or yours with --user)
cloudpin install-hook <agent> [--user]
cloudpin uninstall-hook <agent> [--user]How it works
A .cloudpin.yml in your project lists the accounts it uses. cloudpin init writes it for you, with readable
names as comments:
azure:
subscription: "3f2a0000-0000-0000-0000-000000000c91" # Acme Prod
tenant: "8b1d0000-0000-0000-0000-00000000044e"
aws:
account: "123456789012"
gcloud:
account: "deploy@acme.com"
project: "acme-prod"
vercel:
team: "team_x9KqZr" # acme
github:
user: "acme-bot"
kubernetes:
server: "https://acme-prod.hcp.westeurope.azmk8s.io:443" # acme-prod-admin
namespace: "payments"
supabase:
project: "abcdefghijklmnopqrst" # Acme prod
org: "acme"
cloudflare:
account: "0123456789abcdef0123456789abcdef" # AcmeBefore a guarded command runs, cloudpin works out which account that command would use (asking the CLI, or for Kubernetes reading the kubeconfig), honouring the command's own flags and environment, and compares the answer with the file:
CLI | What is pinned | What cloudpin takes into account |
| subscription ID, tenant ID |
|
| account ID |
|
| account, project |
|
| team ID |
|
| user, host |
|
| project ref, organisation (optional) |
|
| account ID |
|
| API server URL, namespace (optional) |
|
For Kubernetes the server URL is pinned rather than the context name, because context names are personal: the same
cluster is prod on one laptop and acme-prod-admin on another. init writes your context name as a comment, and
pins the namespace only if your context sets one. With a namespace pinned, -A / --all-namespaces is a mismatch.
Commands that never reach a cluster (kubectl config, kubectl kustomize, helm template, helm repo, ...) are
never blocked, and standalone kustomize isn't guarded at all. cloudpin can't see a namespace: written inside a
manifest you apply, so pin the namespace and keep manifests namespace-free if that matters to you.
For gcloud, an impersonated service account (the last one in a delegation chain) is the account compared with the pin; with an access token or token file the account can't be known, so an account pin gives "can't tell".
For Supabase the project ref is worked out the way the CLI does it, without a network call: --project-ref, then
SUPABASE_PROJECT_ID, then the project supabase link saved in supabase/.temp/. A linked branch counts as its
parent project. The organisation comes from supabase projects list. The local stack (start, stop, status,
functions serve, and db reset, db diff or migration up without --linked) is never blocked. A --db-url
pointing anywhere but your own machine is stopped, because cloudpin can't tell which project a URL belongs to.
For Cloudflare, cloudpin follows Wrangler's order: account_id in the config file Wrangler would find, then
CLOUDFLARE_ACCOUNT_ID, then the account Wrangler cached, then the only account the login sees
(wrangler whoami --json), with the auth profile the command uses (--profile or wrangler auth activate).
Variables Wrangler loads from the project's .env files count too. If it sees several and none is set, Wrangler
would ask or fail, so cloudpin stops the command, as for a profile it can't ask about. Local commands (dev, and
d1, kv key or r2 object without --remote) are never blocked; dev with remote: true bindings reaches your
account unchecked. Built to Wrangler's source and docs, not yet run against a real Cloudflare login; reports welcome.
Match: the command runs as if cloudpin wasn't there.
Mismatch: the command is stopped, and you're told which account is active and how to switch.
Can't tell (an expired login, a broken token, no network): the command is stopped too, and cloudpin says so plainly, with the CLI's own reason and the command that shows what's wrong.
Logging in, logging out, switching accounts, --help and --version are never blocked (where a CLI would still
run the command, as vercel deploy -v does, the command is checked). A folder without a
.cloudpin.yml is never affected. Monorepos work: the nearest .cloudpin.yml above the current folder wins.
Environments
One file can pin staging and production separately. Mark an environment protected and, even on the right
account, any command that could change something asks first:
environments:
staging:
vercel: { team: "team_staging" }
aws: { account: "111111111111" }
production:
protected: true
vercel: { team: "team_prod" }
aws: { account: "222222222222" }
branches: # optional: which environment a git branch uses
main: production
"release/*": production
"*": staging
read_only: # optional: more commands that never need confirmation
azure: ["webapp log tail"]Which environment applies, first match wins:
CLOUDPIN_ENV=<name>in the environment.cloudpin use <name>: remembered for this clone, inside.git, so it is never committed.The
branchesmapping for the checked-out branch, or forCLOUDPIN_BRANCH=<name>: an exact name first, then the first matching pattern.The first environment listed.
An unknown name is an error, so the command is stopped rather than checked against the wrong pins. cloudpin status and every message say which environment applies and why.
On a protected environment, read-only commands run as usual. Everything else asks:
In a terminal:
Continue? [y/N].Without a terminal (CI, scripts): the command stops unless
CLOUDPIN_CONFIRM=<name>is set.Claude Code, Copilot CLI, Antigravity and Cursor ask you through the agent's own prompt. Codex and Gemini CLI have no working "ask" in their hooks, so the command is blocked and the agent is told to hand it to you.
The built-in read-only list is short on purpose (az ... list|show, aws <service> describe-*|list-*|get-* and
s3 ls, gcloud ... list|describe, vercel ls|inspect|logs and <group> ls, gh <group> list|view|status,
kubectl get|describe|logs|top|explain, helm list|status|history|get), so
anything it doesn't know asks. read_only can add commands, matched by their leading words, but never remove
any. A wrong account is still blocked outright, protected or not.
Upgrading from the flat format: nothing to do; a file without environments keeps working exactly as before.
To split it, move the provider sections under environments: and a name, or start a fresh file with
cloudpin init --env <name> and run it again per environment (after switching accounts).
Protect your terminal
Add one line to your shell profile. Removing it uninstalls.
eval "$(cloudpin shell-init bash)" # ~/.bashrc
eval "$(cloudpin shell-init zsh)" # ~/.zshrccloudpin shell-init pwsh | Out-String | Invoke-Expression # $PROFILEIf cloudpin is ever uninstalled, the functions fall back to the real CLI, so they never get in your way. To run one
command anyway, on purpose: CLOUDPIN_SKIP=1 <command>.
Aliases. An alias that calls the CLI itself, such as alias kubectl='kubectl --context dev', is still guarded.
An alias that runs another program, such as alias kubectl=kubecolor or alias gh='command gh', bypasses cloudpin,
so each new shell prints a warning naming it (bash 4+, zsh and PowerShell; PowerShell runs any alias before the
wrapper). Put the cloudpin shell-init line after your aliases so it can see them.
Protect your AI agent
cloudpin install-hook claudeThe hook goes into the project's agent settings (--user for your personal settings). cloudpin shows the file before
writing it, keeps a backup, and uninstall-hook removes only its own entry. When a command is blocked, the agent is
told why and asked to check with you. Agents can't use CLOUDPIN_SKIP or CLOUDPIN_CONFIRM, can't pick an
environment by setting CLOUDPIN_ENV in their own command, and need your OK to run cloudpin use.
Agent | Settings file | Status |
Claude Code |
| Tested inside the agent |
Codex |
| Tested inside the agent |
Cursor |
| Tested inside the agent (Cursor CLI) |
GitHub Copilot CLI |
| Tested inside the agent |
Antigravity (CLI, IDE and 2.0) |
| Tested inside Antigravity CLI |
Gemini CLI |
| Built to the documented hook format |
Google replaced Gemini CLI with Antigravity CLI for free and consumer accounts on 2026-06-18; Gemini CLI still serves paid API keys and enterprise licenses, so both are supported.
cloudpin reads the whole command line the agent is about to run, so it also catches
cd ../other && npx vercel deploy, bash -c "...", pipelines, $( ), xargs, find -exec, heredocs fed to a shell
(bash <<EOF), commands held in a variable (CLI=vercel; $CLI deploy) and PowerShell assignments
($prs = gh pr list). Variables set earlier in the line count too (export AWS_PROFILE=other; aws ...,
$env:AWS_PROFILE = 'other'), and when one that decides the account is set from something only known when it runs
(GH_TOKEN=$(cat file) gh ...), the command is stopped with the reason. It can't see inside a script file the agent
writes and runs later (bash deploy.sh).
On Windows, Codex and Copilot CLI run hooks through PowerShell, whose Restricted and
AllSigned execution policies block npm's cloudpin.ps1. So for them, install-hook also writes a Windows command
starting cloudpin through cmd.exe, in a Windows-only field (Codex 0.131.0 or later). A hook from before 1.2.0
doesn't have it: re-run cloudpin install-hook <agent> after upgrading (Codex runs the changed hook once you review it in
/hooks). Gemini CLI has no such field, so its hook needs a policy that runs local scripts, such as RemoteSigned.
cloudpin doctor warns about each of these, about a . or other relative entry in PATH, and about Claude Code
older than 2.1.47.
Claude Code plugin
One install gives Claude Code the hook, two read-only tools it can call before acting, and a short skill telling it to check first and to stop and ask you when cloudpin blocks a command. cloudpin itself must be installed first:
npm install --global cloudpin
claude plugin install cloudpin --marketplace paureis/cloudpinThe plugin replaces cloudpin install-hook claude: with the plugin enabled, install-hook claude declines, and
cloudpin doctor warns if both are present (Claude Code would run both).
MCP server
cloudpin mcp is an MCP server (stdio) for any agent; the Claude Code plugin starts it for you. Its three tools,
cloudpin_status, cloudpin_check and cloudpin_doctor, report the accounts in use, if a command would be allowed,
and why cloudpin may not be guarding. None runs, switches or changes anything: an agent that could switch accounts
could switch to the wrong one.
docs/mcp.md adds it to Codex, Cursor, VS Code and more. It gives advice, not enforcement: where the
agent has a hook, install that too.
Configuration
Variable | Effect |
| Run one command without the check (terminal only; ignored for agents) |
| Use this environment (see Environments) |
| Use this branch for the branches mapping, as in CI; ignored for agents |
| Confirm changing commands on this protected environment without a prompt (terminal and CI only; ignored for agents) |
| Always ask the CLI instead of using the identity cache |
| Where the identity cache (and the time of the last update check) lives |
| Never ask npm whether a newer cloudpin exists ( |
Asking a CLI who it is takes 0.5 to 2 seconds, so cloudpin remembers a successful answer for up to five minutes.
The cache is dropped the moment anything that decides the account changes: the command's flags, the relevant
environment variables, or the CLI's own account files (which az account set, gh auth switch and
vercel switch rewrite). cloudpin check always asks the CLI.
From 1.0 on, .cloudpin.yml only grows: a new version may add sections and keys, never change or remove them. A
file that uses a name your cloudpin doesn't know is refused rather than half read, so a typo such as azrue: can't
switch protection off. The message names your version and says to update in case the file was written for a newer one.
Exit code | Meaning |
| OK |
| Usage error, or |
| Command blocked, or not confirmed on a protected environment |
Security and privacy
cloudpin only reads which account is active, using each CLI's own identity command (az account show,
aws sts get-caller-identity, gcloud config list, vercel teams ls, gh api user). It never logs in or
switches accounts, never reads a credential file other than the kubeconfig (taking only the server and namespace from
it) and the .env files Wrangler loads (taking the account variables), and never prints or stores a token: error messages name a variable
such as GH_TOKEN but never its value, and the cache stores salted hashes of anything sensitive. It runs CLIs
directly, never through a shell. cloudpin has no telemetry and sends nothing about you or your accounts; the
identity commands above talk only to their own provider, as they would if you ran them. Its one request of its own
asks registry.npmjs.org for the latest cloudpin version, at most once a day and only when you run a cloudpin command
in a terminal (never from the shell wrappers, exec or the agent hooks), to tell you when an update is out. Turn it
off with CLOUDPIN_NO_UPDATE_CHECK=1 or NO_UPDATE_NOTIFIER=1; it is off in CI. See SECURITY.md to report a
problem.
Does it slow my commands down? Outside a pinned project, by the time it takes Node to start (about 0.1 s). Inside one, the first check costs one identity call, and later checks come from the cache.
What if a CLI isn't installed? A pinned CLI that isn't installed is skipped; the command would fail anyway.
cloudpin check --only is the exception: it requires every cloud listed.
Can I use it in CI? Yes. On GitHub Actions, add paureis/cloudpin-action@v1
after the job's cloud logins. Elsewhere, run cloudpin check before deploying; it exits 1 if any pinned account doesn't match.
Hosted runners have many cloud CLIs preinstalled, so name the clouds the job deploys to with
cloudpin check --only azure,aws: each must then be installed and logged in to the pinned account. On a pull
request or tag there is no branch; set CLOUDPIN_BRANCH, e.g. to GITHUB_HEAD_REF,
so branches picks the right environment.
Why block when it can't tell? Because "probably the right account" is the situation cloudpin exists to prevent. The message tells you exactly why it couldn't tell.
Roadmap
Ideas and what's next are in ROADMAP.md. Suggestions are welcome in issues.
Development
git clone https://github.com/paureis/cloudpin.git
cd cloudpin
npm ci
npm run build
npm testCommand | Description |
| Compile to |
| Run the test suite |
| Type-check without emitting |
| Check providers against the CLIs logged in on your machine (after a build) |
| Regenerate |
The design decisions, and why they were made, are in DESIGN.md. See CONTRIBUTING.md before opening a pull request.
About
Made by Alvaro Reis (LinkedIn), with Claude Code as a pair programmer. Every behaviour is covered by tests, and every CLI integration is checked against the tool's own documentation and the real CLI. Why it exists: 5 ways your cloud CLI picks the wrong account without telling you.
Available Tools
2 toolscloudpin_checkARead-only
Would cloudpin allow this shell command, as an agent's? Returns each cloud CLI call in it, the account it would use and why, and the verdict (allow, block or ask) with the reason and the fix. Nothing is run.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Folder the command would run in; defaults to the current one. | |
| shell | No | The shell that would run it: powershell for a PowerShell tool's command; defaults to bash. | |
| command | Yes | The full command line, e.g. "cd web && vercel deploy --prod". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds important behavioral context beyond the readOnlyHint annotation by stating 'Nothing is run' and describing the returned verdict, reasons, and fixes. It does not cover auth or rate limits, but for a read-only preflight check that is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three compact sentences with no filler, front-loading the core question and then covering return shape and safety. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although there is no output schema, the description explains what is returned: each cloud CLI call, the account used, the reason, the verdict, and the fix. Combined with complete parameter schema coverage and the readOnlyHint annotation, an agent has enough context to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters are already documented in the schema. The description references the shell command generally but does not add meaning about cwd or shell beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation: check whether cloudpin would allow a given shell command, including per-CLI-call account and verdict details. It is clear what the tool does, but it does not explicitly differentiate itself from the sibling cloudpin_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the question form and the mention of shell commands, but there is no explicit statement of when to use this tool versus alternatives or when not to use it. The sibling cloudpin_status is not mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cloudpin_statusARead-only
Which cloud accounts each CLI (az, aws, gcloud, vercel, gh, kubectl, helm, supabase, wrangler) is using here, what this project's .cloudpin.yml pins, which environment applies, and which agent hooks are installed. Call it before cloud work.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Project folder; defaults to the current one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes this is a safe inspection, so the description's main job is to add context. It enumerates what gets surfaced (accounts, pins, environment, hooks), which is useful, but says nothing about whether it shells out to CLIs, how slow it is, or how it handles a missing .cloudpin.yml.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is two sentences with no padding, and the core capability is front-loaded. The parenthetical CLI list is long but earns its place by telling the agent exactly which tools are covered.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining results, and it does so by naming the four categories of information returned. Only the exact shape of the response (per-CLI mapping vs. list, file path vs. parsed pins) is left unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the cwd parameter is already fully documented as "Project folder; defaults to the current one." The description adds nothing about cwd and does not need to, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (cloud accounts per CLI, .cloudpin.yml pins, environment, agent hooks) and scope ("here", "this project"). It is clear what the tool reports, but it never names or contrasts with the sibling cloudpin_check, so an agent must infer the difference from the names alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit usage trigger: "Call it before cloud work." That is real guidance, but there are no exclusions and no mention of when to prefer cloudpin_check, leaving the sibling choice unresolved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.2.1- Changed
cloudpin_check1 field changed- added
Input schema / properties / shellAdded value: +{ + "description": "The shell that would run it: powershell for a PowerShell tool's command; defaults to bash.", + "enum": [ + "bash", + "powershell" + ], + "type": "string" +}
2 tool updates
v1.1.2- First observed
cloudpin_check - First observed
cloudpin_status
TDQS
Scored across 2 tools
cloudpin_check evaluates a specific shell command for policy compliance, while cloudpin_status reports account/environment/hook context. The split is clear, though both revolve around the same cloudpin configuration and an agent could briefly wonder which to call first for `gh` or `kubectl` operations.
Both tools use a consistent `cloudpin_` prefix with a short snake_case verb/noun suffix (check, status). Predictable and uniform.
Two tools is thin for a server, even a focused policy-guard one. A read-only status plus a dry-run check does not leave much surface area, and there is no tool for inspecting or validating the pinning configuration itself.
The guard/preflight lifecycle is covered (status → check), but notable gaps remain: no way to list or explain the effective policy rules, validate `.cloudpin.yml`, or enumerate blocked/allowed command patterns without supplying a command. Agents will hit dead ends when they want to understand the policy rather than test one command.
Maintenance
Related MCP Connectors
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
The Cortex MCP server provides read-only access to real-time engineering context from the Cortex developer portal, allowing AI coding assistants to answer natural language questions about your organization's catalog (microservices, libraries, domains, teams, infrastructure), scorecards (engineering standards and best practices), initiatives (goals and deadlines), and Engineering Intelligence metrics. It includes tools for querying documentation, tracking personal entities, and accessing AI-assisted insights across the entire Cortex ecosystem.
Hosted X (Twitter) MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server for AI coding agents to inspect repositories, audit code quality, route engineering skills, and plan safe issue/PR workflows.1MIT
- AlicenseAqualityBmaintenanceRead-only MCP server for the RareCloud API, enabling AI agents to list servers, browse the catalog, check billing, and plan deployments.10025 npmMIT
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server for inspecting and diagnosing HCP Terraform workspaces, runs, and plan summaries from ChatGPT and other MCP clients. It provides tools to list workspaces, inspect runs, and summarize plans without exposing sensitive data.MIT
- FlicenseNot gradedqualityDmaintenanceA read-only MCP server for GitHub that exposes 7 tools (list repos, commits, branches, pull requests, issues, file contents, search) via a Cloudflare Worker, using a single password for authorization and a fine-grained GitHub token for access control.-