Follow Discord
Sweep 27 Oct 2026 · 19:04Z Build v2.1.312 531 read Stable v2.1.308 Latest v2.1.312 Next v2.1.312 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Use the mods API changedplugins/mods/api

Upstream edited this page at 25 Oct 2026 14:35 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 25 Oct 2026 14:37 UTC.

Upstream edited
Recorded here
Lines+51added
Lines−5removed
From line 309 where the diff opens
First seen 1 Oct 2026 this site's first read of the page
Recorded edits15to this page, all time

### Calls refused in `claude -p` runs and Agent SDK sessions ### A `claude -p` run with your mod never exits ### Read all settings, one source, or one key

The whole hunk

from line 309, old and new numbered
/
lines
from line 309
309309 
310310#### What refused calls return
311311 
312In the results, `<reason>` stands for `the session was stopped and nobody has sent input since`:
312In the results, `<reason>` stands for the reason the call was refused. After an interruption, that's `the session was stopped and nobody has sent input since`. For other reasons, see [Calls refused in `claude -p` runs and Agent SDK sessions](#calls-refused-in-non-interactive-runs).
313313 
314| Some refused calls | Result until the user's next input |
314| Some refused calls | Result |
315315| :- | :- |
316316| `$.prompt.submit` | Resolves with `{ drop: '<reason>' }` and queues no prompt |
317317| `$.command.run` | Rejects with an error whose message ends with `<reason>` |
from line 320
320320| `$.session.send` to an [agent team](https://code.claude.com/docs/en/agent-teams.md) teammate | Resolves with `{ isDelivered: false, reason: 'Teammate "<name>" was not messaged: <reason>.' }`, where `<name>` is the teammate's name |
321321| [`$.tool.call`](https://code.claude.com/docs/en/plugins/mods/reference#mods-api-methods) of Bash with `run_in_background: true`, Monitor, or CronCreate | Resolves with `{ deny: '<tool> was not run: it starts background work, a schedule or a goal, and <reason>' }`, where `<tool>` is the tool's name |
322322 
323Along with these `$.session.send` and `$.tool.call` results, the user can see the [`Stopped:` toast](https://code.claude.com/docs/en/plugins/mods/troubleshoot#stopped-type-a-message-to-continue).
323When one of these `$.session.send` or `$.tool.call` calls is refused after an interruption in an interactive session, the user can see the [`Stopped:` toast](https://code.claude.com/docs/en/plugins/mods/troubleshoot#stopped-type-a-message-to-continue).
324324 
325325#### Work your mod started before the interruption
326326 
from line 337
337337 
338338When a scheduled job comes due or a monitor raises an event before the user's next input, the user can see the [`Stopped:` toast](https://code.claude.com/docs/en/plugins/mods/troubleshoot#stopped-type-a-message-to-continue).
339339 
340### Calls refused in `claude -p` runs and Agent SDK sessions
341 
342In a `claude -p` run or an [Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview.md) session, a result such as `{ drop: 'the run reached its --max-turns limit' }` means the run refused your mod's call.
343 
344A refused `$.prompt.submit` resolves with `{ drop: '<reason>' }`. Other refused calls, such as `$.command.run` and `$.agent.spawn`, give the results shown in [What refused calls return](#what-refused-calls-return) with the reason in place of `<reason>`. Find your `<reason>` below for what to do about it:
345 
346* **`the run reached its --max-turns limit`**: turns from your mod's prompts and from subagents it spawns count toward [`--max-turns`](https://code.claude.com/docs/en/cli-reference#cli-flags) or the Agent SDK's [turn limit](https://code.claude.com/docs/en/agent-sdk/configuration.md#limit-turns-and-spend). For more turns, start the run with a higher limit. If you can't, have your mod stop making the refused call. If the run takes another prompt from the user or the SDK application, the turn count resets and the run accepts calls again.
347* **`the run is past its --max-budget-usd limit`**: start the run with a higher `--max-budget-usd`, or raise the Agent SDK's [spend limit](https://code.claude.com/docs/en/agent-sdk/configuration.md#limit-turns-and-spend). If you can't, have your mod stop making the refused call. The limit applies to the run's total cost so far. That total keeps adding up when the run takes another prompt, so a retry returns the same reason.
348* **`the host has ended its input`**: for example, the SDK application ended its [streaming input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md), or stdin closed on a run started with [`--input-format stream-json`](https://code.claude.com/docs/en/cli-reference#cli-flags). The run is ending and takes no more input, so a retry returns the same reason. Have your mod stop making the refused call. If you start the run yourself, next time keep that input open until your mod has no more calls to make.
349* **`the session was stopped and nobody has sent input since`**: the run was [interrupted](#calls-and-background-work-after-the-user-interrupts-a-turn), for example with the Agent SDK's [`interrupt()`](https://code.claude.com/docs/en/agent-sdk/typescript#query-object). To make the call again after the next message from the user or the SDK application, follow [Retry a refused or dropped call](#retry-a-refused-or-dropped-call).
350 
351### A `claude -p` run with your mod never exits
352 
353If your mod submits a prompt at the end of every turn, each prompt starts another turn. Without [`--max-turns`](https://code.claude.com/docs/en/cli-reference#cli-flags) or `--max-budget-usd`, a `claude -p` run that loads the mod goes on until you stop it yourself.
354 
355To make the run end on its own, add either flag to the command in your shell. If other people start the run, have your mod stop submitting prompts once its work is done. This command adds `--max-turns`:
356 
357```bash theme={null}
358claude -p "find the TODOs" --max-turns 5
359```
360 
361Once the run reaches that limit, the mod's next prompt is [refused](#calls-refused-in-non-interactive-runs) instead of starting a turn, and the run ends.
362 
363If the run still goes past the limit, run `claude --version` in your shell, and [update Claude Code](https://code.claude.com/docs/en/setup.md#update-claude-code) if yours is earlier than v2.1.304. The mod's prompts are refused at the limit from v2.1.299. If your mod spawns subagents, their turns count toward `--max-turns` from v2.1.304.
364 
340365## Send and receive messages between sessions
341366 
342367A mod can send a plain-text message to another of your sessions, to one of this session's subagents, or to a teammate in its [agent team](https://code.claude.com/docs/en/agent-teams.md). It can also observe the messages that arrive and leave.
from line 411
386411| `$.http` | `fetch(url, init)` over `http` or `https`. It resolves to `{ status, ok, headers, text }` once the body is read. |
387412| `$.store` | A JSON key-value store of your plugin's own, kept between sessions |
388413| `$.env` | `get` and `set` environment variables. Write the name as a string literal. |
389| `$.settings` | `read` what the settings files and managed policy hold |
414| `$.settings` | `read()` resolves to all settings, merged into one object. With `{ source }` or `{ key }`, it resolves to [one source's settings or one key's value](#read-one-source-or-one-key) instead. |
390415| `$.session` | `messages()` returns the transcript as a list of `{ role, text, toolUses }`. Also the working directory, model, and more. [`usage()`](https://code.claude.com/docs/en/plugins/mods/reference#mods-api-methods) returns context window use and plan limits. |
391416| `$.mcp` | `call` a tool on a connected MCP server |
392417 
from line 428
403428 
404429* **`$.process.spawn started, and a plugin withheld its result:`**: the refusing mod hadn't read the command's output to the end. Claude Code stops the command if it's still running.
405430* **`$.process.spawn ran, and a plugin withheld its result:`**: the refusing mod had read the command's output to the end, so the command had exited
431 
432### Read all settings, one source, or one key
433 
434`$.settings.read()` resolves to one object that holds the settings from all sources in use, merged by [precedence](https://code.claude.com/docs/en/settings.md#settings-precedence). Pass `{ source }` to read one source instead, `{ key }` to read one key, or both:
435 
436| Call | Resolves to |
437| :- | :- |
438| `$.settings.read()` | The merged settings as one object. Its top-level keys are those of a `settings.json` file, such as `permissions` and `hooks`. |
439| `$.settings.read({ source: 'policy' })` | That one source's settings as one object, or `{}` when that source holds no settings |
440| `$.settings.read({ key: 'spinnerTipsEnabled' })` | That key's value in the merged settings, or `undefined` when the key isn't set |
441| `$.settings.read({ key: 'spinnerTipsEnabled', source: 'user' })` | That key's value in that one source, or `undefined` when that source doesn't set it |
442 
443For `source`, pass the name of the one settings source to read:
444 
445* **`user`**: `~/.claude/settings.json`
446* **`project`**: `.claude/settings.json`
447* **`local`**: `.claude/settings.local.json`
448* **`flag`**: what you pass with `--settings`, and the SDK's inline settings
449* **`policy`**: [managed settings](https://code.claude.com/docs/en/managed-settings.md#how-claude-code-combines-managed-sources)
450 
451For `key`, pass the exact name of one top-level key, not a dotted path into a nested object. The `key` argument requires Claude Code v2.1.304 or later.
406452 
407453## Next steps
408454 
Feedback