Skip to main content
Glama

FixIt MCP

CI License: MIT Container image

A self-hosted MCP server for diagnosing appliance problems, built for the Build, Ship, Shape: Amazon Developer Hackathon (Alexa+ track).

Try it in 5 minutes (no AWS account)

You need Python 3.12 and uv. Nothing else, and no AWS credentials: the local server keeps households in SQLite and reads the committed error-code index.

git clone https://github.com/sadishihab/fixit-mcp.git && cd fixit-mcp
uv sync        # install dependencies
make run       # start the server on http://localhost:8000/mcp; leave it running
make try-it    # in a second terminal

(make quickstart prints these commands.) make try-it starts nothing itself. It connects to the running server over MCP, lists the six tools, and makes four read-only calls for the seeded demo household house-002, which has a GE washer and an LG dryer:

  • diagnose_error for tE1: the LG dryer's code, with its meaning, repair steps and a citation to the manual page.

  • check_warranty for the dryer: the recorded end date and days since it expired. This is a date comparison, not a coverage claim.

  • diagnose_error for IE: the code is documented for an LG washer the household hasn't registered. The answer says so and suggests add_appliance.

  • diagnose_error for ZZ99: a code no manual documents. The result is not_found, with no invented meaning.

With Node.js you can also browse the tools interactively in the MCP Inspector (make inspector, see Inspecting the server).

What needs AWS: the simulated Alexa+ demo UI (make demo) and the grounding eval (make eval), both of which call Claude on Amazon Bedrock; extracting codes from new manuals with FIXIT_EXTRACTOR=bedrock (the default stub extractor needs no AWS, but finds codes only, not their meanings); the agentcore household backend; and building, pushing and deploying to AgentCore Runtime.

Related MCP server: HomeKeeper

Run it with Docker (no AWS account)

If you have Docker but don't want to install Python, run the published image:

docker run --rm -p 8000:8000 ghcr.io/sadishihab/fixit-mcp:latest

The server is then at http://localhost:8000/mcp (MCP over Streamable HTTP). It needs no AWS account, no credentials and no environment variables. Point something at it:

  • MCP Inspector (needs Node.js): npx @modelcontextprotocol/inspector, choose transport Streamable HTTP, and connect to http://localhost:8000/mcp.

  • make try-it, from a clone of this repository (uv sync first): it connects to localhost:8000, lists the six tools and makes four read-only calls for the seeded demo household house-002, exactly as in the section above.

What is in the image. The server, and the two committed indexes it loads at startup: 46 error-code records (five manuals) and 114 troubleshooting rows (the GE refrigerator and washer), plus the manual catalog. Not in it: the manual PDFs (they are never stored in this repository either) or any AWS settings. It runs as a non-root user and listens on 0.0.0.0:8000/mcp. It is built for linux/amd64 and linux/arm64.

Where household data goes. The image uses the SQLite household store, inside the container, and seeds the demo households (house-001, house-002) the first time it starts. Appliances you add are lost when the container is removed, unless you mount a volume:

docker run --rm -p 8000:8000 -v fixit-state:/app/data/state ghcr.io/sadishihab/fixit-mcp:latest

This image is for trying FixIt out, not a production deployment. It has no authentication (any caller that can reach the port can read or change any household), so don't expose it to the internet. For a real deployment see Deploying to AgentCore Runtime and docs/for-manufacturers.md.

The image is published to GitHub Container Registry by .github/workflows/image.yml whenever a version tag (v*) is pushed, never on an ordinary push, and is only published after the workflow has started the image and run the same smoke checks as make docker-smoke against it. Tags are the version (0.3.0, 0.3) and latest.

Overview

FixIt is a self-hosted MCP server (spec 2025-11-25, Streamable HTTP) for home appliance help, built for the Alexa+ track of the Build, Ship, Shape: Amazon Developer Hackathon. It works today: it diagnoses appliance error codes from structured, cited data extracted offline from real manuals (extraction runs on Amazon Bedrock at ingestion time, never inside the live tools); it keeps a household's appliances across sessions in Amazon Bedrock AgentCore Memory; it answers "is it still under warranty?" with a deterministic date comparison; it returns MCP Apps visual cards for error-code diagnoses and for described problems; and it runs on Amazon Bedrock AgentCore Runtime.

Not built: OAuth account linking. The deployed server accepts only AWS-signed (IAM SigV4) requests today, so the real Alexa+ client can't call it yet — also because the Alexa+ developer tools (account linking, the local inspector, add-on submission) are not available to hackathon participants; see FRICTION_LOG.md's Alexa+ tooling access entry. Also not built: parts ordering; maintenance scheduling. The demo client (make demo) is a simulated Alexa+, not the real one, for the same reason. See docs/alexa-plus-requirements.md for the full requirements checklist and CLAUDE.md for the architecture.

Documentation

  • docs/for-manufacturers.md: a guide for a manufacturer, or a developer working for one, who wants to run FixIt on its own manuals: the pipeline, what you own, deploying, the grounding eval, costs, and what is not done yet.

  • docs/architecture.md: the architecture as a diagram, one paragraph per component, and which parts make model calls and which never do.

Tools

Tool

What it does

list_my_appliances

Lists a household's registered appliances.

add_appliance

Registers a new appliance for a household, linking it to a manual on file when one matches.

remove_appliance

Removes an appliance from a household's registry.

diagnose_error

Looks up an appliance error code's meaning, causes, repair steps, parts, and safety warnings, cited to the source manual; has an MCP Apps visual card (ui://fixit-mcp/diagnose-error-card).

diagnose_symptom

Finds a problem the customer describes in their own words (no error code) in the troubleshooting tables of their appliances' manuals and returns the manual's own rows — the problem, possible causes, what it says to do — cited to a page. Keyword matching only, no model call; says not_found rather than guess. Covers the GE refrigerator and washer so far. Has an MCP Apps visual card (ui://fixit-mcp/diagnose-symptom-card).

check_warranty

Reports whether a registered appliance's recorded warranty is active or expired, from a deterministic server-side date comparison — never a coverage claim.

Project status

Works today

  • The MCP server (spec 2025-11-25, also negotiates 2025-03-26) with six tools: appliance registry, error-code diagnosis from real manuals (with a visual card), symptom lookup from the manuals' troubleshooting tables, and a recorded-date warranty check.

  • Offline ingestion of manuals into a committed error-code index, and a one-command way to add a manual (make add-manual). Troubleshooting-table rows for the GE refrigerator and washer go into a second committed index (make extract-symptoms, Amazon Nova only).

  • A container image and a deployment to AgentCore Runtime with household data in AgentCore Memory. The deployed server accepts only AWS-signed (IAM SigV4) requests today — it has no anonymous or OAuth inbound auth.

Simulated

  • The Alexa+ client. The demo (make demo) is a small local backend that plays Alexa+'s role: an MCP client driving an LLM tool-use loop. It is not the real client, because the Alexa+ developer tools (account linking, the local inspector, add-on submission) are not available to hackathon participants — see FRICTION_LOG.md's Alexa+ tooling access entry.

Roadmap

  • OAuth account linking, so real Alexa+ can reach the deployed server — if Alexa+ tooling becomes available.

  • Parts ordering.

  • Maintenance scheduling.

  • More manuals (see CONTRIBUTING.md and docs/good-first-issues/).

Demo video

Watch the demo video: https://youtu.be/EbuSbJQJrXQ

Architecture

FixIt architecture: the client, the MCP server, its in-memory indexes and household memory, and the offline ingestion pipeline

The diagram (Mermaid source and one paragraph per component) is in docs/architecture.md; the sketch below is the same shape in text.

Alexa+ (real client: not connected yet; the demo simulates it)
   |  Streamable HTTP, MCP 2025-11-25 (also negotiates 2025-03-26)
   v
FixIt MCP server  (AgentCore Runtime; `make run` locally)
   |-- error-code index: data/index/error_codes.json, loaded once at startup
   |-- symptom index: data/index/symptoms.json, loaded once at startup
   `-- household appliances: AgentCore Memory (`agentcore` backend), SQLite
       or in-memory for local dev

Offline, never in a request: manual PDFs -> parser -> Bedrock extraction ->
committed error-code index (`make add-manual`); manual PDFs -> table reader ->
Nova extraction + audit -> committed symptom index (`make extract-symptoms`)

The runtime server is a thin, fast lookup layer with no LLM calls in tool handlers: Alexa+ does all language generation from the structured data the tools return. The heavy AI work (parsing and extracting manuals) happens offline, in the ingestion pipeline.

How this meets the Alexa+ track requirements

  • MCP SDK import and server entry point: src/fixit_mcp/server.py imports from mcp.server.fastmcp import FastMCP and defines create_server() / main(). src/fixit_mcp/tools/appliances.py also imports FastMCP (for type hints) and registers the tool via @mcp.tool(...). src/fixit_mcp/__main__.py is the process entry point (python -m fixit_mcp).

  • Protocol version: pinned to mcp>=1.30,<2, whose LATEST_PROTOCOL_VERSION is 2025-11-25 and which correctly negotiates the 2025-03-26 version the Alexa+ client sends (verified in tests/integration/).

  • Transport: Streamable HTTP, stateless mode, served at 0.0.0.0:8000/mcp — matching both the Alexa+ Toolkit's requirements and Amazon Bedrock AgentCore Runtime's container contract (the image is deployed there today).

  • Latency: no LLM calls in any tool handler; tests/integration/test_latency.py asserts p95 < 100ms locally over 50 calls. On the deployed AgentCore Runtime, the measured warm p50 was about 572 ms from Dhaka, of which about 320 ms is network to us-east-1. The in-region figure of roughly 200-250 ms is an estimate, not a measurement, so the 500ms Alexa+ budget is not yet confirmed from inside the region. Cold sessions (a brand-new session) take about 5 seconds and are a known limitation; see FRICTION_LOG.md's "Cold-start latency: known limitation" entry.

  • Full requirement-by-requirement checklist: docs/alexa-plus-requirements.md.

Quickstart

Requires uv and Python 3.12.

git clone <this-repo>
cd fixit-mcp
uv sync
cp .env.example .env   # optional, defaults work as-is
make run                # starts the server on http://0.0.0.0:8000/mcp

Inspecting the server

make inspector

This starts the MCP Inspector (requires Node.js/npm). In the browser UI it opens, choose transport "Streamable HTTP" and connect to http://localhost:8000/mcp.

Exposing it remotely (for testing with Alexa+)

Alexa+ requires a remote HTTPS URL. For local development/demos, use a cloudflared quick tunnel:

# Install cloudflared first, e.g.:
#   macOS:   brew install cloudflared
#   Linux:   see https://pkg.cloudflare.com/index.html
make tunnel

This prints a temporary https://*.trycloudflare.com URL that proxies to your local server.

Running in Docker (AgentCore Runtime image)

The Dockerfile builds the image Amazon Bedrock AgentCore Runtime will run: linux/arm64, non-root (UID 1000), prod dependencies only, serving 0.0.0.0:8000/mcp in stateless mode, the same defaults as make run, so nothing is overridden. It's about 76 MB compressed and about 235 MB unpacked (boto3 is included for the agentcore backend).

# x86_64 hosts only, once per boot: register QEMU so arm64 images can build/run.
docker run --privileged --rm tonistiigi/binfmt --install arm64

make docker-build   # docker buildx build --platform linux/arm64 -t fixit-mcp:latest --load .
make docker-run     # serves http://localhost:8000/mcp; SQLite state in the `fixit-mcp-state` volume
make docker-smoke   # in another terminal: end-to-end MCP checks against the running container

make docker-smoke runs scripts/smoke_test.py, which covers both protocol versions, every tool, both MCP Apps cards, and a foreign Mcp-Session-Id header. On an x86_64 host it skips the latency check, because QEMU emulation makes each call about 10x slower than native. Set DOCKER_PLATFORM=linux/amd64 for a native local build if you need real latency numbers. The container tests are opt-in: FIXIT_DOCKER_TESTS=1 uv run pytest tests/integration/test_container.py.

Household data in AgentCore Memory (agentcore backend)

On AgentCore Runtime, local disk belongs to a single session, so household appliances are stored in Amazon Bedrock AgentCore Memory instead (FIXIT_REPOSITORY_BACKEND=agentcore). Each household is an actor, and each appliance is one event under a fixed appliance-registry session. See src/fixit_mcp/repository/agentcore_memory.py for the storage model, and FRICTION_LOG.md (step 4b) for why events rather than long-term records. Events expire after at most 365 days.

One-time setup (region us-east-1):

  1. Create the memory resource: Amazon Bedrock AgentCore → Memory → Create memory. Name it FixItHouseholds, set event expiry to 365 days (the maximum), and add no strategies, since this is short-term memory only and no LLM extraction should run. Wait for status ACTIVE, then copy the memory ID (e.g. FixItHouseholds-a1B2c3D4e5, not the ARN).

  2. Grant the identity that runs the server (your local IAM user now, the AgentCore Runtime execution role later) exactly these three actions on that one memory:

    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "FixItHouseholdAppliances",
        "Effect": "Allow",
        "Action": ["bedrock-agentcore:CreateEvent", "bedrock-agentcore:ListEvents", "bedrock-agentcore:DeleteEvent"],
        "Resource": "arn:aws:bedrock-agentcore:us-east-1:<ACCOUNT_ID>:memory/<MEMORY_ID>"
      }]
    }

    Creating the memory (step 1) additionally needs bedrock-agentcore:CreateMemory / GetMemory / ListMemories for whoever does it. Those are one-time setup permissions that the server itself never needs. No VPC is needed: the data plane is a public regional endpoint.

  3. Seed the demo households and verify:

    export FIXIT_AGENTCORE_MEMORY_ID=<MEMORY_ID>
    make seed-agentcore           # idempotent; RESET=1 clears demo-household rehearsal data first
    FIXIT_AGENTCORE_TESTS=1 uv run pytest tests/integration/test_agentcore_memory_live.py -v -s
    FIXIT_REPOSITORY_BACKEND=agentcore make run      # or: make docker-run-agentcore

The backend never seeds at runtime. A household with no events is simply empty. make seed-agentcore is the only way the demo households get into AgentCore Memory.

Deploying to AgentCore Runtime

The direct path (no CDK and no AgentCore CLI; see FRICTION_LOG.md, step 4c):

  1. Push the already-tested local image to ECR, unchanged.

  2. Create or update the runtime with CreateAgentRuntime, pinned to that image's digest.

The runtime runs with the agentcore backend and IAM (SigV4) inbound auth. Alexa+ can't call it — that needs OAuth/JWT, which isn't applicable to this submission since the Alexa+ developer tools aren't available to hackathon participants (see FRICTION_LOG.md's Alexa+ tooling access entry).

🛑 Stop paying for it: make teardown-runtime

This deletes the runtime, its endpoint, and every session, which stops all Runtime compute charges. It's safe to re-run. make teardown-runtime-all also deletes the fixit-mcp ECR repository and its images (~$0.01/month). Neither touches the AgentCore Memory resource (household data) or the IAM role and policies. Delete those in the console if you want them gone.

One-time IAM setup: make iam-policies renders deploy/iam/*.json with your account's values into build/iam/ (gitignored). The deployer policy must be a customer managed policy, because it exceeds the 2,048-character limit for inline user policies. deploy/iam/README.md says which file attaches where.

export FIXIT_AGENTCORE_MEMORY_ID=<MEMORY_ID>
make docker-build        # if not already built and tested
make docker-push         # push that exact image (no rebuild) -> ECR fixit-mcp
make deploy-runtime      # create or update the runtime; prints its ARN (idempotent)
make runtime-smoke   RUNTIME_ARN=<arn>   # scripts/smoke_test.py, SigV4-signed
make runtime-latency RUNTIME_ARN=<arn>   # cold vs warm latency, with the Runtime overhead split out

Monitoring the deployed runtime (CloudWatch)

make observability (scripts/observability.py, step 23c) sets up a small, idempotent CloudWatch view of the deployed server:

  • four metric filters on the runtime's log group, built from the server's own JSON log lines, publishing to namespace FixIt: ToolLatency (per tool), ToolLatencyAll, ToolCallFailed and MemoryCallFailed;

  • 90-day retention on that log group (it never expired before);

  • dashboard FixIt: runtime invocations, errors and latency, per-tool handler latency, failed tool and Memory calls, and AgentCore Memory latency and errors;

  • alarms fixit-errors (runtime SystemErrors + failed tool calls + failed Memory calls, at least 1 in 5 minutes) and fixit-tool-latency (handler p95 over 300 ms in 2 of 3 five-minute periods), both emailing SNS topic fixit-alerts.

make observability DRY_RUN=1                 # print the plan; no AWS call
export FIXIT_AGENTCORE_MEMORY_ID=<MEMORY_ID>
export FIXIT_ALERT_EMAIL=<your address>      # never committed
make observability                           # create or update; confirm the SNS email
make observability-teardown                  # delete it all (keeps the 90-day retention)

It needs the FixItObservability customer managed policy (deploy/iam/observability-policy.json). It should cost about $0 a month, within CloudWatch's free tier (8 custom metrics, 1 dashboard, 2 alarms). Limitation: this is a server-side view. A 504 Gateway Time-out from AgentCore's front door for a request that never reached the container leaves no log line of ours and isn't documented as a runtime SystemError, so the dashboard may not show it (see FRICTION_LOG.md, step 23c).

State persistence caveat (default sqlite backend). The SQLite household store lives at /app/data/state/appliances.db inside the container. Locally, make docker-run mounts a named volume there so data survives docker rm. AgentCore Runtime has no such volume by default. Every new session runs in a fresh microVM created from the image, so appliances added in one Alexa+ conversation are gone in the next. Deploy with the agentcore backend (above) instead, which keeps household data outside the container.

Simulated Alexa+ demo

There's no real Alexa+ integration — the Alexa+ developer tools aren't available to hackathon participants (see the OAuth row in docs/alexa-plus-requirements.md and FRICTION_LOG.md's Alexa+ tooling access entry). Instead, demo/ is a local FastAPI backend that plays Alexa+'s role -- a real MCP client driving a tool-use LLM loop against this server, including the MCP Apps card -- so the tool-calling behavior can be exercised and demoed. It has a small single-page web UI, and every response is clearly labeled "simulated_alexa_plus": true.

make demo                                          # against the local dev server
make demo AGENT_ARN=<deployed runtime ARN>          # against a deployed AgentCore Runtime

Replies are spoken with the browser's own voice. Set FIXIT_DEMO_POLLY=1 to use Amazon Polly (generative engine, voice Matthew) instead, with the browser voice as the fallback; it is off by default, caches audio by text, and stops at 50,000 characters per run. This is demo-only and the server itself never calls Polly. See demo/README.md.

Add a manual

One command takes a manufacturer manual from a URL to validated, cited records in data/index/error_codes.json:

make add-manual ID=acme-x100-oven BRAND=Acme MODEL=X100 TYPE=oven \
  URL=https://example.com/x100.pdf NOTE="Public support page, free download, no login"
make add-manual ... DRY_RUN=1   # verify the PDF and its content, change nothing
make validate-manifest          # check the manifest is consistent

See CONTRIBUTING.md for what makes a good source and the terms-of-use rule. A new manual only reaches the deployed server after an image rebuild and runtime update.

Data and sources

The error-code records in data/index/error_codes.json and the symptom rows in data/index/symptoms.json are factual, cited extractions from manufacturers' publicly downloadable manuals: each record names its manual and page. Every source is linked in data/manuals/manifest.yaml, with a note on where the URL came from. The manual PDFs themselves are not stored in this repository, and the records do not reproduce manual text.

All trademarks belong to their owners. This project is not affiliated with or endorsed by any manufacturer. A manufacturer that wants its records removed can ask, and the maintainer will remove them.

How we measure grounding

The server never generates language; the assistant does, from the structured tool results. To check that the assistant says only what those results say, make eval runs about 70 scripted conversations (found and unknown codes, described problems, safety questions, warranty questions, and adversarial follow-ups like "how much will the repair cost?" or "is it dangerous?") through the demo against the local server. Each reply is checked deterministically (right tool, right arguments, required or forbidden phrases) and by a second model acting as judge, which lists any claim the tool results do not support. The judge can be wrong, and it cannot catch a claim that merely sounds supported; see CONTRIBUTING.md for details and limits.

Running tests

make test    # pytest: unit + integration (spins up a real local server)
make lint    # ruff check
make format  # ruff format

Test suite:

  • tests/unit/test_repository.py — in-memory repository behavior.

  • tests/integration/test_server_protocol.py — negotiates MCP 2025-11-25 and calls list_my_appliances over real Streamable HTTP.

  • tests/integration/test_server_legacy_protocol.py — negotiates the 2025-03-26 protocol version the Alexa+ client sends and confirms tool calls still work.

  • tests/integration/test_latency.py — 50 tool calls per tool, asserts p95 < 100ms.

  • tests/unit/test_warranty_tool.py / tests/integration/test_check_warranty.py — check_warranty's date resolution (active/expired/unknown/ambiguous/not_found, the ends-today boundary, appliance_id precedence) and its real Streamable HTTP wiring.

  • tests/unit/test_add_manual.py / tests/unit/test_manifest_validation.py — the add-a-manual script (duplicates, wrong-content PDFs, dry run, idempotent merge; synthetic PDFs, mocked HTTP) and the manifest validator, which also checks the real manifest.

  • tests/unit/test_symptom_ingestion.py — the symptom table reader (a synthetic ruled-table PDF), span-level font repair, the verbatim audit gate, the Nova extractor's retry and spending cap with a fake Bedrock client, and the record builder.

  • tests/unit/test_retrieval_symptoms.py / tests/unit/test_symptom_tool.py / tests/integration/test_diagnose_symptom.py — the symptom index loader, the matcher (paraphrases that must match, off-topic descriptions that must not, a description matching two manuals), diagnose_symptom's resolution (found, ambiguous_appliance, unregistered appliance, not_found) and its real Streamable HTTP wiring, on invented data only.

  • tests/unit/test_run_eval.py — the grounding eval runner (case loading, seeding and cleanup, deterministic checks, judge parsing and retry, cost, summary) with fakes.

  • tests/unit/test_try_it.py / tests/integration/test_try_it_script.py — the no-AWS walkthrough (make try-it): its formatting with fakes, and the full run against the dev server.

  • tests/integration/test_smoke_script.py — keeps scripts/smoke_test.py (the container/deployment smoke checks) passing against the dev server.

  • tests/unit/test_observability.py — scripts/observability.py's plan (names inside the IAM policy's scoping, dimensions, alarms, dashboard), idempotent apply and teardown, and a dry run that makes no AWS call, all with fakes.

  • tests/unit/test_dockerfile.py — guards the Dockerfile's contract (startup data files copied in, editable install, non-root, port 8000).

  • tests/integration/test_container.py — opt-in (FIXIT_DOCKER_TESTS=1): runs the real image and checks the smoke suite plus state persistence. Its two agentcore tests also need FIXIT_AGENTCORE_TESTS=1.

  • tests/unit/test_agentcore_memory_repository.py — the agentcore backend against a fake AgentCore Memory client (no AWS).

  • tests/integration/test_agentcore_backend_server.py — the full smoke suite over real Streamable HTTP on the agentcore backend, with only AWS faked.

  • tests/integration/test_agentcore_memory_live.py — opt-in (FIXIT_AGENTCORE_TESTS=1): real AgentCore Memory, including measured per-operation and per-tool latency.

AWS services used

  • Amazon Bedrock AgentCore Memory: household appliance storage at runtime, when FIXIT_REPOSITORY_BACKEND=agentcore. Short-term events only, with no LLM extraction strategies.

  • Amazon Bedrock (Claude): offline error-code extraction from manuals (FIXIT_EXTRACTOR=bedrock), never at request time.

  • Amazon Polly (optional, demo only): spoken replies in the simulated Alexa+ (FIXIT_DEMO_POLLY=1), never in the server.

  • Amazon Bedrock AgentCore Runtime: hosts the server (IAM inbound auth only for now).

Open-source components

License

MIT — see LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that lets LLMs control Amazon Alexa devices, including announcements, text commands, smart-home group management, routines, and list operations.
    18
    4
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Enables MCP-compatible LLMs to control Amazon Alexa devices by sending announcements, text commands, and SSML speech, as well as managing smart-home groups, routines, lists, volume, Do Not Disturb, and sensor queries.
    19
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that enables Alexa+ to autonomously orchestrate multi-step household tasks by decomposing goals into parallel tool calls — cross-session memory and dietary/allergy auditing, culinary planning with wine pairings, Amazon Fresh cart assembly with human-in-the-loop purchase approval, smart-home ambiance and climate control, and calendar scheduling. It pairs AWS Bedrock multi-agent reasoning with Streamable HTTP transport and interactive generative UI cards, carousels, and live IoT sliders.
    MIT