What Your AI Coding Agent Can Do Without Asking
Seven settings in Claude Code, Codex, VS Code, Gemini CLI and MCP configs let an AI agent act without asking you. The safer value, and a 10-second check.
Most AI coding agents ask before they run a command, edit a file or call a tool. A few settings turn that question off. Each one is a single line in a config file. It is easy to set once, for one task, and forget, and nothing reminds you it is still there.
This guide covers seven of them. For each one you get what it does, why it is risky, the safer setting, and a way to check your own machine by hand in about ten seconds. The commands are for macOS and Linux. On Windows, open the same files in your editor and search for the same words.
1. Claude Code: defaultMode set to bypassPermissions
What it does. permissions.defaultMode decides how each Claude Code session starts. Set to "bypassPermissions", Claude Code skips its permission prompts. Shell commands, file edits and web requests all run without asking you.
Why it is risky. Nothing stands between a command the agent writes and your machine. The agent reads files, issues and web pages as it works. An instruction hidden in any of them can become a command that runs straight away.
The safer setting. Remove the line, or set it to "default", which asks the first time each tool is used. To make sure the mode cannot be switched on by accident, you can also set permissions.disableBypassPermissionsMode to "disable".
// Risky
{ "permissions": { "defaultMode": "bypassPermissions" } }
// Safer
{ "permissions": { "defaultMode": "default" } }Check it in 10 seconds. No output means the mode is not set in these files:
grep -sn bypassPermissions ~/.claude/settings.json .claude/settings.json .claude/settings.local.jsonRecent versions of Claude Code only honor this mode from your user file, ~/.claude/settings.json, or from settings your organization manages. Older versions also honored it from a project's files, so check all three. If you are not sure which version you run, check your version's docs.
2. Claude Code: allow rules for any shell command, or for git push
What it does. The permissions.allow list names what Claude Code may do without asking. "Bash" and "Bash(*)" both allow every shell command. A narrower rule such as "Bash(git push *)" allows one command, every time, with no prompt.
Why it is risky. A rule for every command means the shell never asks. A rule for git push lets the agent publish code to a shared branch before you have read it. The same goes for other commands whose effect leaves your machine or cannot be undone, such as npm publish, terraform apply, kubectl delete or rm -rf.
The safer setting. Allow only the commands you run all day and would never think twice about, such as your tests and linter. Put commands that push, publish, deploy or delete in the ask list, so Claude Code asks you first. An ask or deny rule for a command takes priority over an allow rule for it.
// Risky
"allow": ["Bash"]
"allow": ["Bash(*)", "Bash(git push *)"]
// Safer
"allow": ["Bash(npm run test *)", "Bash(npm run lint)"],
"ask": ["Bash(git push *)"]Check it in 10 seconds. Type /permissions in Claude Code. It lists every rule and the file it comes from. Or search the files directly:
grep -sn '"Bash' ~/.claude/settings.json .claude/settings.json .claude/settings.local.jsonLook for "Bash", "Bash(*)", or a push, publish, deploy or delete command under allow. Rules can appear without you editing anything: choosing "Yes, and don't ask again" on a prompt saves one to .claude/settings.local.json.
3. Codex: approval_policy "never" with a full-access sandbox
What it does. Two keys in ~/.codex/config.toml decide how much Codex does on its own. approval_policy decides when it asks you, and "never" means it never does. sandbox_mode decides what its commands can reach, and "danger-full-access" turns the sandbox off, so commands can reach every file your account can, and the network.
Why it is risky. Each one removes a safeguard. Together they let Codex run any command, anywhere on your machine, with no prompt. "never" is meant for runs where no person is there to answer, such as a script. On your own machine it means nobody is asked.
The safer setting. Have Codex ask when it wants to go beyond what the sandbox allows, and keep its commands inside the project.
# Risky
approval_policy = "never"
sandbox_mode = "danger-full-access"
# Safer
approval_policy = "on-request"
sandbox_mode = "workspace-write"The accepted values have changed between Codex versions, so check your version's docs before you pick a different one.
Check it in 10 seconds.
grep -nE 'approval_policy|sandbox_mode|profile' ~/.codex/config.tomlIf a profile line shows up, the active profile can set these keys again and override the top of the file. Where profiles are kept depends on your version, so check your version's docs and look there too.
4. VS Code agent mode: chat.tools.autoApprove
What it does. In VS Code's agent mode, chat.tools.global.autoApprove approves every tool call for you. Older versions call it chat.tools.autoApprove. VS Code's own description says it disables critical security protections. A related setting, chat.tools.terminal.autoApprove, approves the terminal commands that match its rules, and a catch-all rule such as "/.*/": true approves all of them.
Why it is risky. The agent can run terminal commands and use tools with no confirmation, including commands it picked up from content it read.
The safer setting. Turn it off and approve tools as they are used. If the prompts get tiring, approve a few specific, harmless commands in chat.tools.terminal.autoApprove instead of all of them.
// Risky
"chat.tools.global.autoApprove": true,
"chat.tools.terminal.autoApprove": { "/.*/": true }
// Safer
"chat.tools.global.autoApprove": false,
"chat.tools.terminal.autoApprove": { "/^npm test$/": true }Check it in 10 seconds. Open the Command Palette, run Preferences: Open User Settings (JSON), and search for autoApprove. Then check the project's own settings:
grep -n autoApprove .vscode/settings.jsonIf your setup differs, the user settings file is ~/Library/Application Support/Code/User/settings.json on macOS, ~/.config/Code/User/settings.json on Linux, and %APPDATA%\Code\User\settings.json on Windows.
5. Gemini CLI: MCP servers marked trust: true
What it does. Gemini CLI reads MCP servers from the mcpServers block of its settings.json. A server with "trust": true skips every confirmation for that server's tools.
Why it is risky. You approve the server once, when you add it. After that, every tool it offers runs without a prompt. That includes tools added in a later release of the server, and tools whose description tells the agent to do something you did not ask for.
The safer setting. Remove trust, or set it to false, so each tool call asks first.
// Risky
"mcpServers": {
"github": { "command": "...", "trust": true }
}
// Safer
"mcpServers": {
"github": { "command": "..." }
}Check it in 10 seconds. The first file applies to every project. The second applies only to the project you are in.
grep -sn '"trust"' ~/.gemini/settings.json .gemini/settings.json6. MCP servers that run unpinned code
What it does. Most MCP servers start from a command in your MCP config. npx some-server@latest, npx some-server with no version, uvx some-server with no version, and a Docker image tagged :latest or with no tag all fetch whatever was published most recently.
Why it is risky. The code your agent runs can change without you doing anything. If a package or image is taken over, or a new release changes what a tool does, the next start runs the new code with the same access you gave the old one.
The safer setting. Pin an exact version, so the server only changes when you change it. For images, pin a version tag or, better, a sha256 digest. The versions below are placeholders: use the one you have reviewed.
// Risky
"args": ["-y", "@modelcontextprotocol/server-filesystem@latest", "."]
"command": "uvx", "args": ["mcp-server-git"]
"args": ["run", "-i", "--rm", "ghcr.io/example/mcp-server:latest"]
// Safer
"args": ["-y", "@modelcontextprotocol/server-filesystem@1.2.3", "."]
"command": "uvx", "args": ["mcp-server-git==1.2.3"]
"args": ["run", "-i", "--rm", "ghcr.io/example/mcp-server@sha256:<digest>"]Check it in 10 seconds. Search the MCP configs your editors use. This covers the common ones:
grep -snE '@latest|:latest|"npx"|"uvx"|"docker"' .mcp.json .vscode/mcp.json .cursor/mcp.json ~/.cursor/mcp.json ~/.claude.json ~/.gemini/settings.json ~/.codex/config.tomlFor each npx or uvx line, look for an exact version after the package name. For each image, look for a tag other than latest, or a digest.
7. Tokens written in plain text in MCP config
What it does. Many MCP servers need a token for the service they talk to. The quickest way to give them one is to paste it into the server's env block.
Why it is risky. Anything that can read the file can read the token: other extensions, other agents, backups, and git if the file is ever committed. An agent asked to look at your setup can read it too.
The safer setting. Keep the token out of the file. Reference an environment variable, or use your editor's secret prompt, which asks once and stores the value outside the file. Then rotate the token, because the old one has already sat on disk in plain text.
// Risky
"env": { "GITHUB_TOKEN": "ghp_your_real_token" }
// Safer: read it from an environment variable
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }The reference syntax depends on the tool. ${GITHUB_TOKEN} works in Claude Code's .mcp.json and in Gemini CLI's settings. In VS Code's mcp.json, an inputs entry with "password": true and a ${input:...} reference asks you for the value instead. Check your editor's docs for the exact form.
Check it in 10 seconds.
grep -sniE 'token|key|secret|password' .mcp.json .vscode/mcp.json .cursor/mcp.json ~/.cursor/mcp.json ~/.gemini/settings.jsonA value that starts with $ or ${ is a reference. A long string of letters and numbers is probably the real thing.
Related: the eight checks to run before any MCP server joins your workspace: https://deepsweep.ai/blog/mcp-server-security-checklist