Run it on a schedule
A report every Monday from GitHub Actions, cron or Hermes, with no terminal open. Examples for systemd and launchd are in the docs.
Set up scheduled runsInstall for
For CLI
Run in any terminal.
In your terminal: npm i -g github:noro-to/noro Or run it once without installing: npx @noro-to/noro this report.csv
For Claude plugin
In the Claude Code chat, add the marketplace, then install the plugin.
In your agent chat: /plugin marketplace add noro-to/noro In your agent chat: /plugin install noro@noro Update it later from the /plugin menu.
For Codex
Add the marketplace in your terminal.
In your terminal: codex plugin marketplace add noro-to/noro Then open Plugins in Codex, find noro and install it.
For Hermes
Install the CLI and set your key, then add the skill to Hermes.
In your terminal: npm i -g github:noro-to/noro && noro init In your terminal: hermes skills install skills-sh/noro-to/noro/noro Or use skills.sh: npx skills add noro-to/noro -g -a hermes-agent
Hermes passes only the variables you list to MCP servers, so noro reads your key from its own file.
mcp_servers:
noro:
command: "npx"
args: ["-y", "@noro-to/noro", "mcp"]
timeout: 600
connect_timeout: 30 For skills.sh
Run in your terminal. It installs the skill for every agent it finds: Claude Code, Codex, Cursor, Copilot, Zed and more.
In your terminal: npx skills add noro-to/noro Update it later with npx skills update noro
For MCP
Pick your host.
Run once. It adds noro for every project.
In your terminal: claude mcp add --transport stdio --scope user noro -- npx -y @noro-to/noro mcp Add this to your Codex config. A report takes a few minutes, so raise the tool timeout.
[mcp_servers.noro]
command = "npx"
args = ["-y", "@noro-to/noro", "mcp"]
startup_timeout_sec = 30
tool_timeout_sec = 600 Add noro to your global MCP file.
{
"mcpServers": {
"noro": { "command": "npx", "args": ["-y", "@noro-to/noro", "mcp"] }
}
} Adds noro to your VS Code profile for Copilot agent mode.
In your terminal: code --add-mcp '{"name":"noro","command":"npx","args":["-y","@noro-to/noro","mcp"]}' Add this block to your Hermes config.
mcp_servers:
noro:
command: "npx"
args: ["-y", "@noro-to/noro", "mcp"]
timeout: 600
connect_timeout: 30 Add noro to your MCP config, then refresh the server list.
{
"mcpServers": {
"noro": { "command": "npx", "args": ["-y", "@noro-to/noro", "mcp"] }
}
} On newer builds the file is ~/.config/devin/mcp_config.json.
Add noro under context_servers in your Zed settings.
"context_servers": {
"noro": { "command": "npx", "args": ["-y", "@noro-to/noro", "mcp"] }
} noro adds two tools: noro_this writes or audits a report, and noro_facts returns the computed facts table with no model call.
JEV labels each fact as signal, noise or luck, then a chat model writes the report. Both see fact ids and labels, never your numbers.
For CLI, Hermes
Answer a few questions and noro writes the file for you:
In your terminal: noro init Or add the lines below to ~/.config/noro/.env yourself.
For Claude plugin, Codex, skills.sh, MCP
Answer a few questions and noro writes the file for you:
In your terminal: npx -y @noro-to/noro init Or add the lines below to ~/.config/noro/.env yourself.
Pick who writes
One key covers both steps: JEV labels the facts and Claude Opus 5.5 writes.
OPENROUTER_API_KEY=sk-or-...
# Optional. This is the default.
NORO_MODEL=openrouter:anthropic/claude-opus-5.5 Get a key at openrouter.ai/keys. Any model on OpenRouter works: NORO_MODEL=openrouter:<model-id>.
For your own use with your own plan
noro runs your installed, logged-in Claude Code to write. It never sees your login, and it removes API keys from the environment so the run counts against your plan.
Needs: Claude Code, logged in with your Claude plan.
NORO_MODEL=claude-cli:claude-opus-5-5
# JEV labels the facts
OPENROUTER_API_KEY=sk-or-... JEV still labels the facts through OpenRouter. With no OpenRouter key, noro labels them with built-in rules.
For your own use with your own plan
noro runs your installed, logged-in Codex CLI to write, with Codex’s own default model. It never sees your login, and it removes API keys from the environment so the run counts against your plan.
Needs: The Codex CLI, logged in with ChatGPT (codex login).
NORO_MODEL=codex-cli:default
# JEV labels the facts
OPENROUTER_API_KEY=sk-or-... JEV still labels the facts through OpenRouter. With no OpenRouter key, noro labels them with built-in rules.
Write with Claude Opus 5.5 on your own Anthropic key.
ANTHROPIC_API_KEY=sk-ant-...
NORO_MODEL=anthropic:claude-opus-5-5 JEV still labels the facts through OpenRouter. With no OpenRouter key, noro labels them with built-in rules.
Write with an OpenAI model on your own key.
OPENAI_API_KEY=sk-...
NORO_MODEL=openai:gpt-6.1-sol noro is tuned on Claude Opus 5.5. Other models work and may need more retries.
JEV still labels the facts through OpenRouter. With no OpenRouter key, noro labels them with built-in rules.
Write with Gemini on a Gemini API key.
GEMINI_API_KEY=...
NORO_MODEL=google:gemini-3.1-pro-preview Google AI Pro and Ultra plans can’t be used: Google’s terms forbid using them with other products. Use an API key. noro is tuned on Claude Opus 5.5. Other models work and may need more retries.
JEV still labels the facts through OpenRouter. With no OpenRouter key, noro labels them with built-in rules.
Write with a model on your own machine. Built-in rules label the facts with no setup, or run a local decision model. Nothing leaves the machine.
Needs: A 27B model needs about 24 GB of GPU memory or a 32 GB Mac.
In your terminal: ollama pull qwen3.8:27b NORO_MODEL=ollama:qwen3.8:27b
NORO_CLASSIFY=rules Start Ollama with OLLAMA_CONTEXT_LENGTH=16384, or long prompts get cut.
In your terminal: lms server start NORO_MODEL=lmstudio:qwen3.8-27b
NORO_CLASSIFY=rules In your terminal: ollama pull nimble # Replaces NORO_CLASSIFY=rules
NORO_CLASSIFY=jev
NORO_CLASSIFY_BASE_URL=http://localhost:11434
NORO_CLASSIFY_MODEL=nimble Ollama serves the decision model next to the writing model. NORO_CLASSIFY=rules stays the zero-setup option.
noro is tuned on Claude Opus 5.5. Other models work and may need more retries.
Each provider uses its standard variable names. Set NORO_MODEL to provider:model-id.
AWS_PROFILE=default
AWS_REGION=us-east-1
NORO_MODEL=bedrock:global.anthropic.claude-opus-5-5 GOOGLE_CLOUD_PROJECT=my-project
GOOGLE_CLOUD_LOCATION=global
NORO_MODEL=vertex:gemini-3.1-pro-preview Uses your Google Cloud login (gcloud auth application-default login).
AZURE_OPENAI_API_KEY=...
AZURE_OPENAI_RESOURCE_NAME=my-resource
NORO_MODEL=azure:gpt-6.1-sol The model id is your deployment name.
MISTRAL_API_KEY=...
NORO_MODEL=mistral:mistral-large-4 DEEPSEEK_API_KEY=...
NORO_MODEL=deepseek:deepseek-v4-pro GROQ_API_KEY=...
NORO_MODEL=groq:openai/gpt-oss-120b NORO_BASE_URL=http://localhost:8000/v1
# Optional
NORO_API_KEY=...
NORO_MODEL=openai-compatible:my-model vLLM, llama.cpp, LiteLLM or a company proxy.
noro is tuned on Claude Opus 5.5. Other models work and may need more retries.
JEV still labels the facts through OpenRouter. With no OpenRouter key, noro labels them with built-in rules.
For CLI
Check the setup for free, then point noro at an export.
In your terminal: noro doctor In your terminal: noro this ~/Downloads/campaign-report.csv Point it at a report you wrote and noro audits and rewrites it. Either way it asks about each flag: keep, cut or reword.
For Claude plugin, Codex, skills.sh
Check the setup for free, then start a new chat in any folder and ask:
In your terminal: npx -y @noro-to/noro doctor In your agent chat: noro this ~/Downloads/campaign-report.csv The skill runs noro, shows you the report and asks about each flag: keep, cut or reword.
For Hermes
Check the setup for free, then ask Hermes in any chat, including Slack or Telegram:
In your terminal: noro doctor In your agent chat: noro this ~/Downloads/campaign-report.csv Hermes runs noro, shows you the report and asks about each flag: keep, cut or reword.
For MCP
Check the setup for free, then ask your agent:
In your terminal: npx -y @noro-to/noro doctor In your agent chat: Use noro on ~/Downloads/campaign-report.csv Your agent calls noro_this and gets the report back with every number traced to a fact id.
Reports can run without you. noro needs no terminal when you pass --yes.
For Hermes
With Hermes cron
A weekly report, delivered where Hermes talks to you:
In your terminal: hermes cron create "every monday 9am" "noro this ~/exports/latest.csv --format slack" --skill noro --name noro-weekly Set delivery to slack or telegram when Hermes asks.
In GitHub Actions
Copy the weekly workflow into your repo and add OPENROUTER_API_KEY as a repository secret. It runs every Monday.
With cron
Add this line with crontab -e. It runs Mondays at 07:17.
Line to paste: 17 7 * * 1 cd ~/reports && /usr/local/bin/noro this exports/latest.csv --yes > report.md In Docker
No Node or Python on the machine. Run it from the folder that holds your .env.
In your terminal: docker run --rm -it -v "$PWD:/work" -w /work --env-file .env ghcr.io/noro-to/noro this exports/latest.csv Subscription writers need your own login, so use an API key in Docker and CI.
A report every Monday from GitHub Actions, cron or Hermes, with no terminal open. Examples for systemd and launchd are in the docs.
Set up scheduled runsnoro mcp gives Claude Code, Codex, Cursor, VS Code and Hermes two tools: one writes or audits a report, one returns the facts table.
Write with a model in Ollama or LM Studio and label facts with built-in rules or a local decision model. Your data and every model call stay on your machine.
Set up a local model