mcp-server-custody
Custody
Tell it once. Find it later. Know who has it.
Custody is a voice-first shared object memory for Alexa+. It helps households remember where an item was last reported, identify who currently has a shared item, correct stale records naturally, and guide a user through a short search when the item is not where expected.
This repository is planned as both:
a self-hosted Model Context Protocol server named
mcp-server-custody, served over Streamable HTTP; anda portable Agent Skill that teaches a compatible agent how to use Custody's tools safely and respond in a concise, voice-native style.
Custody is being designed for the Alexa+ track of Amazon's Build, Ship, Shape developer hackathon.
Development status
Transport scaffold implemented. The FastAPI host, Streamable HTTP MCP endpoint, health check, and six typed stub tools are in place. Database-backed behavior begins in Milestone 2.
Naming
Purpose | Name |
Product | Custody |
Recommended repository |
|
MCP server identity |
|
Python package |
|
Agent Skill name |
|
Public MCP endpoint |
|
Health endpoint |
|
The repository name includes both Alexa and MCP so that “Custody” is not mistaken for a legal, child-custody, or evidence-management project.
GitHub repository description
Voice-first shared object memory for Alexa+: a Streamable HTTP MCP server and Agent Skill for locating items, correcting stale records, Lost Mode, shared custody, and privacy-aware access.
Suggested repository topics:
alexa-plus · mcp · model-context-protocol · agent-skills · fastapi · python · voice-ai · accessibility · hackathon
The problem
Most object-location tools assume that a user can visually scan a room, open an app, or maintain a perfectly accurate inventory. That breaks down for:
blind and low-vision users;
people who benefit from reduced working-memory demands;
older adults and caregivers;
families sharing keys, tools, documents, remotes, and other objects; and
workshops or small teams lending shared equipment.
The hard problem is not merely storing item = location. Real households produce incomplete, stale, and conflicting information. Custody therefore treats every location as a reported event with provenance, not as an unquestionable fact.
Product promise
Custody should answer four practical questions:
Where was this item last reported?
Who reported or moved it, and when?
Who currently has it if it was borrowed?
What should I check next if the recorded location is stale?
It must never pretend to physically track an object that it cannot sense.
Voice-native interaction
Remember an item
User: “Remember that my keys are on the hallway console.”
Custody: “Got it. Your keys are on the hallway console.”
Retrieve an item
User: “Where are my keys?”
Custody: “You last reported them on the hallway console this morning.”
Correct a stale record
User: “They weren’t there. I found them in my work bag.”
Custody: “Got it. I’ll remember that your keys are now in your work bag.”
Check out a shared item
User: “I’m taking the drill.”
Custody: “Okay. I’ve recorded that you have the drill.”
Later, another authorized household member asks:
User: “Where is the drill?”
Custody: “Michael checked out the drill at 2:30 this afternoon.”
Start Lost Mode
User: “The keys aren’t there. Help me find them.”
Custody: “Let’s look together. First, check your work backpack. Say ‘next’ if they aren’t there.”
Product principles
Reported, not guaranteed. Say “last reported” or “you last said,” never “definitely located.”
Short speech. Default spoken responses should contain no more than 25 words.
One step at a time. Lost Mode gives one search instruction, not a spoken list.
Self-healing state. Natural corrections append new events and update current state.
Privacy before convenience. Authorization is checked before existence or location is revealed.
Deterministic truth. The database owns item state. An LLM may interpret language but must not invent location facts.
Auditable history. Placement, movement, checkout, check-in, correction, and missing-item actions are stored as events.
Explicit destructive confirmation. Forgetting an item requires confirmation and permanently removes its associated records.
MVP scope
The MVP contains five user capabilities delivered through six MCP tools.
Capability | Outcome |
Remember and locate | Save an item event and retrieve the latest authorized state |
Natural correction | Update stale state using conversational corrections |
Lost Mode | Search previous or configured locations one step at a time |
Shared custody | Check items out and back in, with holder attribution |
Privacy controls | Mark items private, shared, or restricted and delete them permanently |
MCP tool surface
All tools are exposed through the single Streamable HTTP MCP endpoint at /mcp.
Tool | Type | Purpose |
| Write | Record placement, movement, correction, found, missing, checkout, or check-in events |
| Read | Return the latest authorized location or custody state with provenance |
| Write/read | Create a guided search session and return the first step |
| Write/read | Record a search result and return the next step or close the session |
| Write | Set private, household-shared, or restricted access |
| Destructive write | Permanently remove an item and its associated history after confirmation |
Shared tool response
Every tool returns structured data plus a short speech field intended for the voice response.
{
"status": "ok",
"speech": "You last reported the keys in your work bag this morning.",
"item_id": "item_01J...",
"confirmation_required": false,
"next_action": null,
"data": {
"location": "work bag",
"reported_by": "Favour",
"reported_at": "2026-09-06T08:15:00Z"
}
}The Agent Skill should normally speak only the speech value. Structured fields exist for the agent, simulator, tests, and optional visual presentation.
Tool contracts
record_item_event
Records an immutable event and atomically updates the item's current state.
Planned inputs:
Field | Type | Required | Notes |
| string | Yes | Natural name used by the speaker |
| enum | Yes |
|
| string | Demo only | Derived from authentication in production |
| string/null | Conditional | Required for |
| string/null | Conditional | Used for checkout; defaults to current actor |
| datetime/null | No | Server time is used when omitted |
| string/null | No | Supports idempotency on retried writes |
Important behavior:
Append history instead of overwriting the previous event.
Normalize the item name and resolve authorized aliases.
Do not expose private-item matches during entity resolution.
Require a location for location-changing events.
Clear custody on a valid check-in.
Return a short confirmation suitable for speech.
locate_item
Returns the most recent authorized state without claiming physical certainty.
Planned inputs:
Field | Type | Required | Notes |
| string | Yes | May be a canonical name or known alias |
| string | Demo only | Derived from authentication in production |
Priority rules:
Enforce access before returning or acknowledging the item.
If checked out, return the current holder and checkout time.
Otherwise, return the last reported location, reporter, and timestamp.
If marked missing, say so and offer Lost Mode.
If no authorized match exists, return the same neutral result used for a nonexistent item.
start_lost_mode
Creates a search session and returns exactly one search step.
Planned inputs:
Field | Type | Required |
| string | Yes |
| string | Demo only |
Candidate search locations are drawn from:
the item's most recent distinct location events;
user-confirmed search locations for that item; and
safe, deterministic category defaults when explicitly configured.
The service must not invent locations from unrelated household activity.
continue_lost_mode
Advances or closes an active Lost Mode session.
Planned inputs:
Field | Type | Required | Notes |
| string | Yes | Returned by |
| enum | Yes |
|
| string | Demo only | Must own or be authorized for the session |
| string/null | Conditional | Required when result is |
When the item is found, the service records a found event, updates current state, and closes the session.
set_item_access
Changes who may discover and retrieve an item.
Planned inputs:
Field | Type | Required | Notes |
| string | Yes | Owner-authorized item |
| string | Demo only | Must be the owner or an authorized administrator |
| enum | Yes |
|
| list[string]/null | Conditional | Used for |
Unauthorized requests receive a neutral not-found response so the server does not reveal that a private item exists.
forget_item
Permanently removes the item, aliases, events, permissions, custody state, and Lost Mode sessions.
Planned inputs:
Field | Type | Required | Notes |
| string | Yes | Item to remove |
| string | Demo only | Must own the item |
| boolean | Yes | Must be |
If confirmed is false, the tool returns confirmation_required: true without deleting anything.
Architecture
flowchart TD
A["Short voice request"] --> B["Alexa+ or demo agent"]
B --> C["Custody Agent Skill"]
C --> D["Streamable HTTP /mcp"]
D --> E["MCP tool handlers"]
E --> F["Domain services"]
F --> G["Authorization policy"]
F --> H["Item and search repositories"]
H --> I["SQLite or PostgreSQL"]
F --> J["Short structured response"]
J --> B
B --> K["Spoken answer"]Responsibility boundaries
Layer | Responsibility |
Alexa+ or demo agent | Understand the user's utterance, select a tool, ask necessary follow-up questions, and speak the short result |
Agent Skill | Define when to use Custody, tool-selection rules, privacy behavior, confirmations, and voice-output constraints |
MCP transport | Provide standard tool discovery and invocation over Streamable HTTP |
Tool handlers | Validate MCP-facing inputs and map service results into structured tool output |
Domain services | Apply event, custody, Lost Mode, and authorization rules |
Repository layer | Persist and query users, households, items, events, permissions, and search sessions |
Database | Store current state and immutable event history transactionally |
Technology stack
Core server
Technology | Role |
Python 3.12 | Application runtime |
| Official MCP Python SDK, tool registration, structured output, Inspector integration, and Streamable HTTP |
FastAPI | Host application, health endpoint, middleware, and future OAuth routes |
Uvicorn | Local and deployed ASGI server |
Pydantic v2 | Tool input/output schemas and application settings |
Data layer
Technology | Role |
SQLAlchemy 2.0 async | ORM and transactional repository implementation |
Alembic | Database migrations |
SQLite + | Zero-configuration local development and unit tests |
PostgreSQL + | Recommended deployed database |
RapidFuzz | Deterministic alias and approximate-name matching |
Alexa+ already provides the agentic language layer. The MCP server should keep truth resolution deterministic. Gemini or another LLM may later be used in the standalone demo client, but it is not required for the core Custody server.
Quality and operations
Technology | Role |
Pytest and pytest-asyncio | Unit, integration, authorization, and tool-contract tests |
HTTPX | HTTP and ASGI integration tests |
Ruff | Linting and formatting |
mypy | Static type checking |
Docker | Reproducible deployment image |
GitHub Codespaces/devcontainer | Consistent development environment |
GitHub Actions | Automated lint, type, test, and build checks |
Standard JSON logging | Request correlation and safe operational diagnostics |
Authentication plan
Hackathon simulator: explicit demo household and actor profiles supplied by the simulator.
Deployed Alexa+ integration: OAuth 2.1 account linking and server-derived user identity.
Tool arguments such as
actor_idandrequester_idare temporary simulator inputs. A production agent must not invent identity values.Per-speaker Alexa household identity is not assumed until the platform provides and documents it for the integration.
Planned repository structure
custody-alexa-mcp/
├── .agents/
│ └── skills/
│ └── custody/
│ ├── SKILL.md
│ ├── references/
│ │ └── tool-contracts.md
│ └── evals/
│ └── evals.json
├── .devcontainer/
│ └── devcontainer.json
├── .github/
│ └── workflows/
│ └── ci.yml
├── migrations/
├── src/
│ └── custody_mcp/
│ ├── __init__.py
│ ├── app.py
│ ├── config.py
│ ├── database.py
│ ├── mcp_server.py
│ ├── domain/
│ │ ├── enums.py
│ │ ├── models.py
│ │ └── policies.py
│ ├── repositories/
│ │ ├── items.py
│ │ ├── events.py
│ │ └── searches.py
│ ├── services/
│ │ ├── custody.py
│ │ └── lost_mode.py
│ └── tools/
│ ├── access.py
│ ├── items.py
│ └── lost_mode.py
├── tests/
│ ├── contract/
│ ├── integration/
│ └── unit/
├── .env.example
├── .gitignore
├── Dockerfile
├── LICENSE
├── pyproject.toml
└── README.mdFastAPI and Streamable HTTP server template
The implementation will use the current v2 MCP Python SDK. In v2, the server class is MCPServer. The MCP application is mounted inside FastAPI, and the FastAPI lifespan explicitly starts the MCP session manager.
The following illustrates the intended server shape. Service methods are placeholders until their repository-backed implementations are added.
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from datetime import datetime
from typing import Any, Literal
from fastapi import FastAPI
from mcp.server import MCPServer
from pydantic import BaseModel, Field
EventType = Literal[
"placed",
"moved",
"found",
"checked_out",
"checked_in",
"marked_missing",
]
Visibility = Literal["private", "shared", "restricted"]
SearchResult = Literal["found", "not_found", "skip", "cancel"]
class CustodyToolResponse(BaseModel):
status: Literal[
"ok",
"not_found",
"confirmation_required",
"forbidden",
"completed",
]
speech: str = Field(description="Voice-ready response of no more than 25 words")
item_id: str | None = None
confirmation_required: bool = False
next_action: str | None = None
data: dict[str, Any] = Field(default_factory=dict)
mcp = MCPServer(
"mcp-server-custody",
instructions=(
"Use Custody to remember and locate physical items, track shared-item "
"custody, correct stale locations, and guide Lost Mode. Treat every "
"location as last reported rather than physically verified."
),
)
@mcp.tool(title="Record an item event")
async def record_item_event(
item_name: str,
event_type: EventType,
actor_id: str,
location: str | None = None,
holder_id: str | None = None,
occurred_at: datetime | None = None,
operation_id: str | None = None,
) -> CustodyToolResponse:
"""Record that an item was placed, moved, found, borrowed, returned, or marked missing."""
return await custody_service.record_item_event(
item_name=item_name,
event_type=event_type,
actor_id=actor_id,
location=location,
holder_id=holder_id,
occurred_at=occurred_at,
operation_id=operation_id,
)
@mcp.tool(title="Locate an item")
async def locate_item(
item_name: str,
requester_id: str,
) -> CustodyToolResponse:
"""Return an authorized item's last reported location or current holder."""
return await custody_service.locate_item(
item_name=item_name,
requester_id=requester_id,
)
@mcp.tool(title="Start Lost Mode")
async def start_lost_mode(
item_name: str,
requester_id: str,
) -> CustodyToolResponse:
"""Start a guided search and return only the first place to check."""
return await lost_mode_service.start(
item_name=item_name,
requester_id=requester_id,
)
@mcp.tool(title="Continue Lost Mode")
async def continue_lost_mode(
search_session_id: str,
result: SearchResult,
requester_id: str,
found_location: str | None = None,
) -> CustodyToolResponse:
"""Record the previous search result and return the next step or finish the search."""
return await lost_mode_service.continue_search(
search_session_id=search_session_id,
result=result,
requester_id=requester_id,
found_location=found_location,
)
@mcp.tool(title="Set item access")
async def set_item_access(
item_name: str,
requester_id: str,
visibility: Visibility,
allowed_user_ids: list[str] | None = None,
) -> CustodyToolResponse:
"""Set an owned item as private, household-shared, or restricted."""
return await custody_service.set_item_access(
item_name=item_name,
requester_id=requester_id,
visibility=visibility,
allowed_user_ids=allowed_user_ids,
)
@mcp.tool(title="Forget an item")
async def forget_item(
item_name: str,
requester_id: str,
confirmed: bool = False,
) -> CustodyToolResponse:
"""Permanently delete an owned item and its records after explicit confirmation."""
return await custody_service.forget_item(
item_name=item_name,
requester_id=requester_id,
confirmed=confirmed,
)
mcp_http_app = mcp.streamable_http_app()
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
async with mcp.session_manager.run():
yield
app = FastAPI(
title="Custody MCP Server",
version="0.1.0",
lifespan=lifespan,
)
@app.get("/health", tags=["operations"])
async def health() -> dict[str, str]:
return {"status": "ok", "service": "mcp-server-custody"}
# Keep this mount after ordinary FastAPI routes because Mount("/") matches all paths.
app.mount("/", mcp_http_app)When running locally, the MCP client connects to:
http://127.0.0.1:8000/mcpFor a public hostname, the implementation must configure MCP transport security with an explicit Host and Origin allowlist. It must not disable DNS-rebinding protection merely to make deployment errors disappear.
Data model
Custody uses current-state columns for fast answers plus append-only events for auditability.
households
Column | Purpose |
| Household boundary |
| Display name |
| Creation timestamp |
users
Column | Purpose |
| Internal user identity |
| Tenant boundary |
| Safe spoken attribution |
| Member or administrator |
items
Column | Purpose |
| Stable item identifier |
| Tenant boundary |
| Normalized item name |
| Owner and privacy authority |
| Private, shared, or restricted |
| In place, checked out, or missing |
| Latest reported location |
| Current borrower when checked out |
| Latest state-change timestamp |
item_aliases
Maps phrases such as “car fob,” “Honda clicker,” and “spare car key” to an authorized canonical item.
item_events
Immutable event history containing event type, actor, location, holder, timestamp, and optional idempotency operation ID.
item_permissions
Stores explicit user access for restricted items.
search_sessions
Stores Lost Mode state, ordered candidate locations, current index, requester, status, and completion outcome.
Item resolution
Item matching proceeds in a privacy-safe order:
Limit candidates to the requester's household.
Remove items the requester is not authorized to discover.
Try an exact canonical-name match.
Try an exact alias match.
Apply conservative RapidFuzz matching above a configured threshold.
If multiple close matches remain, return a short clarification request.
The server must never run fuzzy matching over inaccessible items and then reveal the candidate names in an error.
Authorization and privacy
Visibility modes
Mode | Access |
| Owner only |
| Authorized household members |
| Owner plus explicitly selected members |
Privacy rules
Authorization precedes item lookup output, history output, and alias disclosure.
Unauthorized and nonexistent items produce the same external response.
Logs contain opaque IDs, not sensitive item names or locations.
The server does not ingest ambient conversations.
The server does not infer locations from unrelated smart-home telemetry in the MVP.
forget_itemperforms a verified hard deletion of associated records.Destructive and access-changing actions require clear confirmation.
Voice response contract
The Agent Skill and tests enforce the following:
Prefer 8–20 spoken words; never exceed 25 words by default.
Give one answer or one next step.
Use ordinary words instead of IDs, timestamps, or status enums.
Convert timestamps to human language such as “this morning” or “two hours ago.”
Say “last reported” when state has not been physically verified.
Never read a history list aloud.
Ask only one clarification question at a time.
Do not reveal internal errors, database names, tokens, or authorization logic.
Agent Skill package
The canonical skill will live at:
.agents/skills/custody/SKILL.mdIts YAML frontmatter will use name: custody, matching the parent directory. The skill will describe:
when requests should activate Custody;
how to choose among the six tools;
how to interpret follow-up corrections;
how to maintain Lost Mode conversation state;
when confirmation is required;
how to handle private or unknown items; and
the maximum spoken-response length.
Detailed contracts will remain in references/tool-contracts.md so the core SKILL.md remains concise. Trigger and response evaluations will live in evals/evals.json.
Local development plan
The final scaffold will use uv for dependency and command management.
Prerequisites
Python 3.12
Git
uvNode.js and
npxfor MCP InspectorDocker only when testing PostgreSQL or the production image
Planned setup commands
git clone https://github.com/YOUR_USERNAME/custody-alexa-mcp.git
cd custody-alexa-mcp
uv sync --all-groups
cp .env.example .env
uv run alembic upgrade head
uv run uvicorn custody_mcp.app:app --reloadPlanned environment variables
APP_ENV=development
DATABASE_URL=sqlite+aiosqlite:///./custody.db
LOG_LEVEL=INFO
MCP_ALLOWED_HOSTS=127.0.0.1:*,localhost:*
MCP_ALLOWED_ORIGINS=http://127.0.0.1:*,http://localhost:*
FUZZY_MATCH_THRESHOLD=90
VOICE_MAX_WORDS=25
DEMO_AUTH_ENABLED=trueSecrets and real tokens must never be committed. .env.example contains names and safe defaults only.
Running and inspecting the MCP server
After the implementation is scaffolded:
uv run uvicorn custody_mcp.app:app --host 127.0.0.1 --port 8000 --reloadHealth check:
curl --fail http://127.0.0.1:8000/healthExpected response:
{"status":"ok","service":"mcp-server-custody"}The MCP endpoint itself is not a normal REST endpoint and should be exercised with an MCP client or Inspector rather than an arbitrary JSON body.
Planned Inspector command:
uv run mcp dev src/custody_mcp/mcp_server.pyThe exact Inspector command will be finalized after the application factory and import path are implemented.
Testing strategy
Unit tests
Item-name normalization and alias matching
Event-driven state transitions
Checkout and check-in rules
Visibility and permission policies
Lost Mode candidate ordering
Voice-response word limit
Idempotent duplicate write handling
Integration tests
Save then locate an item
Correct a stale location and retrieve the correction
Check out an item and retrieve its current holder
Check an item back in and restore its location state
Start and advance Lost Mode
Finish Lost Mode with a found-location event
Deny unauthorized discovery without revealing existence
Require confirmation before deletion
Permanently delete an item and its related records
List and invoke all six tools through an in-process MCP client
Connect through the deployed Streamable HTTP
/mcpendpoint
Agent Skill evaluations
Examples that should activate Custody:
“Where did I put my keys?”
“Remember that the passport is in the blue drawer.”
“The drill isn't there. Help me look for it.”
“Tell Custody that I’m borrowing the stud finder.”
“Make my journal private.”
Examples that should not activate Custody:
“Where is Mount Everest?”
“Track my delivery.”
“Find a hardware store near me.”
“Remind me to call Sarah tomorrow.”
“Where should I store a passport safely?”
Continuous integration
Every pull request should run:
uv run ruff format --check .
uv run ruff check .
uv run mypy src
uv run pytestThe CI workflow should also build the Docker image after tests pass.
Deployment approach
The service will be packaged as one Dockerized ASGI application with HTTPS termination at the hosting platform.
For the hackathon deployment:
run one server process initially to avoid legacy-session routing complexity;
use a managed PostgreSQL database;
expose
/mcpand/healthonly;configure exact MCP Host and Origin allowlists;
terminate TLS at a trusted proxy or managed platform;
trust forwarded headers only from that proxy;
keep operational logs free of item names and locations; and
verify protocol negotiation and every tool using MCP Inspector before connecting the simulator.
The final hosting provider will be selected after the local MCP and Alexa+ simulation pass end-to-end testing.
Delivery plan
Milestone 0 — Repository and Codespace
Create
custody-alexa-mcpAdd MIT license
Open a GitHub Codespace
Add Python 3.12 devcontainer
Add
pyproject.toml, Ruff, mypy, Pytest, and CI
Exit condition: A clean Codespace runs the test command successfully.
Milestone 1 — MCP transport skeleton
Create
MCPServer("mcp-server-custody")Mount Streamable HTTP in FastAPI
Add
/healthRegister six stub tools with final schemas
Verify tool discovery in MCP Inspector
Exit condition: Inspector lists exactly six tools and can invoke each stub.
Milestone 2 — Database and event model
Add SQLAlchemy models and Alembic migration
Implement household, user, item, alias, event, permission, and search repositories
Add transactional current-state updates
Add demo household seed data
Exit condition: Database integration tests pass from an empty database.
Milestone 3 — Core memory and custody
Implement
record_item_eventImplement
locate_itemImplement checkout/check-in state
Add provenance and voice-ready responses
Add conservative alias resolution
Exit condition: Remember, locate, correct, checkout, and check-in flows pass end to end.
Milestone 4 — Lost Mode and privacy
Implement
start_lost_modeImplement
continue_lost_modeImplement
set_item_accessImplement confirmed
forget_itemAdd privacy non-disclosure tests
Exit condition: Guided search, permission, and deletion scenarios pass without information leakage.
Milestone 5 — Agent Skill and voice simulation
Write
SKILL.mdAdd tool-selection reference
Add positive and negative trigger evaluations
Connect to the Alexa+ Web Simulator when available
Build a minimal fallback voice simulator if necessary
Exit condition: Natural utterances consistently select the correct tool and spoken answers remain within the voice limit.
Milestone 6 — Deployment and hardening
Add production Dockerfile
Deploy with HTTPS and managed PostgreSQL
Configure Host/Origin allowlists
Add request correlation and sanitized logs
Run remote MCP Inspector tests
Export successful test traces
Exit condition: A fresh external client can discover and invoke all six tools over the public /mcp endpoint.
Milestone 7 — Hackathon submission
Record a demo under three minutes
Complete architecture and setup documentation
Add product feedback and friction log
Confirm repository visibility, license, and reproducible setup
Submit before the hackathon deadline
Three-minute demo outline
Time | Beat | Demonstrated value |
0:00–0:20 | Accessibility problem and product promise | Why voice is necessary |
0:20–0:50 | Remember and locate keys | Fast voice-native happy path |
0:50–1:25 | Stale answer, Lost Mode, natural correction | Trust recovery and self-healing state |
1:25–1:55 | Borrow and locate a drill from another profile | Shared custody and attribution |
1:55–2:20 | Private-item request from unauthorized profile | Privacy-aware multi-user design |
2:20–2:45 | Inspector/tool trace and architecture | Genuine MCP implementation |
2:45–3:00 | Impact and future direction | Memorable closing |
Non-goals for the MVP
Custody will not initially:
listen to ambient household conversations;
physically track objects through Bluetooth, RFID, cameras, or GPS;
infer locations from smart locks or unrelated device telemetry;
calculate invented confidence percentages;
build object-to-object spatial graphs;
interrupt users with proactive routine prompts;
provide long spoken histories or on-screen inventory management; or
claim that a last-reported location is physically verified.
These constraints keep the demo trustworthy, voice-native, privacy-conscious, and achievable.
Key risks and mitigations
Risk | Mitigation |
Users forget to record movements | Natural correction loop and check-out phrasing |
Stale records damage trust | Always include provenance and relative time; offer Lost Mode |
Private item existence leaks | Authorization-first lookup and neutral not-found responses |
Similar item names collide | Conservative matching and one short clarification question |
Duplicate tool retries create events | Optional operation ID and database uniqueness constraint |
Agent gives long answers | Dedicated |
Demo depends on undocumented speaker recognition | Explicit simulated profiles; production identity remains an account-linking concern |
Deployment rejects remote MCP requests | Explicit Host/Origin allowlists and remote Inspector tests |
Future possibilities
Only after the MVP is stable:
optional QR, NFC, Bluetooth, or RFID evidence;
caregiver-managed accessibility profiles;
multilingual voice responses;
organization/workshop mode with due-back times;
optional visual history for screen-enabled devices; and
privacy-preserving aggregate insights such as frequently misplaced item categories.
Contributing
The project will accept focused issues and pull requests that preserve its voice-first and privacy-first principles. Proposed features should explain:
the specific user problem;
why voice is the correct interaction;
the required tool or schema change;
privacy and failure behavior; and
how the feature can be tested deterministically.
License
MIT License. A complete LICENSE file will be added when the repository is initialized.
References
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/BLVCK-MAMBA-6/custody-alexa-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server