Configuring an extension
An extension that needs values from the person (their city, a site's address, a token) declares them as options, and the person gives them once. How an author declares them is in Writing one; this page is what happens to them.
The two sidesβ
- The author declares them in the extension's
plugin.json, underuserConfig, exactly as Claude Code does, and their servers take them as${user_config.KEY}in theirargsandenv. The same folder works in Claude Code, which asks for them itself and keeps them in its own settings. - The person gives the values, through the agent:
| Where | How |
|---|---|
| π¦ When it's installed | my-agent extension add weather@ada asks for each option without a value, on a terminal (a secret without echo). --set city=Madrid gives one without asking (a script). |
| β¨οΈ Later, from a shell | my-agent extension config weather shows them; extension config weather units=imperial sets one; extension config weather token asks for it, without echo when it's a secret; --unset <key> clears one. |
| π¬ In the chat | /extensions config weather shows them; /extensions config weather units=imperial sets them and restarts the extension's servers in the same conversation. Never a secret: what's typed in a chat is kept in its history. |
| π₯οΈ In a desktop or web agent | A settings form made from its options, each by its type (text, number, a choice, a checkbox), a secret as a password field that's never filled back. Captain Whiskers' drawer has it; a host of your own builds it from the chat controller's extensionOptions(name) and saves with setExtensionOptions(name, values), secrets included. |
$ my-agent extension config weather
city = Santa Cruz de Tenerife (Your city, required)
units = metric (default) (Units)
What the values doβ
- A required option without a value (nor a default) keeps the extension off, saying which and how to set it:
needs city (Your city) set: extension config weather city=<value>. - Values are checked by type: a number within its
minandmax, one of itsoptionswhen it has them,true/false(oryes/no) for a boolean, several comma-separated for amultipleone, an absolute path for adirectoryorfile. - Values reach the server as text: a boolean as
trueorfalse, a list comma-separated, one without a value as empty. - Reinstalling or updating keeps them; removing the extension deletes its secrets.
Where they're keptβ
Never in the prompt, the transcript or a tool's result:
- Non-sensitive values in the scope's lock entry (
options). In a workspace, that's the project's lock, so the people who share the project share them too (a team's Moodle sites, say). - Secrets (
sensitive: true) in the scope's private folder,.secrets/<name>.json: the agent's scope's own, or, for a workspace's extension, in the agent's folder, never in the project. No session's file tools reach it, even when the scope's folder is readable.
Changing them while a session runsβ
The kit's launcher reads the values when it starts a server, so a change reaches the server when it starts again:
- From the chat (
/extensions config, or a settings form), the extension's servers restart in the same session (reconnectMcpServer(): a new process with the values as they are now), and the model is told with the next message. A call running at that moment fails. - From another terminal (
extension config), the change applies when its server starts again: a new session, or/extensions disableandenablein the chat. - A session the agent builds itself gets
restartExtension(name)frombuildSessionOptions(), which returnsfalsewhen it can't be done in that session.
What isn't configurationβ
What the server learns or creates while it works (a signed-in browser session, a cache, sites added by asking it) isn't an option: the server keeps it in its data folder, which survives restarts, reinstalls and updates. And variables of the agent's own (${VAR} in a server's env, from the agent's environment) reach a server only when its .mcp.json names them.