Quickstart
We'll build a plugin that logs every tool call the agent makes and pins the model to a low temperature. Three steps: write the file, register it, restart.
1. Write the module
Put the file somewhere stable and outside any project — a plugin registered by absolute path keeps working no matter which directory the server starts in.
import { appendFileSync } from "node:fs"
export default {
id: "tool-log",
server({ cwd, version }, { config }) {
const logFile = config?.file ?? "/tmp/podcode-tools.log"
console.log(`[tool-log] started — runtime ${version}, cwd ${cwd}`)
return {
// Every model call in every session.
"chat.params": (params) => ({
...params,
temperature: config?.temperature ?? 0.2,
}),
// Every tool call, before it runs.
"tool.execute.before": (input) => {
appendFileSync(logFile, `${input.toolID} ${JSON.stringify(input.args)}\n`)
return undefined // no change
},
}
},
}Two things are doing real work here:
idis the config key.plugin_config["tool-log"]is what arrives asconfig— not the filename, not a package name.- Returning
undefinedmeans "no change." Thetool.execute.beforehook above only observes, so it hands nothing back and the arguments pass through untouched.
2. Register it
Plugins are registered in the global config, never in a project's .podcode/config.json.
{
"plugin": ["/Users/you/.config/podcode/plugins/tool-log.mjs"],
"plugin_config": {
"tool-log": {
"file": "/Users/you/podcode-tools.log",
"temperature": 0.1
}
}
}The plugin_config block is optional. Without it, config arrives as undefined — which is why the example reads it with ?. and falls back to a default.
You can do the same thing from the app: Settings → Plugins → Add Plugin. That form takes an npm package name and writes the same two keys for you, then restarts the server automatically.
3. Restart
Plugins load exactly once, at server boot. After editing the config or the plugin file:
podcodeRestarting from Settings → Plugins does this for you; the server is unavailable for a few seconds while it comes back up.
4. Verify
Start a session and ask the agent to read a file. Then check your log:
tail -f /Users/you/podcode-tools.logYou should see a line per tool call — read {"filePath":"..."} and so on.
If the file stays empty, the plugin probably never loaded. The server log says so plainly; Troubleshooting covers the four warnings you'll actually hit and what each one means.
Next
- Plugin anatomy — what's in
server()'s arguments and what you may return. - Custom tools — go past observation and give the agent a new capability.