Inspiration

An incident commander should not change a service because someone typed "approve." Fleet Commander is the board for that decision. The product on screen is FleetOps. A person declares what happened, reads the suggested fix, and writes why they are approving, rejecting, or overriding it. Nothing runs until that reason is there.

The fleet in this demo is a scenario simulator, not a customer's live metrics, logs, or traces. The board says that on every reply.

What it does

Reset scene opens on three incidents: payment-service, vault-secrets-manager, and ingress-nginx-controller. Simulate chaos degrades the next healthy service in the catalog. A muted service is skipped.

Open is the decision list. Alerts is that same incident with the rule and the suggested action. Fleet is the healthy services, grouped by layer. Declare is on a healthy service: you file the title, the security level, and what happened. Notes, links, and attributes are kept when you add them. The catalog fault stays underneath.

Overview, Timeline, and Dashboard are the three views of one incident. Ask "what's wrong with payments?" in the box, or press Talk about this. The microphone uses the same path. The reply is Situation, Insight, Knowledge, and the token budget. Every turn is kept in the command record.

You can hand FleetOps a repository path or a git URL. It reads that repo and does not install or edit until you approve.

Approve runs the suggested fix and marks the service healthy. Reject leaves it open as triage and keeps your reason. Override picks a different action and target, and nothing runs until Execute. All three stay disabled until the Why field is filled in.

How we built it

The board is a Next.js app. It talks to one FastAPI agent. That agent is also an MCP server on protocol 2025-11-25.

The public MCP tools are read-only:

  • get_fleet
  • get_service_status
  • verify_recovery
  • list_incidents
  • get_timeline
  • get_alert

Declaring an incident, muting a service, and approve, reject, or override stay on the agent routes. The operator chooses a catalog service and files a title, a security level (SEV-1, SEV-2, or SEV-3), and the incident details.

SEV-1 is an error rate at or above 20%, or a critical failure. SEV-2 is at or above 5%. Anything else open is SEV-3. A rising rate is labeled "approaching SEV-2." The dashboard groups the fleet by the simulator's layers.

A discussion reply is split into Situation, Insight, Knowledge, and a token budget capped at 40 model calls. The AWS strip shows the last Bedrock result, whether the CloudWatch log group exists, and the App Runner host.

Challenges we ran into

Amazon Bedrock is the reasoning path. This account returns Error 002, "Access to Bedrock models is not allowed for this account," so InvokeModel is refused. The board still makes the call, and the source stays Scenario fallback. We did not hide that.

Alexa+ partner tools were closed to this hackathon, so the board is the MCP client. Approve and reject are not MCP tools.

Slack and Jira send a notice only when real credentials are configured. They are not configured here, so those notices are idle.

The CloudWatch log group for the hosted agent is /opspilot/traces. That is the group already created in the account. The product name on the board is FleetOps.

Accomplishments that we're proud of

The person owns the change. Approve, reject, and override stay disabled until a Why is written, and that sentence is kept on the incident and on the timeline.

The MCP server speaks protocol 2025-11-25 and stays read-only. Six tools can look at the fleet, the service, the recovery, the incident list, the timeline, and the alert. Declaring, muting, and the decision stay on the agent routes.

The board shows its source. When Amazon Bedrock refuses the call with Error 002, the badge stays Scenario fallback. We still make the InvokeModel call, and we do not replace the refusal with a quieter answer.

Slack and Jira stay quiet unless real credentials are present. They are not present, so the board does not pretend a message was sent.

What we learned

A read-only tool list is easier to trust. The MCP server can look at the fleet, and the person still owns the change. A one-word "approve" is not a decision, so the board keeps the sentence that explains it. When a model call is refused, the useful move is to show the refusal, not to swap in a quieter answer.

What's next for Fleet Commander

Clear Bedrock Error 002 with AWS so InvokeModel can answer. The source badge stays either way: Bedrock when the account allows the call, Scenario fallback when it does not.

Redeploy the agent so the public App Runner URL serves this board. The repository name still says OpsPilot, and that should change before the link goes on this page.

Turn on Slack and Jira only with real workspace credentials. Until those exist, the notices stay idle.

When Alexa+ partner tools are open to this project, the skill should call this same agent. Approve and reject stay off the MCP tool list.

Built With

Share this project:

Updates

posted an update —

Fleet Commander is up.

The board is FleetOps. It reads one service, proposes a recovery, and waits. Approve and Reject stay off until a person writes the reason. Approve runs that action and marks the service healthy. Reject leaves it open as triage and keeps the same sentence. Override picks a different action, and nothing runs until Execute.

This fleet is a scenario simulator. The board says that on every reply. Six tools are read-only: the fleet, one service, recovery, the incident list, the timeline, and the alert. Declare, mute, and the decision stay with the operator.

In this build, Payments is open. The suggested fix is rollback to version 2.0.9. The reason is: "The pool exhaustion started in version 2.1.0, so version 2.0.9 is the last known good release."

We do call Amazon Bedrock. This account returns Error 002: access to Bedrock models is not allowed. InvokeModel is already allowed. The call is still made, and the badge stays Scenario fallback. Slack and Jira send nothing until a real workspace is connected. Alexa+ was closed to this hackathon, so this board is the client.

The code is public under the MIT license: https://github.com/sachidur007/OpsPilot

Next is the same rule on a real fleet, Bedrock answering when the account allows it, and Slack and Jira only as notices after that workspace is connected. Generating a fix will get cheaper. Someone will still have to own the change.

Log in or sign up for Devpost to join the conversation.

posted an update —

OpsPilot – AI Incident Commander

The command center is up. It is a simulated production fleet: 21 healthy services, and three incidents already open.

When something fails, OpsPilot reads the telemetry and recommends the action that matches the failure. Payment service is severity one, connection pool exhausted, rollback. The secrets vault is sealed, unseal. The ingress certificate is expired, rotate it.

The commander stays in the loop. Approve runs the action and moves the service into the healthy fleet. Reject leaves it in triage. Override lets you pick a different action and target. Simulate Chaos breaks the next healthy service, so a new incident shows up the same way. Reset scene restores the opening three.

It also speaks what it found, in my own voice, including incidents that were not in the opening scene.

Still in progress: live model responses are on a fallback while access is sorted out, and the talk button still needs a microphone test.

Log in or sign up for Devpost to join the conversation.

Submission history