Scripting Claude Code can be the most cost effective way to build automations on AI today. I use this when I need a set unit of defined work done in a parallel way but I can't use programatic means. The best way to do this is by mimicking how Anthropic has designed this [for CI use cases](https://code.claude.com/docs/en/gitlab-ci-cd). ## Using Claude Code non-interactively The core flag to switch to non-interactive mode is `-p`. This flag means that the response should be printed to stdout and Claude should exit immediately after taking it's desired actions. ```shell claude -p "Instructions" ``` Now we get to add on the fun flags though to do a little bit more. ## Structured Output I swear by structured output for so many use cases, and it's really easy to get this output from the tool. ```shell curl https://simonwillison.net/guides/agentic-engineering-patterns/better-code/\#atom-everything | claude --print "I want to extract metadata about the site into structured json." --output-format=json --json-schema '{"type":"object","properties":{"title":{"type":"string"},"author":{"type":"string"},"publishedAt":{"type":"string"}},"required":["title","author","publishedAt"]}' | jq '.structured_output' ``` Which will return a result like the following: ```json { "title": "AI should help us produce better code", "author": "Simon Willison", "publishedAt": "2026-03-10" } ``` ## Tools & Permissions If you know a workflow is going to need a specific tool to work you can give permission ahead of time with `--allowedTools` and it's complement: - `--allowedTools, --allowed-tools <tools...>` - `--disallowedTools, --disallowed-tools <tools...>` This could be used if you have specific tools that need to be run in your workflow: ```shell claude -p "Initialize this folder as a new repo and write a basic template readme for it. You should commit this as an initial commit." --allowedTools "Bash(git init *)" "Edit(/README.md)" "Bash(git add *)" "Bash(git commit *)" ``` However, most often I just end up wanting to give the agent a general "permission mode". This is set with `--permission-mode`: ```shell claude --help | claude -p "Write a document called non-interactive-claude.md that exmplains how to use claude non-interactively." --permission-mode acceptEdits ``` | **Mode** | **File Edits** | **Bash Commands** | | ---------------------- | --------------------------------------- | --------------------------------------- | | plan | Blocked | Blocked | | dontAsk | Blocked (unless using `--allowedTools`) | Blocked (unless using `--allowedTools`) | | default | Prompts once per session | Prompts, can save approval | | acceptEdits | Auto-approved | Prompts, can save approval | | bypassPermissions/auto | Auto-approved | Auto-approved | ## Sessions I am a regular user of `--continue` or `-c` for short. It get's me back into an existing session and is super useful. There's also the `--resume <session-id>` option that is most useful in multi turn scripting or building UI on top of Claude Code. ```shell # Continue the most recent conversation claude -p "what did we just discuss?" --continue # Resume a specific session by ID claude -p "follow up on that" --resume <session-uuid> ``` `--resume` is most often used with `--output-format=json` since the output contains the session id that is needed to resume.