Inspiration

I'm a software engineer. Most of my day is sitting, reading and typing, with very little talking. I wanted a habit that makes me say things out loud: recall my day, put it into words, and practise speaking, instead of typing one more thing. Journaling was the obvious fit, but writing a journal is just more typing. So I built one you keep by talking: you tell the assistant what happened, your exact words become a dated entry, and you can ask for them back later or read them on your phone.

What it does

  • Write by talking to an assistant. "Add to my journal: I walked by the bay after dinner." The assistant calls Omoide's MCP server, and the entry is saved in your own words, dated in your time zone.
  • Ask about your past days. "What did I write yesterday?" or "When did I last mention the bay?" The assistant reads or searches your journal.
  • Read it on your phone. The Omoide app for iOS and Android shows the same journal, grouped by day, with search, editing and a calendar.
  • One account everywhere. The app, the MCP server and the Alexa skill all sign in through the same Amazon Cognito account, so an assistant only ever sees your journal.

MCP tools: write_entry, list_entries, search_entries, read_day.

How I built it

  • MCP server (the Alexa+ track's required tech). Spring AI 2.0 on Spring Boot 4.1 serves an MCP server at /mcp: protocol version 2025-11-25, Streamable HTTP (stateless). Tools are annotated Java methods (@McpTool) that call the same services as the app's REST API.
  • MCP authorization with Amazon Cognito. The server is an OAuth 2.0 resource server that validates Cognito access tokens (JWKS) and checks client_id and token_use, since Cognito access tokens carry no aud. It publishes RFC 9728 Protected Resource Metadata (Spring Security 7) and answers 401 with a resource_metadata pointer. Cognito's discovery document doesn't advertise code_challenge_methods_supported, which the MCP spec requires, so the server also publishes RFC 8414 metadata pointing at Cognito's endpoints with S256.
  • Accounts. The Cognito sub is the account's primary key, so the app, Alexa and MCP all resolve to the same journal with no mapping table.
  • Mobile app. Flutter with the official MVVM architecture; sign-in through Cognito's hosted pages with flutter_appauth (authorization code + PKCE, per RFC 8252).
  • Classic Alexa skill. A custom skill at /alexa verifies Amazon's request signatures and links accounts through Cognito. It's a second voice path into the same journal.
  • Data. PostgreSQL with Flyway migrations. A journal "day" is the local date in the person's time zone, and entries written before 4 am count as the previous day.
  • Specs first. Each slice (Cognito auth, Alexa linking, MCP) was written as an OpenSpec change with requirements and test scenarios before any code; the specs are in the repo.

Challenges I ran into

  • Cognito as an MCP authorization server. Cognito has no RFC 8414 metadata, no Dynamic Client Registration, and its discovery document omits PKCE methods. I used pre-registered public app clients plus a small metadata document on the server that fills the gap.
  • The Alexa Skills Kit SDK for Java on Spring Boot 4. The SDK's servlet support is still javax-only. Its signature and timestamp verifiers don't depend on the servlet API, so I fed them directly from a Jakarta request.
  • Alexa+ developer tooling is partner-only. Connecting a self-hosted MCP server to a real Alexa+ device isn't possible yet for participants, so the demo uses an MCP client.

Accomplishments I'm proud of

  • An MCP server that follows the 2025-11-25 authorization spec end to end, from the 401 challenge through to a real Cognito token, tested with a live sign-in.
  • One account and one journal across a phone app, an MCP server and an Alexa skill.
  • 38 server tests (including real MCP JSON-RPC calls) and 61 app tests.

What I learned

  • How MCP authorization discovery works in practice: the protected resource metadata, then authorization server metadata, then PKCE. Also why a single missing metadata field can stop a client.
  • How Alexa account linking and Cognito fit together, and how to verify Alexa requests on a self-hosted endpoint.

What's next

  • A spoken Alexa+-style front end that talks to the MCP server.
  • Reading entries back aloud ("read me what I wrote on Monday").
  • Hosting on AWS so the MCP server is always reachable.

Built With

Share this project:

Updates

Submission history