What the judges should run first

  1. python -m unittest discover -s tests — the full suite, no AWS credentials needed; every stub path is tested and labeled.
  2. python server.py, then open http://127.0.0.1:8000/console — the operator console; submit a gated request and watch it wait as PENDING until a human clicks Approve or Deny.

The problem

Coverage outside business hours usually means one solo operator — or a two-person team — holding real production risk at 2 a.m. The dangerous moment is not a lack of tools; it is a tired human (or an eager AI) running the wrong action with nobody accountable for the yes. BedrockOps is built for that moment: an AI operations agent that is not allowed to act on a gated request until a named human approves it, and that keeps the receipt either way.

What BedrockOps is now

BedrockOps is an open-source (MIT) cloud operations agent built on the official MCP Python SDK — a Streamable HTTP server (protocol 2025-11-25) exposing three tools: system_probe, bedrock_route, and audit_ledger. v2 adds an operator console at /console, served by the same app: type an ops request, see the route decision, watch service status panels for Bedrock / DynamoDB / Lambda, and read the audit history back in the same screen. Every result is badged exactly as it happened — live, stub, or persisted — and the code returns "live": false / persisted: false rather than simulating success when credentials or services are absent.

Two-step approval: the gate is the feature

A destructive or high-spend request does not execute. It becomes a PENDING proposal: no probes run, no model call fires. A human clicks Approve — only then does the routed request execute (bedrock_agent.execute_approved()) — or Deny, which executes nothing. Both outcomes are written to the audit ledger. Approval in BedrockOps deliberately runs a routed Bedrock model call; there is no code path that mutates AWS resources, even after approval. That scope limit is a design decision, stated here on purpose.

Multi-service orchestration, one audit record

A single request can probe Bedrock, DynamoDB, and Lambda in sequence, combine the results, route, and write exactly one orchestration_run audit record for the whole run — orchestration, not a single API call dressed up as one. Probes are read-only and fail closed: an unreachable service reports UNREACHABLE, it never fakes HEALTHY.

Audit history that survives restarts

The ledger is a SHA-256-chained audit trail persisted to a single DynamoDB table (bedrockops-audit-ledger: SessionId String partition key, Timestamp Number sort key, on-demand billing). read_history() reads it back with a DynamoDB Query on that one table — scoped to the operator session, so restarts of the same session see the trail; it never widens to a Scan. When no table or credentials exist, the fallback is labeled source: memory — history that is not persisted is never presented as persisted. Terraform defines exactly this: the table plus a least-privilege IAM policy (PutItem + Query, one table ARN, nothing else). The table itself has been created and verified Active on the owner's account.

Named impact scenario

A solo cloud-ops operator is paged at 02:00 for a degraded service. The request that would "fix it fast" is also the one that could delete the production database. In BedrockOps, that request stops at the gate as a pending proposal; the operator reads the route decision, approves the safe action (or denies the dangerous one), and the approved run completes with its audit record persisted and readable across sessions — a named human accountable for the yes, with the receipt to prove it. No invented users, no testimonials; this is the workflow the tool is built to serve.

Reproducible architecture

Operator ──► /console (web UI) ──► orchestrator.py
                                  gate -> PENDING proposal
                                  Approve -> execute + audit
                                  Deny    -> audit only
MCP client ─► /mcp (official SDK, Streamable HTTP, 2025-11-25)
                                  system_probe / bedrock_route / audit_ledger
Probes (read-only, boto3): Bedrock, DynamoDB, Lambda
Ledger: SHA-256 chain -> DynamoDB PutItem + Query (one table)
infra: terraform/main.tf (table + least-privilege IAM)

One command runs it locally (python server.py); the console is a localhost demo surface with no authentication — documented as such, never to be port-forwarded. 31 automated tests cover the MCP protocol, the approval gate (submit executes nothing), the deny path, stub orchestration, history read-back and its memory fallback, and the console API — all without AWS credentials.

Friction log

What building this actually taught us is in the repo, unedited: FRICTION_LOG.md — eleven real items in Task / Steps / Expected vs Actual / Severity / Workaround / Suggestion format, including the honest headliner below.

Live proof — stated plainly

The tests prove a real official-SDK MCP server with a working approval gate, orchestration, and a DynamoDB write path proven against a fake client. A live Bedrock call, a successful live AWS probe, and a real DynamoDB write are not yet proven: since the owner's account upgraded to a paid plan on October 19, its Bedrock inference quotas have shown an applied value of 0 (a provisioning issue AWS Support is working under case #179183401700335), so no credentialed run has been possible yet. The code says so in every result — live: false / persisted: false — rather than simulating success. The live run remains planned on the owner's account as soon as AWS restores the default quotas.

Built With

Share this project:

Updates

Submission history