Get started with OKed
One page to install Claude Code, Codex, Cursor, GitHub Copilot, the Vercel AI SDK, the OpenAI Agents SDK, or LangGraph (JavaScript), see which actions wait, and check a receipt. The package READMEs on GitHub have the rest.
Where approvals show up
- Sign up, or sign in, then link Telegram or turn on web push.
- Approvals arrive on Telegram and the web dashboard. You can turn on both. iPhone Soon.
Claude Code
In your project:
npm install -g @oked/claude-code oked init
oked init writes a PreToolUse hook into .claude/settings.json, opens a browser to pair this machine, and stores the API key in ~/.oked/config.json. Open a new Claude Code session in that project. The hook is active.
oked statusshows the install and pings the backend.oked init --no-browserprints the pairing link instead of opening a browser. Use it on a server or over SSH.oked uninstallremoves the project hook. Other hooks are kept.
Codex CLI
In your project:
npm install -g @oked/codex oked-codex init
oked-codex init (the same command as npx oked-codex init) writes a PreToolUse hook into .codex/hooks.json with a timeout of 690 seconds, opens a browser to pair this machine, and stores the API key in ~/.oked/config.json. Then, in Codex, run /hooks and trust the hook. Codex remembers that trust against the hook hash. Run /hooks again if a later init changes the timeout or the command.
If this device is not paired, the hook denies. The reason is Pair first: run oked-codex init. The approval window is 10 minutes. The SDK waits 630 seconds, inside the 690 second hook timeout, so a missed approval can be written as a deny before Codex kills the hook. Codex fails open if the hook errors, times out, or prints malformed output. An allow prints nothing. Command hooks do not run in Codex cloud, and hosted tools such as web search are not sent to this hook.
oked-codex statusshows the install and pings the backend.oked-codex init --no-browserprints the pairing link instead of opening a browser. Use it on a server or over SSH.oked-codex uninstallremoves the project hook. Other hooks in.codex/hooks.jsonare kept.
See the package README.
Cursor
In your project:
npm install -g @oked/cursor oked-cursor init
oked-cursor init writes .cursor/hooks.json with a timeout of 690 seconds and failClosed: true, opens a browser to pair this machine, and stores the API key in ~/.oked/config.json. Open a new Cursor agent session in that project. Cursor reloads the file when it changes.
If this device is not paired, the hook denies. The reason is Pair first: run oked-cursor init. It does not print ask. With failClosed, a crash, a timeout, or no output denies the action. Cursor does not document a maximum timeout, and a 10 minute wait has not been confirmed inside the Cursor app. Run one real session before you rely on it. On a reported Windows CLI bug, the verdict is dropped at the deadline, so failClosed denies an approval as well as a denial.
If a Claude Code oked-hook is already installed, init does not add a second hook. Cursor loads those hooks by default, and both would ask. oked-cursor init --native installs the Cursor hook anyway. The imported Claude hook has no failClosed field, so a timeout of that hook fails open. Cloud agents load .cursor/hooks.json only.
oked-cursor statusshows the install and pings the backend.oked-cursor init --no-browserprints the pairing link instead of opening a browser. Use it on a server or over SSH.oked-cursor uninstallremoves the Cursor hook. Other hooks in.cursor/hooks.jsonare kept. A Claude Code hook is not removed.
See the package README.
GitHub Copilot
For the Copilot CLI and for VS Code. VS Code hooks are Preview. In your project:
npm install -g @oked/copilot oked-copilot init
oked-copilot init writes .github/hooks/oked.json with timeoutSec 690, opens a browser to pair this machine, and stores the API key in ~/.oked/config.json. Open a new Copilot CLI session, or a new Copilot chat in VS Code, in that project.
If this device is not paired, the hook denies. The reason is Pair first: run oked-copilot init. It does not print ask. A crash or any non-zero exit denies the tool. A timeout fails open, including for a policy hook. There is no failClosed field. Copilot's default timeout is 30 seconds, and the docs state no maximum. Confirm timeoutSec: 690 in the CLI and in VS Code before you rely on a 10 minute approval.
If this project's .claude/settings.json or .claude/settings.local.json already has oked-hook, init does not write a second hook. oked-copilot init --native installs anyway, and you are asked twice until that entry is removed. A user-level ~/.claude/settings.json hook does not run in Copilot. The cloud coding agent loads this same project file. Its network reaches GitHub hosts only, unless an org admin allows api.oked.ai. Without that, high_stakes is denied. The wait counts against the job timeout.
oked-copilot statusshows the install and pings the backend.oked-copilot init --no-browserprints the pairing link instead of opening a browser. Use it on a server or over SSH.oked-copilot uninstallremoves the Copilot hook. Other hooks in the file are kept. A Claude Code hook is not removed.
See the package README.
These hooks and the Claude Code hook call @oked/hook-core. Do not install that package on its own. It has no init command.
How an action is sorted
Classification looks at the kind of effect, not the command's name, and it runs on your machine. Codex, Cursor, and GitHub Copilot use this same sorting and map their tool names onto it. The Vercel AI SDK, OpenAI Agents SDK, and LangGraph packages use these same tiers. A denial or a timeout does not run the tool. A Bash command with no detected side effect defaults to safe. An unknown tool that is not Bash defaults to review. A request that nobody answers within 10 minutes is denied when the host lets the hook finish. See Codex, Cursor, and GitHub Copilot above for timeout limits.
| Tier | What happens | Examples |
|---|---|---|
safe |
Runs. No notification. | Reads and queries, SELECT, ls, grep, plain curl GET. |
warning |
Runs, and is logged in the terminal. No push. | File create, cp, mv, a /tmp delete, local git commit, npm install. |
review |
Waits for your tap, for up to 10 minutes. | sudo, writes to ~/.ssh, sending email, curl POST with an inline body. |
high_stakes |
Waits for your approval, with confirmation, for up to 10 minutes. | rm of data outside /tmp, DROP TABLE, git push, npm publish. |
Other agents
Claude Agent SDK
npm install @oked/claude-agent-sdk
Wire the hook into options.hooks. See the package README.
OpenClaw
npm install @oked/openclaw
Enable it in ~/.openclaw/openclaw.json. See the package README.
Vercel AI SDK
npm install @oked/ai-sdk
Set OKED_API_KEY to a key from the dashboard. This package has no pairing command. okedToolApproval() needs AI SDK 7. Pass it as toolApproval. safe and warning run immediately. review and high_stakes wait. A denial or a timeout does not run the tool. Approvals arrive on Telegram or the web dashboard.
import { okedToolApproval } from "@oked/ai-sdk"; await generateText({ model, tools, toolApproval: okedToolApproval(), prompt, });
On AI SDK 5 and 6, wrap execute with withOked() or wrap a tools object with okedTools(). Do not also set toolApproval on a tool you already wrapped. See the package README.
OpenAI Agents SDK
npm install @oked/openai-agents
For the TypeScript SDK (@openai/agents). Set OKED_API_KEY to a key from the dashboard. This package has no pairing command. okedTool() takes the same arguments as tool(). A denial or a timeout does not run the tool, and execute is not called. Approvals arrive on Telegram or the web dashboard. Do not also set needsApproval on that tool.
import { okedTool } from "@oked/openai-agents"; const refundPayment = okedTool({ name: "refund_payment", description: "Refund a charge", parameters: z.object({ chargeId: z.string(), amount: z.number() }), async execute({ chargeId, amount }) { return `Refunded ${amount} on ${chargeId}`; }, });
withOkedTools() wraps a list you already built. See the package README.
LangGraph
npm install @oked/langgraph
LangGraph support is JavaScript for now. Set OKED_API_KEY to a key from the dashboard. This package has no pairing command. withOkedApprovals() wraps a list of LangChain tools. Pass that list to createReactAgent. A denial or a timeout does not run the tool. Approvals arrive on Telegram or the web dashboard.
import { createReactAgent } from "@langchain/langgraph/prebuilt"; import { withOkedApprovals } from "@oked/langgraph"; const agent = createReactAgent({ llm, tools: withOkedApprovals([searchDocs, sendEmail]), });
withOkedApproval() wraps one tool. See the package README.
NVIDIA OpenShell
OKed runs as supervisor middleware. The project is an early preview and covers the GitHub REST API. Install and the macOS quickstart are in oked-ai/oked-openshell. Get a key without installing the Claude Code hook:
npm install -g @oked/claude-code oked init --key-only
Any Node.js agent
npm install @oked/sdk
Call oked.approve() once before the action. The default timeout is 10 minutes, and a timeout is a denial. See the SDK README.
Rules
On Telegram, tap ⚙️ Rule on an approval card. On the web dashboard, use the gear on a card, or open Rules and add one. A rule can always allow, always deny, or change the tier (the action still asks). Rules match the fields on the card: kind, title, target, body, and folder. They run top to bottom, and the first match wins. A rule's decision gets a receipt marked as a rule.
Example: a rule whose target contains prod can deny the action, or raise it to high_stakes so it still asks.
Environment
| Variable | What it does |
|---|---|
OKED_API_KEY |
Optional after pairing. The host init command stores the key in ~/.oked/config.json. The Vercel AI SDK, OpenAI Agents SDK, and LangGraph packages read this variable. Create the key on the dashboard. The config file is used when the variable is unset. |
OKED_STRICT_FAIL_CLOSED |
Set to 1 to deny every sensitive action when the backend is unreachable. The default denies only high_stakes. |
Receipts
Every decision gets a receipt signed by OKed (Ed25519) and hash-chained to the one before it. Your copy is ~/.oked/receipts.jsonl.
oked receipts verify
That checks signatures and the links between neighbouring receipts. Gaps in the sequence are expected on one machine, because other devices share the chain.
An export from the dashboard is checked offline, with no account required:
npx @oked/verify oked-receipts.zip
A receipt records who decided, how they were verified, when, and a digest of the exact action. The readable summary is the title you were shown, unless you turned summaries off. The export holds those digests, not the commands themselves. Since version 0.6.0, an approval with no valid receipt is denied. Set OKED_REQUIRE_RECEIPT=0 only for a backend that does not sign receipts.
The field-by-field format is in docs/receipts.md. An export can also be checked offline with npx @oked/verify.
Check a receipt
Paste one receipt JSON. The signature is checked in this browser against OKed's published keys. Nothing is uploaded.
Questions or need help? contact@oked.ai