Skip to main content
Glama

FixTrail

A neutral, tamper-evident repair record for renters and landlords, reported by voice.

FixTrail is an MCP server for the Alexa+ track of the Amazon Developer Hackathon. A tenant says "Alexa, the heater stopped working", FixTrail emails the landlord immediately, and every event goes into a shared, append-only record that neither side, and not even FixTrail itself, can quietly rewrite.

The Alexa+ simulator calling FixTrail's MCP tools

Track / challenge

What FixTrail provides

Alexa+

An MCP server over Streamable HTTP (spec 2025-11-25) with 10 tools, an Agent Skill, and an Alexa+ simulator web app

AWS Builder

Amazon Bedrock + the Strands Agents SDK power the simulator; Amazon SES, S3, and SNS handle email and photos (AWS.md)


The problem

When something breaks in a rental home, disputes follow: "I reported this five times" versus "I was never told." Housing inspectors, mediators, and courts need dated, trustworthy records, and usually nobody has them. A tenant's private notes are weak evidence because anyone can write anything. A useful record has to be fair to both sides and hard to fake.

Related MCP server: Property MCP Server

How it works

  1. The tenant speaks. "The kitchen sink is leaking." The assistant calls FixTrail's report_issue tool.

  2. The landlord is notified at once, by email, with a private link to respond: acknowledge, schedule a repair, mark it fixed, or say they couldn't get in.

  3. Both sides add to one shared timeline. The tenant can add photos (upload them, or simply reply to a FixTrail email with photos attached) and say "I called my landlord", "remind my landlord", or "the sink is fixed".

  4. Anyone can produce a dated report with response times, such as "Landlord first responded after 2 days" or "No landlord response in 12 days".

 Tenant's voice
      |
 Alexa+ (or the Alexa+ simulator: Strands agent + Bedrock + FixTrail Agent Skill)
      |  MCP over Streamable HTTP
      v
 FixTrail server (Python, FastAPI)
      |-- 10 MCP tools at /mcp
      |-- web pages: tenant timeline, landlord responses, photos, reports, /verify
      |-- append-only, hash-chained event log (SQLite with triggers)
      |-- email out: local .eml files, or Amazon SES  (every email carries the record's fingerprint)
      |-- photos: local folder, or Amazon S3
      |-- photo replies by email: local inbox/ folder, or SES receiving -> S3 -> SNS -> /inbound/ses

How FixTrail earns trust

Honest labels. Every event is marked Verified only if FixTrail itself saw it happen (it received the report or photo, sent the email, or recorded the landlord's click). Things it can't see, like phone calls or a visit where nobody answered, are labeled Tenant-reported or Landlord-reported.

An append-only hash chain. Each event's fingerprint (SHA-256) is computed from its contents plus the previous event's fingerprint. Database triggers block edits and deletes, server time is used for every timestamp, and /verify recomputes the whole chain.

Witnesses outside FixTrail. A hash chain alone can be rewritten by whoever runs the server. So every email ends with the record's fingerprint at that moment. Those emails sit in the tenant's and landlord's inboxes, where FixTrail can't change them. If history is rewritten, old fingerprints stop matching:

The operator rewrites history and recomputes every hash: /verify still says "Record intact"...

...but a fingerprint from an old email exposes it

Record intact

No match

scripts/tamper_demo.py performs exactly this attack (with a backup and --restore) for the demo.

Screenshots

Tenant dashboard

Issue timeline with labels and an emailed photo

Dashboard

Timeline

Landlord response page (no login, private link)

Printable repair report

Landlord page

Report

Screenshots use the clearly bannered demo data from scripts/seed.py --demo.

MCP tools

Tool

Tenant says something like

What happens

report_issue

"The kitchen sink is leaking."

Logs the issue, emails the landlord, emails the tenant a reply-with-photos address

list_open_issues

"What's still broken?"

Days open and the landlord's latest response for each issue

get_issue_history

"What happened with the heater?"

Spoken summary of one issue's timeline

send_follow_up

"Remind my landlord about the heater."

Reminder email, logged as verified

log_contact_attempt

"I called my landlord about the sink."

Logged as tenant-reported (unverified)

confirm_fixed

"The sink is fixed."

Closes the issue and tells the landlord

dispute_fix

"The heater still isn't working."

Records the dispute and tells the landlord

get_photo_upload_link

"How do I add photos?"

Emails the tenant: reply with photos, or use the upload link

generate_report

"Make my repair report."

Printable dated report; the tenant is emailed the link

ping

"Is FixTrail working?"

Health check

Users say "the heater", not an ID, so FixTrail matches everyday words (and typos) to the right issue and asks a short question when it's ambiguous. Every reply is one or two speakable sentences, and tools answer in a few hundred milliseconds (Alexa+ requires under 500 ms), with emails sent in the background.

Agent Skill: skills/fixtrail/SKILL.md follows the Agent Skills specification and passes its reference validator. It teaches any agent which tool fits what the tenant said, how to answer by voice, and the honesty rules (never present an unverified claim as proven; no legal advice).

Alexa+ simulator (/simulator): speak (browser speech recognition, best in Chrome or Edge) or type. A Strands agent connects to FixTrail's /mcp exactly as Alexa+ would, and the transcript shows which MCP tool was called. SIMULATOR_MODE=bedrock uses an Amazon Bedrock model with the Agent Skill as instructions; offline (the default) uses keyword rules with the same agent loop and real MCP calls, so it works without an AWS account.


Run it locally

Requires Python 3.10 or newer (tested with 3.12) and Git. No AWS account needed.

Windows (PowerShell)

git clone https://github.com/himani-png/fixtrail.git
cd fixtrail
python -m venv .venv
.venv\Scripts\python -m pip install -r requirements.txt
copy .env.example .env
.venv\Scripts\python scripts\seed.py --demo
.venv\Scripts\python -m uvicorn app.main:app --reload

macOS / Linux

git clone https://github.com/himani-png/fixtrail.git
cd fixtrail
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
cp .env.example .env
.venv/bin/python scripts/seed.py --demo
.venv/bin/python -m uvicorn app.main:app --reload

Then open:

Address

What it is

http://localhost:8000

Tenant dashboard (passcode change-me, set in .env)

http://localhost:8000/simulator

Alexa+ simulator: click the microphone or an example phrase

http://localhost:8000/verify

Check the record, or paste a fingerprint from an email in outbox/

http://localhost:8000/mcp

The MCP endpoint, for MCP Inspector or any MCP client

Leave out --demo to start with an empty record. Emails are saved as .eml files in outbox/; open one and its /respond/... link to act as the landlord.

Try the scripts

Run these in a second terminal while the server is running (use .venv/bin/python on macOS/Linux):

.venv\Scripts\python scripts\try_it.py            # a voice scenario over MCP, like Alexa+ would run it
.venv\Scripts\python scripts\make_test_reply.py   # a tenant replies to an email with a photo...
.venv\Scripts\python scripts\ingest_email.py      # ...and FixTrail checks and adds it
.venv\Scripts\python scripts\tamper_demo.py --yes # rewrite history; then paste the printed fingerprint at /verify
.venv\Scripts\python scripts\tamper_demo.py --restore

Connect MCP Inspector

npx @modelcontextprotocol/inspector --transport http --server-url http://localhost:8000/mcp

Run the tests

.venv\Scripts\python -m pytest -q

120 tests cover the hash chain and tamper detection, every tool (including real MCP calls), the web pages, photo replies by email, the simulator's full agent loop over HTTP, the demo tools, and the AWS integrations (with botocore's Stubber, so no AWS account is needed).

Configuration

All settings live in .env (copied from .env.example, never committed).

Setting

Default

Purpose

BASE_URL

http://localhost:8000

Public address used in email links; its host is allowed by the MCP endpoint

TENANT_PASSCODE

change-me

Protects the tenant pages

PROPERTY_ADDRESS, TENANT_*, LANDLORD_*

example values

The demo property and people

SIMULATOR_MODE

offline

bedrock to use an Amazon Bedrock model

BEDROCK_MODEL_ID

us.amazon.nova-lite-v1:0

Bedrock model for the simulator

MAILER

console

ses to send real email with Amazon SES (SES_FROM_EMAIL required)

PHOTO_STORE

local

s3 to store photos in Amazon S3 (S3_BUCKET required)

INBOUND_EMAIL_DOMAIN

fixtrail.example.com

Domain for photos+<token>@... reply addresses

INBOUND_SECRET, INBOUND_SNS_TOPIC_ARN, INBOUND_S3_BUCKET

empty

Real photo replies through SES receiving

ALLOWED_HOSTS

empty

Extra public host names for the MCP endpoint (for example a tunnel)

Deploying

docker build -t fixtrail .
docker run -p 8000:8000 -v fixtrail-data:/data --env-file .env fixtrail

The image runs as a non-root user, keeps all data in /data (mount a volume), and has a health check. See docs/AWS.md for the AWS setup: Bedrock, SES sending and receiving, S3, SNS, least-privilege permissions, and hosting on a small instance with a persistent disk.

Project structure

app/
  main.py           FastAPI app; MCP mounted at /mcp; security headers
  mcp_tools.py      the 10 MCP tools (thin wrappers)
  services.py       what each action does; shared by tools and web pages
  db.py             schema, append_event, verify_chain, check_fingerprint
  models.py         status from events, issue matching, wording
  web.py            web pages, simulator API, /inbound/ses
  simulator.py      Alexa+ simulator agent (Strands; Bedrock or offline model)
  inbound_email.py  photo replies: address, sender, verdict, and image checks
  mailer.py         ConsoleMailer and SESMailer
  photos.py         LocalPhotoStore and S3PhotoStore
  reports.py        report statistics, computed only from the event log
  demo.py           clearly marked demo data with simulated dates
skills/fixtrail/SKILL.md   the Agent Skill
scripts/            seed, try_it, make_test_reply, ingest_email, tamper_demo
tests/              120 tests
docs/               AWS, design review, friction log, product feedback, build plan, screenshots

Limitations and responsible use

  • FixTrail is a record-keeping tool, not legal advice. Tenant laws and notice requirements vary by place, and some leases or laws require specific methods such as certified mail. Whether records are accepted as evidence is up to the relevant court or agency.

  • It proves notice and documents what happened; it can't force repairs. Its value is the evidence a tenant (or a fair landlord) can bring to an inspector, mediator, or court.

  • An email sent is not an email read, and messages from an unfamiliar sender can land in spam.

  • Unverified claims stay unverified: calls, texts, and visits FixTrail didn't witness are labeled as such.

  • Email fingerprints protect against rewriting history only if the parties keep their emails.

  • Hackathon scope: one property, one tenant passcode, unguessable landlord links, an in-memory login limit, and SNS messages checked by secret and topic rather than signature. A real service would need accounts, multi-property support, export, and stronger security and privacy controls (see the /privacy and /terms pages in the app).

  • The Alexa+ simulator stands in for Alexa+ because the Alexa+ MCP Toolkit isn't available to participants. It uses the same MCP endpoint, so a real Alexa+ connection needs no server changes beyond the add-on setup.

  • Demo data uses simulated dates and is bannered on every page and report. Real records always use server time.

More documents

  • Design review: strengths, weaknesses, and answers to likely judge questions

  • AWS: every AWS service used, and how to set it up

  • Friction log: every confusing or broken step, with suggestions

  • Product feedback: feedback on each tool, plus feature requests

  • Build plan: the phase-by-phase plan this was built from

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables renters to cross-examine their rent ledger against their lease using deterministic tools, uncovering discrepancies in charges, fees, and rent amounts.
    15
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to operate property management systems via natural language, covering repair orders, owner info, payments, notices, and inspections. Features a full agentic workflow with human-in-the-loop and observability.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables voice-first household maintenance tracking, turning spoken updates into durable records, service history, and due-date reminders for a concise maintenance brief.
    MIT