What the judges should run first
python -m unittest discover -s tests— the full suite, no AWS credentials needed; every stub path is tested and labeled.python server.py, then openhttp://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.
Log in or sign up for Devpost to join the conversation.