Documentation
Encrypted CI/CD, cron, webhook and server alerts to your phone.
Sender secrets can only send. Relay sees ciphertext. Actions are optional.
Getting started
Install NerveOps from the App Store or Google Play, then create your first pipe.
- Create a pipe in the mobile app.
- Open pipe setup and choose Send signals.
- Copy the DSN into your shell or CI secret store.
- Send your first encrypted signal with
nerve send.
Send signals
Signals are the safe default. A sender DSN can post encrypted messages into one pipe only. It cannot read history or execute commands.
Install the CLI, paste the sender DSN from pipe setup, then send a small test signal.
curl -fsSL https://nerve.ink/install.sh | sh
export NERVE_DSN="nerve://TOKEN:[email protected]"
echo "deploy failed" | nerve send --title "Nerve test"
Go fallback / developer install:
go install github.com/nerve-ink/nerve-cli/cmd/nerve@latest
export PATH="$PATH:$(go env GOPATH)/bin"
Webhooks
Use webhooks when a service can post an event but cannot run the Nerve CLI. A webhook sender is still a signal source: it can create alerts for one pipe, but it cannot read history, connect as an agent, or execute commands.
Keep webhook payloads short and operational. Send the job name, environment, status, URL, and a few useful fields instead of raw logs, secrets, or full incident context.
Nerve is intentionally protocol-first: webhooks for HTTPS-capable tools, nerve send for scripts and CI runners, the GitHub Action for GitHub workflows, API paths for custom senders, and the optional agent for signed bounded actions. It complements Prometheus, Grafana, Alertmanager, cron, uptime checks and deploy tools; it does not try to replace their exporter or dashboard ecosystems.
GitHub Actions
Store the DSN as a repository or environment secret named NERVE_DSN, then notify from a workflow step.
- name: Install Nerve
run: curl -fsSL https://nerve.ink/install.sh | sh
- name: Notify Nerve on failure
if: failure()
env:
NERVE_DSN: ${{ secrets.NERVE_DSN }}
run: |
printf 'FAILED: %s\nbranch: %s\nrun: %s\n' \
"${{ github.repository }}" \
"${{ github.ref_name }}" \
"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
| nerve send --severity critical --title "CI failed"
Run agent
The agent connects infrastructure you control for signed, bounded actions. Treat the token like host access. Prefer a dedicated user, least privilege, and runbook-style commands.
# Linux x86_64 / ARM64
command -v go >/dev/null || {
GO_VERSION="$(curl -fsSL 'https://go.dev/VERSION?m=text' | head -n 1)"
case "$(uname -m)" in
x86_64|amd64) GO_ARCH="amd64" ;;
aarch64|arm64) GO_ARCH="arm64" ;;
*) echo "Unsupported architecture: $(uname -m)"; exit 1 ;;
esac
curl -fsSLO "https://go.dev/dl/${GO_VERSION}.linux-${GO_ARCH}.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "${GO_VERSION}.linux-${GO_ARCH}.tar.gz"
export PATH="/usr/local/go/bin:$PATH"
}
go install github.com/nerve-ink/nerve-agent@latest
export PATH="$PATH:$(go env GOPATH)/bin"
nerve-agent -server api.nerve.ink:443 -token TOKEN
Security model
- The relay routes encrypted envelopes, routing metadata, and device delivery metadata; it should not receive plaintext signal, command, or output payloads.
- Sender DSNs can send into one pipe only and cannot read or execute.
- Push notifications wake or notify the device; clients sync encrypted records and decrypt locally.
- Agent tokens connect a controlled machine; command execution still requires signed command payloads from the mobile identity.
- Nerve is not SSH, a PTY, or a native mobile terminal.
Leak model
Nerve separates sender and agent credentials so the safe path stays safe even when a CI secret leaks.
Rotation
- If a sender DSN leaks, create a new sender from pipe setup, update your CI secret, then delete the old sender.
- If an agent token leaks, create a new agent token and stop the old process before trusting the pipe again.
- If a device identity mismatches, use the in-app recovery or reset flow instead of accepting silent key replacement.
Troubleshooting
Why do I see encrypted text after reinstall?
Your local E2E identity may still be syncing through iCloud Keychain or may not match the relay fingerprint. Nerve blocks silent key rotation and asks you to retry recovery or reset explicitly.
Should I start with the agent?
No. Start with send-only signals unless you explicitly need signed actions on a machine you control.
Do I need Go installed on the server?
No for the sender CLI path. Use curl -fsSL https://nerve.ink/install.sh | sh. Go remains available as a developer fallback and for the agent path.
Why do I get 415 Unsupported Media Type?
You are probably calling an old shell function or a generic webhook instead of the Go CLI. Run type nerve and nerve --help. The current CLI sends JSON automatically and prints sent on success.
What should a signal contain?
Keep it short: service, environment, status, commit SHA, and a run URL. Do not send full logs, secrets, tokens, or environment dumps.