Inspiration
You're on the couch, in the kitchen or in bed, and your PC is across the room. It's lagging, a window is stuck, or you just want it locked. Voice remotes for PCs already exist, but they fire a command and hope. We wanted an assistant that treats your PC like something precious: it checks before it acts, asks before it closes anything, and never says "done" unless the PC itself confirmed it.
We also wanted to build the kind of add-on Alexa+ is meant to host: a real MCP server with proper sign-in, not a thin wrapper around an existing API.
What it does
Within Reach lets you check on and control your own Windows PC by voice. You talk to a simulated Echo Show page, clearly labeled "Simulated Alexa+". It calls a real MCP server on AWS, which reaches a real Windows PC. A panel beside the conversation shows every MCP request and response.
- "Is my PC on?" The PC's live state: online or "offline since...", locked or not, CPU and memory.
- "What's slowing my PC?" It reads the PC's own live check and names the busiest app by kind, never by window title. If nothing is busy, it says so instead of inventing a problem.
- "Close Notepad." then "Yes." The server prepares the close and asks; your yes runs it. The PC shows a 10-second countdown naming the app, with a Cancel button, asks the app to close politely (it never force-kills), and measures CPU and memory before and after. The assistant repeats what the PC reported.
- "Lock my PC." It says "locked" only after Windows confirms the session is locked, otherwise "sent".
- More abilities: open an app from the PC's own list, find your newest download and highlight it in File Explorer, press media keys, open a saved website, and read a game launcher's update state.
The PC never receives a path, a program argument or a URL from the cloud. It gets only the words you said, which it matches against its own lists. Files come back as kind, rough size, age and folder, never as a path or contents.
Where each part stands
- Live-checked on a real PC: lock (Oct 14); close by name with a spoken yes, the countdown and before/after (Oct 15, Oct 22, and four times in a row on Oct 23); opening an app, finding the newest download and showing it in File Explorer, media keys, a saved website and a launcher's update check (Oct 22).
- Built and unit-tested, not live-checked: saved routines.
- Implemented, deployed, unit-tested and security-reviewed, but never run on a second PC: pairing your own PC through the page with a one-time code and no AWS keys.
- Simulated: Alexa+ itself, the Echo, and the voice (your browser's speech). We claim no Echo integration and no Alexa+ certification.
How we built it
A browser page plays the Echo Show. A Strands agent on AWS Lambda plays the Alexa+ cloud and calls our MCP server as a real MCP client, with the signed-in user's token. Its system prompt is our Agent Skill (SKILL.md).
The MCP server is TypeScript (MCP spec 2025-11-25, Streamable HTTP, stateless JSON) on AWS Lambda behind an API Gateway HTTP API. Sign-in is Amazon Cognito: OAuth 2.1 authorization code with PKCE, required authenticator-app sign-in, and resource binding, so every token's audience is our server. The server publishes its own RFC 9728 and RFC 8414 metadata.
The server reaches the PC through AWS IoT Core. The PC agent is a Python tray app that runs as a standard user and only connects outward, over MQTT 5 with mutual TLS. Its key was generated inside the PC's TPM chip and can't be exported. Commands go out on the PC's own topic with a 60-second expiry, the PC's state comes back through its device shadow, and a Last Will plus a rule marks it offline. Every command passes a fixed sequence of checks on the PC (size, JSON, a schema shared with the server, time window, expiry, replay) before anything runs.
Every MCP call has to answer quickly, so the server never waits on the PC for long. Slow work, such as a close or a launch, becomes a job that the client follows:
$$t_{\text{MCP call}} < 500\ \text{ms}, \qquad t_{\text{wait for the PC}} \le 400\ \text{ms}$$
A close is confirmed only once, and only inside this window after it was prepared, then the PC counts down 10 seconds with a Cancel button:
$$2\ \text{s} \;\le\; t_{\text{yes}} - t_{\text{prepared}} \;\le\; 120\ \text{s}$$
AWS: Lambda (Node.js 24 and Python 3.13 on arm64), API Gateway HTTP APIs, Cognito, IoT Core, DynamoDB (single-use confirmations and one-time pairing codes, with TTL), CloudFront and S3 (the page with a strict content security policy, same-origin API routes, the try-it page and the PC app download), Systems Manager Parameter Store, CloudWatch Logs, Budgets, and the CDK in TypeScript for all of it.
The model was chosen by measurement. We ran fixed scenarios, including a planted instruction to close the wrong app, and scored them with plain checks. Claude Haiku 5.5 with thinking off passed every safety check at a 95th-percentile voice turn of 3.4 to 3.6 seconds. The larger model cost about 20 times more and did worse.
Quality: over 13,000 automated tests across five packages, and a line-by-line security review of every security-sensitive change.
Built with Claude Code. I made the product, design and security decisions, ran the accounts and the hardware tests, and recorded the demo; the code came from Claude Code and from me.
Challenges we ran into
- Bedrock said no. Every call failed with "Error 002: Access to Bedrock models is not allowed for this account" while the availability check said the model was ready. We ruled out the use-case form, the model, the region, the API and permissions, and filed an AWS Support case. The simulator runs Claude Haiku 5.5 through Anthropic's API, behind a one-setting switch back to Bedrock.
- Standards that almost line up. Cognito publishes no RFC 8414 metadata, and resource binding with custom scopes only works if the resource server's identifier is the resource URL. Our server serves the metadata itself.
- Presence. The device shadow ignores a Last Will sent to its own topics, so "offline since" needs a normal topic, a rule and a role.
- A key that never leaves the TPM. Windows couldn't install an AWS IoT certificate for a TPM key the standard way. certutil's repair step links them.
- Confirmation by voice. Random challenge words broke on browser speech, so we moved to a plain spoken "yes" and kept every other guard in code (the window above, single use, the countdown). Our first live close repeated itself because the model prepared it again, so a short "yes" is now recognised by plain code. The model is weakest on short follow-ups, so on the last morning we moved "show me" into plain code too.
- Safety rails versus convenience. The PC starts at most one program every 5 seconds, so a voice request can't start a flood of programs. The cost: asking for three apps in one sentence opens only the first.
- Old news. A game update check from the day before was repeated in every status answer for 24 hours, by design. Honest, but noisy.
- A safety feature in our own way. By default the PC holds a close while anyone is using the keyboard or mouse, which is exactly what you're doing while testing. We turned that wait off on the demo PC in its policy file, which the cloud can't change.
- Letting a stranger pair a PC without AWS keys. IAM can't scope some IoT attach calls to one thing, and HTTP APIs can't set CORS per route or cap a request's size, so those guards live in our own tested code.
Accomplishments that we're proud of
- A real PC reacting to a spoken request, with an honest answer every time: "locked" only when Windows confirms, "sent" when it hasn't, "offline since" when the PC is gone, and "nothing much changed" when a fix did nothing.
- A security model with no inbound ports, a hardware-bound key that can't be copied, typed allowlisted tools with no shell, and safety rules in plain code (the model only judges whether you said yes).
- A real MCP server with OAuth 2.1 that follows Alexa+'s documented add-on contract, a portable Agent Skill, and a clearly labeled simulation instead of a pretend integration.
- Over 13,000 automated tests, and a friction log of ten entries for AWS and Amazon developer tools.
What we learned
- Treat the model as a talker, not a decider. Every safety rule belongs in code you can test, and so do the short replies ("yes", "show me") where a model is least reliable.
- Measure the model choice. The cheapest model that passed every safety check won.
- Read the IAM and documentation edges before building on them. Several of ours are in the friction log.
- Build the honest failure states first. "Sent", "offline since" and "nothing changed" are what make an assistant trustworthy.
What's next
- Several apps in one request, queued behind the PC's 5-second launch limit.
- Saved routines checked live, and called reliably by the model.
- A clean-machine test of pairing on a second PC.
- A spoken voice code for riskier abilities, and shutdown after a download with a 60-second countdown.
- Several PCs per account.
- "Couch mode": computer use with the user in the room, one visible window, and a plain-code gate on send and delete.
- Real Alexa+ testing, if partner access opens.
Built With
- amazon-web-services
- api
- cdk
- claude
- cloudfront
- cloudwatch
- cognito
- dynamodb
- gateway
- haiku
- iot
- json
- lambda
- mcp
- mqtt
- node.js
- oauth
- protocol
- python
- s3
- sdk
- speech
- typescript
- windows
Log in or sign up for Devpost to join the conversation.