There is no separate pip install nerva package today.
The supported Python integration model is:
Python orchestrates from the outside, Nerva runs as the local agent runtime.
Use the nerva CLI from Python through subprocess, read text or JSON output,
and control state with CLI flags.
git clone https://github.com/hannes-wan/nerva.git
cd nerva
cargo install --path .Confirm it is available:
nerva --helpimport subprocess
result = subprocess.run(
["nerva", "--no-session", "--print", "summarize this repository"],
text=True,
capture_output=True,
check=True,
)
print(result.stdout)import json
import subprocess
result = subprocess.run(
["nerva", "--no-session", "--mode", "json", "summarize this repository"],
text=True,
capture_output=True,
check=True,
)
payload = json.loads(result.stdout)
print(payload["response"])JSON output shape:
{
"provider": "openai",
"model": "<model>",
"sessionId": "<session-id>",
"message": "<user-message>",
"thinking": null,
"response": "<assistant-response>"
}import subprocess
prompt = "Review this release checklist and list the blockers."
result = subprocess.run(
["nerva", "--no-session", "--print"],
input=prompt,
text=True,
capture_output=True,
check=True,
)
print(result.stdout)Non-interactive mode requires either a message argument or non-empty stdin.
import subprocess
result = subprocess.run(
[
"nerva",
"--no-session",
"--mode",
"json",
"review these files",
"@Cargo.toml",
"@src/main.rs",
],
text=True,
capture_output=True,
check=True,
)
print(result.stdout)For automation, isolate user-level Nerva state:
import os
import subprocess
from pathlib import Path
agent_home = Path(".automation/nerva-home").resolve()
agent_home.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["NERVA_AGENT_DIR"] = str(agent_home)
result = subprocess.run(
["nerva", "--mode", "json", "--no-session", "summarize the current repo"],
text=True,
capture_output=True,
check=True,
env=env,
)
print(result.stdout)Project-local state still lives under the current workspace's ./.nerva/.
Continue latest session:
subprocess.run(
["nerva", "--continue", "--print", "continue from the last state"],
text=True,
check=True,
)Use an explicit session directory:
subprocess.run(
[
"nerva",
"--session-dir",
".automation/nerva-sessions",
"--mode",
"json",
"run the release check",
],
text=True,
check=True,
)Use --no-session for deterministic one-shot jobs where transcript persistence
is unwanted.
--trigger-json accepts a JSON string. If the JSON has message or prompt,
that value becomes the message. Otherwise, Nerva wraps the JSON in an
<external_trigger> block for the model.
import json
import subprocess
event = {
"source": "ci",
"prompt": "review the failing test output",
"runId": "12345"
}
result = subprocess.run(
["nerva", "--no-session", "--mode", "json", "--trigger-json", json.dumps(event)],
text=True,
capture_output=True,
check=True,
)
print(result.stdout)- use
--mode jsonwhen another program needs to parse the answer - use
--no-sessionfor stateless calls - use
--session-dirwhen automation needs isolated persistent sessions - set
NERVA_AGENT_DIRfor isolated user-level settings and auth - pass files with
@fileinstead of concatenating large prompts yourself - prefer project-local
.nerva/settings.jsonfor provider defaults in a repo
Today, Python integration is process-based. There is no in-process Python SDK, no Python host API, and no streaming callback API.
For richer integration, write a Nerva extension. Extensions are also process-based, but they can register model-visible tools, slash commands, and event hooks.