Keyturn
by Solve4x-ai
README.md
<div align="center">
# Keyturn
### Your AI proposes. You turn the key.
**Run IT for many organizations in natural language — with a human hand on every change.**
A local command center that lets your AI assistant (Claude, Cursor, Codex, Devin, any MCP client) investigate and operate your RMM fleet — while every endpoint action waits for **your** approval, signed with a passkey.
[](https://github.com/Solve4x-ai/Keyturn/actions/workflows/ci.yml)




[](LICENSE)
[Try the demo](#try-it-in-60-seconds) · [Setup](SETUP.md) · [Features](FEATURES.md) · [Tools](TOOLS.md) · [Connect an AI client](docs/harness-guide.md) · [Security model](docs/security-model.md)
<img src="docs/images/keyturn-demo.gif" alt="30-second demo: ask an AI assistant about a nearly full DHCP scope, review the exact plan it proposes in Keyturn, approve it with a passkey, and see the verified receipt" width="100%">
<sub>Demo tenant with fictional data · the chat panel stands in for any MCP client (Claude, Cursor, Codex, …)</sub>
</div>
## Why
MSPs and IT teams already have an agent on every machine. What they don't have is a safe way to let an AI *use* it. Keyturn is that missing layer:
- **Talk to your fleet.** "Which DHCP scopes are almost full?" "Why is the reception PC offline?" "Inventory the GPOs on the domain and flag anything unlinked." The assistant answers from collected evidence — not guesses.
- **Nothing runs without you.** Every endpoint action is an immutable, hashed plan that waits for a human. With a YubiKey, Windows Hello, or Bitwarden passkey enrolled, an AI holding every token on the box still cannot approve anything.
- **Everything is remembered.** Findings, questions, answers, decisions, and receipts are durable. The next session — or the next AI — picks up where the last one left off.
- **One pane per client, or all of them.** A global organization scope follows you across every page.
- **Local by design.** No cloud service, no telemetry. Your RMM credentials never leave your machine.
## Try it in 60 seconds
No RMM account needed. The demo runs the full UI against a fictional MSP with three clients and ~85 devices, sandboxed and read-only:
```bash
git clone https://github.com/Solve4x-ai/Keyturn.git
cd Keyturn
npm install
npm run demo
```
Your browser opens at `http://localhost:39399`. Press `Ctrl+C` to stop; `npm run demo -- --reset` regenerates the data.
## Screenshots
<img src="docs/images/overview.png" alt="Overview — fleet status, server constellation with evidence-backed DC/DNS/DHCP roles, approvals, risks, and operations" width="100%">
**Overview** — fleet health, a server constellation with DC / DNS / DHCP roles taken only from collected evidence, what's waiting on you, and operation success at a glance.
| | |
|---|---|
| <img src="docs/images/organization.png" alt="Organization command page"> **Organizations** — every client as a command page: KPIs, infrastructure snapshot, servers, risks, and what needs attention. | <img src="docs/images/infrastructure.png" alt="Infrastructure overview"> **Infrastructure** — Active Directory with FSMO roles, DNS, DHCP, and Group Policy health, derived only from collected evidence. |
| <img src="docs/images/dhcp.png" alt="DHCP scopes"> **DHCP** — scope utilization gauges, options, and stale AD authorizations checked against live agents. | <img src="docs/images/review-center.png" alt="Review Center"> **Review Center** — AI- and rule-proposed risks with provenance; your decisions are recorded, never rewritten. |
| <img src="docs/images/approvals.png" alt="Approvals queue"> **Approvals** — plans your AI proposed wait here. Approval binds the exact script, target, and parameters. | <img src="docs/images/analytics.png" alt="Analytics"> **Analytics** — runbook reliability, p50 / p95 time-to-receipt, change volume, and findings flow. |
<div align="center"><img src="docs/images/organization-light.png" alt="Light theme" width="80%"><br><sub>Dark, light, and system themes · four accents · compact or comfortable density · <code>Ctrl+K</code> command palette</sub></div>
## How it works
```mermaid
flowchart LR
AI["AI client<br/>(Claude · Cursor · Codex · Devin)"] -- "MCP · stdio" --> MCP["Connector layer<br/>reporting · command profiles"]
MCP -- "create_plan" --> Store[("Local evidence store<br/>SQLite · per tenant")]
Human["You"] -- "review + passkey" --> UI["Keyturn dashboard<br/>localhost · bearer + WebAuthn"]
UI -- "approve · dispatch" --> Store
Store -- "approved plan only" --> RMM["RMM API<br/>(NinjaOne connector)"]
RMM --> Agents["RMM agent<br/>on every endpoint"]
Agents -- "receipts + evidence" --> Store
```
1. **Collect** — read-only diagnostic runbooks (AD health, DNS, DHCP, GPO, …) run through an approved PowerShell runner. Results land as timestamped observations with explicit coverage, so "not found" is only claimed where a complete enumeration ran.
2. **Understand** — deterministic rules raise findings; the AI adds context, questions, and recommendations in the Review Center.
3. **Propose** — endpoint work becomes a plan: exact script, targets, parameters, and a hash that binds them.
4. **Approve** — you approve in the local UI. Approvals expire, are single-use, bind to the plan hash, and require a passkey once one is enrolled.
5. **Execute & verify** — dispatch is idempotent, canary batches gate the rest of the fleet, and "accepted" never means "done" until a receipt proves it.
## Safety model
| Layer | Guarantee |
|---|---|
| **Two profiles** | A read-only *reporting* identity and a separately authorized *command* identity (OAuth + PKCE). They share no credentials. |
| **Plan-only execution** | Endpoint-affecting tools (scripts, reboot, service control, …) are refused outright — `confirm: true` is not approval. |
| **Human-presence approval** | WebAuthn passkeys. The first key bootstraps; every later key or revocation needs an existing key; the last key can't be removed. |
| **Organization boundaries** | Explicit allowlists, re-checked against a fresh device lookup immediately before dispatch. |
| **Bounded sessions** | Follow-up commands on an approved device are capped by TTL and count — or disabled entirely. |
| **Audit** | Every tool call is journaled with redacted arguments; every approval stores its signed assertion. |
| **Local** | stdio MCP only; the UI binds to loopback. No hosted service, no credentials in client config. |
Details: [docs/security-model.md](docs/security-model.md).
## Use it with your NinjaOne tenant
Requirements: **Windows**, **Node.js 22.13+**, and two NinjaOne API applications (an API Services app for read-only reporting and a Native app for commands). The UI and MCP server are cross-platform Node, but the endpoint runbooks and setup scripts are PowerShell-first.
```powershell
git clone https://github.com/Solve4x-ai/Keyturn.git
cd Keyturn
npm install
npm run build
Copy-Item config\reporting.env.example config\reporting.env
Copy-Item config\command.env.example config\command.env
Copy-Item config\policy.example.json config\policy.json
```
Then follow **[SETUP.md](SETUP.md)** — about 15 minutes — to create the NinjaOne apps, authorize the command profile, start the dashboard, enroll a passkey, and connect your AI client from **Settings → MCP clients**.
The tracked policy example disables every write. Enable only what you need, per organization.
## Development
```powershell
npm run build # TypeScript → dist/
npm test # mocked tests — never touch a live tenant
npm run verify # build + tests + PowerShell runner tests
```
The UI is vanilla ES modules and CSS (oklch design tokens, View Transitions, container queries) — no framework and no build step. See [CONTRIBUTING.md](CONTRIBUTING.md).
## Roadmap
Additional RMM connectors (the core is connector-agnostic) · SNMPv3 network-edge agent for switches, firewalls, APs, and printers · reboot / service / patch actions as approved runbooks · scheduled management reports · notifications · OS-account separation for the command server. Details in [FEATURES.md](FEATURES.md#roadmap-planned-not-yet-built).
## Support
- **Questions and ideas:** [Discussions](https://github.com/Solve4x-ai/Keyturn/discussions), or [support@solve4x.ai](mailto:support@solve4x.ai)
- **Bugs:** [GitHub issues](https://github.com/Solve4x-ai/Keyturn/issues)
- **Security:** see [SECURITY.md](SECURITY.md) — please report privately
## License
[MIT](LICENSE). Originally derived from [NinjaOneMCP](https://github.com/Lungshot/NinjaOneMCP). The NinjaOne connector is built on the NinjaOne public API; this project is not affiliated with or endorsed by NinjaOne.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues