100% free and open source · every tool, every host, no licence key · read the licence
Secronyx

Free forever Open source Self-hosted

Secronyx Diagnostics that read,
never write.

Free to download, free to run, free to keep. A read-only MCP agent that lets any AI assistant investigate production hosts through 530 fixed, typed queries. No shell, no write path, secrets redacted, every call audited, scopes enforced per caller.

No account. No licence key. No node limit. No credit card. Run it on 5 hosts or 50,000 at no cost.

secronyx

How a diagnosis happens

Alert in. Agent asks the servers. Evidence augmented. Operators fix it first.

The agent talks to every server over MCP. What comes back is typed and redacted; the agent augments its diagnosis with that evidence and sends operators a conclusion with citations, not a guess. The operator acts on it; Secronyx never does.

🔒

Read-only by construction

No caller-composed command is ever run. Unix collectors use native APIs and fixed argv; Windows collectors run fixed PowerShell scripts with every caller value validated and quoted.

🎫

Scopes per tool, per caller

Nineteen scopes. A token, key or certificate grants some; the server enforces the grant on every call and hides the rest from tools/list.

✂️

Redaction on by default

Environments, command lines, config files, registry values and log lines pass through credential detection before they leave the process.

📜

Tamper-evident audit

Hash-chained JSON lines with identity, arguments, duration and outcome. Verify the chain with --audit-verify. Falls back to stderr, never silent.

🪪

Enterprise authentication

OIDC, OAuth introspection, API keys, mutual TLS with SPIFFE and CRLs, and SSH-key request signing. Chain them: mTLS gates the handshake, and an unmapped certificate leaves the identity to the key, signature or token.

🚧

Refuses unsafe exposure

Will not listen off loopback without auth and TLS. Rejects short tokens. Probes never reach cloud metadata, link-local or loopback.

🧾

Typed JSON, every platform

The same schema on Linux, macOS and Windows. The model reasons over fields, not over the quirks of ps and netstat.

⏱️

Bounded by design

A 4 MiB result cap on every transport. On HTTP: per-client rate limits, a 32-way concurrency cap and lockout after repeated bad credentials.

📦

One static binary

No runtime, no agent framework. Signed MSI, macOS pkg, Helm chart, and SLSA-attested static binaries. Speaks MCP over stdio by default and opens no port until you ask.

At a glance

json-rpc
// the assistant asks a fixed question
{ "method": "tools/call", "params": { "name": "get_app_config",
    "arguments": { "path": "/etc/app/config.yml" } } }

// the host answers with typed evidence, secrets already struck out
{ "path": "/etc/app/config.yml", "format": "yaml",
  "content": "db_host: pg.internal\ndb_user: app\ndb_password: [REDACTED]\napi_token: [REDACTED]",
  "redaction_summary": { "total_redactions": 2, "by_type": { "password": 1, "token": 1 },
    "env_var_refs": 0, "template_refs": 0 } }

// and the ledger records it
{ "timestamp": "2026-09-16T08:41:20Z", "seq": 42, "action": "tools/call",
  "resource": "get_app_config", "identity": "sre-oncall", "client_ip": "10.0.4.7",
  "params": { "path": "/etc/app/config.yml" }, "result": "success",
  "duration_ns": 3000000, "prev_hash": "4f2a…", "hash": "9c1e…" }

Nothing composed, nothing guessed. The assistant never composes a command. It picks a tool, the server runs a fixed collector, and the answer comes back as a schema the model already knows. That is why Secronyx works on hosts where an SSH session would never be approved.

What it costs

Nothing. Secronyx is free forever.

You install it on your own hosts and run it yourself. It is free for everyone, including businesses, with no charge per node, per seat or per query, and nothing held back behind a paid tier or a licence key. There is no edition to upgrade to: what you download is the whole product.

Free forever Everything, for everyone
  • All 530 diagnostic tools, nothing gated
  • Unlimited hosts, unlimited queries
  • Every authentication method: API keys, mutual TLS, SSH signing, OIDC
  • Redaction, audit ledger and scope enforcement
  • Commercial use inside your business, at no cost
  • Full source on GitHub, builds you can reproduce

Secronyx is open source under the GNU Affero General Public License v3, an OSI-approved licence. Use it, change it and share it freely, for any purpose including commercial use. Running it asks nothing of you. If you distribute modifications, or offer a modified version as a service to others, publish those modifications under the same licence.

Invoke it anywhere

One agent per host. Thousands of hosts. Same four ways in.

Every Secronyx agent speaks the same JSON-RPC over MCP, so an assistant, your own automation, a fleet controller and a monitoring webhook all call it the same way. Scopes, redaction and the audit ledger apply whichever door you come through.

💬

From an assistant

Claude, Cursor or any MCP client, local or remote

json · remote MCP server
{ "mcpServers": { "prod-db-03": {
    "url": "https://prod-db-03.example:8443/",
    "headers": { "Authorization": "Bearer ${SECRONYX_TOKEN}" } } } }

The assistant sees only the tools its token's scopes allow. Ask it a question; it plans the calls.

🤖

From your own agent

Any language, plain HTTPS, an API key with scopes

python · one host
import httpx, json
r = httpx.post("https://prod-db-03.example:8443/",
    headers={"X-API-Key": KEY},
    json={"jsonrpc": "2.0", "id": 1, "method": "tools/call",
          "params": {"name": "get_disk_info", "arguments": {}}})
res = r.json()["result"]              # MCP CallToolResult
if res.get("isError"): raise RuntimeError(res["content"][0]["text"])
evidence = json.loads(res["content"][0]["text"])  # typed, redacted, audited

Feed the result into your retrieval store or straight into a model prompt. The audit line is already written on the host.

🌐

Across a fleet

Fan out the same question to every host, in parallel

python · 5,000 hosts
async def ask(host, tool, args={}):
    r = await client.post(f"https://{host}:8443/", headers=AUTH,
        json={"jsonrpc": "2.0", "id": 1, "method": "tools/call",
              "params": {"name": tool, "arguments": args}})
    res = r.json()["result"]                  # MCP CallToolResult
    return host, json.loads(res["content"][0]["text"])

results = await asyncio.gather(*[ask(h, "get_disk_info") for h in inventory])
hot = [h for h, ev in results if any(p["used_percent"] > 90 for p in ev["partitions"])]

Per-host rate limits and result caps keep a fleet-wide sweep from becoming a fleet-wide incident. Behind NAT? Run agents in hybrid mode: they dial out to Secronyx, no inbound port on any host.

📟

Triggered by monitoring

An alert webhook starts the loop; operators get evidence before they open a shell

yaml · runbook
on: alert.disk_usage_high
steps:
  - ask: [get_disk_info, get_processes, get_journal_logs]   # against $host
  - ground: retrieve from evidence, cite each fact
  - notify: on-call with diagnosis + evidence links

The alert carries the host; the runbook carries the questions. By the time a person looks, the evidence is already collected, redacted and on the record.

Security

Built so the strictest security team can sign it off.

Every control is on by default and written down in the threat model. Each has a startup flag that turns it off, and turning off redaction, the audit ledger, HTTP rate limiting or the sensitive-scope guard logs a warning at startup. Nothing here is a roadmap item.

What it will never do

  • Run a shell pipeline, or any command or script a caller composed
  • Answer a call outside the caller's granted scopes
  • Return an environment variable, argument or config value that looks like a credential
  • Read a file outside the allowed roots, follow a symlink out of them, or open key material
  • Start on a non-loopback address without authentication and TLS
  • Probe a cloud metadata service, link-local or loopback address
  • Return more than 4 MiB in a single result, or let one HTTP client flood the host

What it always does

  • Validates and quotes every caller-supplied value before a collector sees it
  • Redacts by field name and by value pattern; config-file and environment results also report how many values were struck
  • Writes a hash-chained audit line for every call, denial and auth failure
  • Filters tools/list to what the caller may actually invoke
  • Rate-limits per client and locks out after repeated authentication failures
  • Labels estimates as estimates: forecasts carry method, sample count and caveats
  • Ships the threat model, the redaction coverage inventory and the scope table with the code
19
scopes, enforced per call. sensitive is unregistered unless you opt in.
32+
characters minimum for a static token. Shorter is refused at startup.
0
arbitrary file reads. Config and lock-file tools go through a path policy with a deny list for keys.

Authentication

Bring the credentials you already govern.

Methods are checked in a fixed order: API key, then SSH signature, then client certificate, then OIDC or bearer token. Mutual TLS can gate the transport and leave identity to a token, as long as you map no certificate identities.

🏢

OIDC · OAuth

Okta, Entra, Keycloak, any issuer. Local JWT validation with jti replay protection and lifetime caps, or token introspection with a short cache.

🔐

Mutual TLS · SPIFFE

Client certificates mapped to scopes by SPKI fingerprint, SPIFFE ID, DNS name or CN. CRLs enforced, trust domains restricted.

🔑

API keys

Hashed at rest, scoped, expiring, pinned to CIDRs, hot-reloaded. Issued with secronyx apikey create, shown once.

🖊️

SSH keys · certificates

Sign each request with the Ed25519, ECDSA or RSA key you already carry, or an SSH CA certificate. Nonces and a clock window stop replay.

Use cases

Where a read-only agent earns its keep.

Tutorials

From download to first answer.

1

Install and ask your first question

bash
$ curl -fsSL https://github.com/levantar-ai/secronyx/releases/latest/download/secronyx-linux-amd64 | tar xz
$ ./secronyx --query get_cpu_info --json

One static binary. The direct-query mode runs a single tool and prints its JSON, useful for scripts and for checking a host before you connect an assistant.

Read the guide →

2

Connect Claude Desktop or Cursor

json
{ "mcpServers": { "secronyx": {
    "command": "secronyx" } } }

Stdio transport, no port opened. Redaction and the audit ledger are already on; rate limiting and the concurrency cap belong to the HTTP transport. Sensitive tools stay unregistered until you pass --enable-sensitive.

Read the guide →

3

Expose a fleet behind your identity provider

bash
$ secronyx --transport http --listen 0.0.0.0:8443 \
    --tls-cert cert.pem --tls-key key.pem \
    --oidc-issuer https://login.example.com --oidc-audience secronyx \
    --scopes core,logs,hooks

Try this without TLS or without an issuer and the server refuses to start. Each user's token scopes decide which tools they see.

Read the guide →

4

Issue an API key for automation

bash
$ secronyx apikey create --file keys.json \
    --name ci-runner --scopes core,logs --expires 90d --cidr 10.0.0.0/8
$ secronyx --transport http … --api-keys-file keys.json

The key is shown once and stored hashed. Revoke with apikey revoke; the server reloads the file without a restart.

Read the tutorial →

5

Mutual TLS with SPIFFE identities

bash
$ secronyx --transport http … \
    --tls-client-ca ca.pem --mtls-identity-file identities.json \
    --mtls-trust-domain prod.example --mtls-crl crl.pem

Map an SPKI fingerprint, SPIFFE ID, DNS name or CN to a name and scopes. An API key or SSH signature on the same request is checked first; an OIDC or bearer token is not, so if you want the token to supply the identity, pass --tls-client-ca alone and leave the certificate to gate the handshake.

Read the tutorial →

6

Sign requests with the SSH key you carry

bash
$ secronyx --transport http … --ssh-authorized-keys authorized_keys
$ secronyx ssh-sign --key ~/.ssh/id_ed25519 \
    --url https://host:8443/ --body req.json --curl

Each line of authorized_keys can carry scopes=, expires= and from=. SSH CA certificates work too.

Read the tutorial →

Compare

Why not just give the model a shell?

A read-only SSH user is not read-only. An agent on the box is the box.

Agent on the hostSSH, read-only userSecronyx
Can it writeAnything the process canRedirects, tee, crontab, whatever sudo allowsNo. There is no write path, and no command a caller composed.
If the model is subvertedHost compromiseHost compromise within the account's reachDisclosure bounded by the caller's scopes
SecretsEnvironments, history, configs readablecat returns the passwordStruck out before they leave the process
AuthorisationNoneOne account, one privilege levelPer tool, per identity, every call
AuditAgent logs, if anyHistory the same account can editHash-chained ledger with identity and arguments
OutputFree text to parseDiffers by platform and versionSame JSON on Linux, macOS, Windows
Resource impactUnboundedUnbounded per session4 MiB result cap; rate limits and a concurrency cap on HTTP

Read the full comparison →

Deploy

Local by default. Networked only when it can defend itself.

  • Linux · static binary with SLSA provenance, systemd service
  • Windows · MSI with an enterprise config template, runs as a service
  • macOS · pkg and launchd
  • Kubernetes · Helm chart that fails to render an insecure release
  • Docker · Compose files that require a token and publish on loopback only

For agents

Made for assistants, not adapted for them.

  • 530 tools with JSON schemas, so a model plans calls instead of composing commands
  • Results that say what they are: method, based_on_samples, caveat on every estimate
  • Errors flagged with isError on the result and written to the audit ledger, never swallowed
  • A result cap so a runaway query cannot flood the context window
  • Works with Claude, Cursor and any MCP client over stdio or authenticated HTTPS

Read the threat model before you read the pitch.

SECURITY.md, the redaction coverage inventory, the scope table and the audit format ship with the source.