Introducing Crucible CLI — the missing command line for Azure Service Bus
Azure Service Bus has no CLI for message operations.
az servicebusmanages namespaces and queues, but can’t peek a message, replay a dead letter, or search by content. Crucible fixes that.
The problem
If you work with Azure Service Bus, you know the pain:
- Dead-letter queues pile up and you’re clicking through the portal one message at a time
az servicebushas zero message-level commands — you can create a queue but you can’t peek what’s in it- ServiceBusExplorer is Windows-only — if you’re on macOS or Linux, you’re writing throwaway scripts
- No way to search message content — you can peek by sequence number, but you can’t find the message with
OrderId: 12345without writing code - Bulk replay? Not from the portal. Not from the CLI. You write a .NET console app, run it once, delete it.
Every Service Bus team builds the same internal scripts. We built one tool instead.
What Crucible CLI does
# See everything at a glance
$ crucible status
Namespace: sb-prod.servicebus.windows.net
Entity Active DLQ Scheduled
──────────────────────────────────────────────────────────
orders/process-order 142 0 0
orders/notify-warehouse 38 0 2
payments/validate-payment 0 47 0 ← 🔴
payments/process-refund 3 0 0
events/audit-logger 891 0 0
1 entity with dead-lettered messages.
# What's in the dead-letter queue?
$ crucible deadletter payments/validate-payment --reasons
Dead-letter reasons for payments/validate-payment:
Reason Count Oldest
────────────────────────────────────────────────────
MaxDeliveryCountExceeded 31 2h ago
HeaderSizeExceeded 12 18h ago
TTLExpired 4 3d ago
Total: 47 messages
# Find the message you're looking for
$ crucible search payments/validate-payment --dlq --body "INV-2026-0847"
Found 1 message:
Seq: 4892 | Enqueued: 2026-03-21T14:32:01Z | DLQ reason: MaxDeliveryCountExceeded
{
"invoiceId": "INV-2026-0847",
"amount": 1420.00,
"currency": "EUR",
"customerId": "C-9912"
}
# Replay them all — with a backup first
$ crucible replay payments/validate-payment --filter "reason=MaxDeliveryCountExceeded" --backup
Backing up 31 messages to ./crucible-backup-2026-03-22T10-15-00.json
Replaying 31 messages to payments/validate-payment...
████████████████████████████████ 31/31 complete
Done. 31 messages replayed. Backup saved.
# Send a test message
$ crucible send orders/process-order --file test-payload.json --property "env=staging"
Message sent to orders/process-order (seq: 10294)
But wait, there’s more
Live monitoring
crucible monitor gives you a live TUI dashboard — think htop for Service Bus. Real-time counts, color-coded DLQ trends, auto-refreshing every 5 seconds.
$ crucible monitor
┌─ sb-prod.servicebus.windows.net ──────────── refreshing every 5s ─┐
│ Entity Active DLQ Sched Trend │
│ orders/process-order 142 0 0 │
│ orders/notify-warehouse 38 0 2 │
│ payments/validate-payment 0 47 0 ▲ UP │
│ payments/process-refund 3 0 0 │
│ events/audit-logger 891 0 0 │
└───────────────────────────────────────────────────────────────────┘
Namespace topology
See your entire namespace structure — topics, subscriptions, rules — as a tree. Export as Mermaid for documentation.
$ crucible topology
sb-prod.servicebus.windows.net
├── [queue] orders-dlq-parking
├── [topic] orders
│ ├── [sub] process-order
│ │ └── [rule] high-priority (CorrelationFilter)
│ └── [sub] notify-warehouse
│ └── [rule] $Default (TrueFilter)
└── [topic] payments
├── [sub] validate-payment
└── [sub] process-refund
$ crucible topology --format mermaid > topology.md
Drift detection
Snapshot your namespace config, then diff it later — or compare two namespaces side by side (dev vs prod).
$ crucible snapshot --output baseline.json
Snapshot saved: 3 topics, 5 subscriptions, 2 queues, 8 rules
$ crucible diff baseline.json
Changes since 2026-03-20T14:00:00Z:
+ [sub] orders/audit-logger (added)
~ [queue] orders-dlq-parking maxDeliveryCount: 5 → 10
- [rule] payments/validate/legacy (removed)
Export & import
Move messages between environments. Export from DLQ, fix the data, import to another queue.
$ crucible export payments/validate-payment --dlq --format json > failed-payments.json
Exported 47 messages
$ crucible import payments/validate-payment --file failed-payments.json --delay 100ms
Imported 47 messages (4.7s)
Threshold alerts
Watch a queue and trigger a command or desktop notification when DLQ crosses a threshold.
$ crucible watch payments/validate-payment --dlq-threshold 10 --exec "curl -X POST https://hooks.slack.com/..."
Watching payments/validate-payment (poll every 30s, threshold: 10)
Why we built it
We run Power Platform → Azure integrations for clients. Service Bus is the backbone. When a dead-letter queue fills up at 2am, you don’t want to open the Azure portal, navigate to the namespace, find the subscription, click “Peek”, read one message at a time, then write a script to replay them.
You want to type:
crucible deadletter payments/validate-payment --reasons
crucible replay payments/validate-payment --filter "reason=MaxDeliveryCountExceeded"
And be done.
We looked for a tool that does this. Here’s what we found:
| Tool | Peek | Search content | Bulk replay | Live monitor | Topology | Namespace diff | Export/Import | CLI | Cross-platform |
|---|---|---|---|---|---|---|---|---|---|
| Azure Portal | Yes | No | No | No | No | No | No | No | Yes (browser) |
az servicebus | No | No | No | No | No | No | No | Yes | Yes |
| ServiceBusExplorer | Yes | No | Partial | No | No | No | No | No | Windows only |
| Crucible CLI | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
Nothing filled the gap. So we built Crucible.
Getting started
# Install
npm install -g @crucible/cli
# Add your namespace (Entra ID — uses your az login session)
crucible config add prod --namespace sb-prod.servicebus.windows.net
# Or use a connection string
crucible config add dev --connection-string "Endpoint=sb://..."
# You're ready
crucible status
Crucible uses DefaultAzureCredential — it picks up your az login session, environment variables, or managed identity. No connection strings required (but supported if you prefer them).
Want a dashboard instead?
If you prefer a visual interface — or need features like auto-remediation, DLQ trend charts, incident timeline, and audit trail — there’s a self-hosted web dashboard from the same project:
docker run -e SERVICE_BUS_CONNECTION_STRING="..." -p 3000:3000 ghcr.io/broediger/crucible
That’s it. Open localhost:3000. No account, no sign-up. Uses embedded SQLite by default — no database setup needed.
What the dashboard adds over the CLI:
- DLQ trend sparklines across all entities
- Auto-remediation rules (replay/redirect/discard based on conditions — no human needed)
- Interactive flow diagram (topics → subscriptions → rules)
- Incident timeline correlating DLQ spikes with deployments
- Webhook alerting (Slack, Teams, email)
- Audit trail on all destructive operations
The CLI and the dashboard are companions, not competitors. Use the CLI for fast terminal operations, the dashboard for monitoring and team visibility. Or use both — they connect to the same namespaces.
What it’s not
Crucible is not trying to replace Azure Monitor or Datadog. It doesn’t do generic cloud monitoring. It does one thing — Azure Service Bus operations — and does it well.
Open source
Crucible CLI is open source under [MIT/Apache 2.0 — TBD]. The code is on GitHub:
→ github.com/broediger/crucible-cli
Star it, try it, file issues. We’re building this for the teams that are tired of writing the same Service Bus scripts over and over.
What’s next
crucible costs— estimated monthly cost and optimisation suggestions (unused queues, oversized topics)crucible remediate --rules rules.yaml— declarative auto-remediation from a config file (likekubectl applyfor DLQ rules)- Homebrew tap —
brew install cruciblefor macOS/Linux - Standalone binaries — single-file downloads for environments without Node.js
Crucible is built by Rubj IT — a boutique Power Platform and Azure architecture practice. From specification to production.