I am fortunate to know people across the Greater Toronto Area. The challenge is not finding more contacts. It is remembering past conversations and promises to my future self, then surfacing them exactly when it makes sense to act.
I might finish a phone call with someone and think, “The next time I am downtown, I should message them.” By the time I am downtown, that thought is buried under dozens of newer ones.
I wanted to close that gap with a small workflow built around Hermes Agent:
I tell Hermes whom I want to follow up with and where. Later, when I arrive there, Hermes reminds me about that specific person and the reason I wanted to reconnect.
That distinction is important. This is not a system that searches my contacts and sends me everyone associated with Toronto. Hermes only surfaces follow-ups I explicitly asked it to remember for that location.
The finished workflow has two halves:
I capture the relationship context conversationally in Discord.
An iOS location automation retrieves the relevant follow-up when I arrive.
Between those two moments, Hermes keeps the context in a private people.yaml file. iOS Shortcuts, a Cloudflare Worker, Cloudflare Tunnel, Zoraxy, a constrained Hermes webhook, and Discord move the event through the system without exposing my Hermes environment directly.
A traditional contact manager is good at answering questions such as “What is John's phone number?” It is less useful for a more contextual question:
What did I tell myself I wanted to do the next time I was in this place?
That is the job of this assistant.
The record begins with a real interaction. For example, using only fictional data:
I talked to John Smith today over the phone. We discussed his new role and the project he is leading. Next time I am at the Toronto office, remind me to message him so we can arrange a coffee.
Hermes extracts and stores the useful parts of that message:
Who I spoke with;
When and how we spoke;
What we discussed;
What I want to do next; and
The location where I want that reminder to become relevant.
If I give an approximate time but not an exact date, Hermes preserves that ambiguity instead of inventing precision. For example, “catch up in October” can remain a note for October while an exact follow-up date stays unset. That sounds like a small detail, but it is one of the behaviours that makes the system trustworthy: the assistant should organize what I said, not quietly turn a guess into a fact.
Discord is already where I interact with Hermes, so it is also the most natural place to capture a networking intention. I do not open a separate CRM, navigate through a form, or try to predict every field in advance. I describe the conversation in ordinary language.
A fictional example might look like this:
Me:
I talked to John Smith today over the phone. We discussed his new
role and the project he is leading. Next time I am at the Toronto
office, remind me to message him so we can arrange a coffee.
Hermes:
Updated John Smith's contact:
- Last contact: August 30, 2026
- Method: Phone call
- Discussion: His new role and current project
- Follow-up: Message John and arrange a coffee
- Reminder location: Toronto office
The networking-assistant skill turns that conversation into structured data in people.yaml. The real file contains personal information and remains inside the private Hermes profile. A simplified, fictional illustration of the idea, not the production schema, looks like this:
people:
- name: John Smith
last_contact:
date: 2026-08-30
method: phone
notes: Discussed his new role and current project.
follow_up:
action: Message John and arrange a coffee.
location: toronto-office
The stable location ID is deliberately different from a street address or a set of coordinates. The physical geofence stays on my phone. Hermes only needs to know that an event called toronto-office occurred.
The second workflow may happen days or months later.
When I arrive at a configured location, iOS runs a personal automation. The automation calls a reusable Shortcut and gives it the logical location ID. The Shortcut sends that ID to a Cloudflare Worker over HTTPS.
From there, the event follows this path:
iOS arrival automation
-> reusable Shortcut
-> Cloudflare Worker
-> Cloudflare Tunnel
-> Zoraxy reverse proxy
-> Hermes webhook and fixed transformation
-> networking-assistant skill + people.yaml
-> Hermes Discord bot
-> Discord networking channel
Hermes does not return every person whose record happens to mention Toronto. The networking skill looks for the follow-up intentions associated with the incoming logical location. If I asked to be reminded about John at the Toronto office, John is eligible. If I never created a Toronto reminder for another contact, that person is not added merely because they live or work nearby.
That makes the output a reminder of prior intent, not an unsolicited contact recommendation engine.
The arrival event takes a constrained path from iOS to Hermes, while relationship context remains in the private contact store.
The number of components can look excessive for a reminder. Each one, however, has a narrow responsibility.
iOS owns the physical location. Its “When I Arrive” automation detects entry into the geofence, then passes a logical ID such as toronto-office to one reusable Shortcut.
The Shortcut does not send my coordinates to Hermes. It also does not decide whom to contact. It sends a small event that means, in effect, “the Toronto office location is now active.”
Using a reusable Shortcut avoids duplicating the request logic for every place. Each arrival automation only needs to supply a different logical ID.
Each geofence passes a logical location ID to the same reusable Shortcut.
The Worker is the public entry point and a small security boundary. It accepts only the expected request type, verifies the phone's authorization, validates the location ID, and signs the exact request body before forwarding it.
This keeps signing logic out of the Shortcut and means Hermes does not have to trust arbitrary traffic arriving from the internet. The Worker is intentionally narrow: it cannot browse contacts or make networking decisions.
There are two separate trust checks:
the Worker verifies that the request came from an authorized Shortcut; and
Hermes verifies the Worker's signature for this webhook route.
No credential values belong in the article, screenshots, source repository, or logs.
After the Worker signs the request, Cloudflare Tunnel carries it into my environment. Zoraxy, my reverse proxy, routes it to the Hermes webhook service.
This lets the workflow reach Hermes without direct router port forwarding. The public article does not need and should not reveal the real hostname, internal network addresses, upstream ports, or proxy configuration.
The webhook is not a general-purpose remote command interface. It invokes a fixed, read-only transformation that:
accepts only a tightly constrained logical location ID;
reads only the known people.yaml file;
passes structured context to the networking skill;
performs no writes during the location-triggered lookup; and
fails silently rather than exposing private data when input is invalid.
That boundary matters. An internet-originating event should not be able to choose an arbitrary file, path, or command simply because an agent is behind the webhook.
The skill gives Hermes the domain-specific behaviour for capturing conversations and producing reminders. people.yaml is the private memory behind it: contact history, context, follow-up notes, and explicit location intentions.
The conversational capture workflow may update that file. The arrival workflow only reads it. Keeping those responsibilities distinct makes the triggered path easier to reason about and safer to expose through a webhook.
Discord closes the loop. It is both the conversational place where I create the reminder and the place where Hermes delivers it later.
That continuity is useful: I record the intent in a normal conversation, and the result returns to a channel I already use. There is no additional app to remember to check.
Fictional data showing location-based follow-ups after an arrival event.
One lesson from this project is that not every part of an agent workflow should be agentic.
Hermes is useful where interpretation is required. It can turn a natural language account of a phone call into structured relationship context, preserve uncertainty when I did not provide an exact date, and produce a concise reminder that explains why the person matters now.
The surrounding infrastructure is intentionally deterministic:
iOS decides whether I entered a geofence;
the Worker validates and signs a small request;
the Tunnel and reverse proxy route it;
the webhook accepts one constrained event shape; and
the transformation reads one fixed data source.
This separation gives the agent room to reason without giving an internet-triggered request unnecessary freedom.
Relationship data is inherently personal, so I treated privacy as part of the architecture rather than a cleanup step before publication.
Physical addresses and geofence coordinates stay on the iPhone.
The external request contains a logical location ID, not GPS data.
Contact records remain in the private Hermes profile and are not copied into the documentation repository.
The phone-to-Worker and Worker-to-Hermes checks use separate credentials.
The location-triggered transformation is fixed and read-only.
Hermes is reached through a managed tunnel and reverse proxy, not direct public port forwarding.
Screenshots for publication must be generated from fictional test records, not edited versions of real contact output.
Hostnames, credentials, internal addresses, private paths, and internal ports are omitted from public material.
The last point deserves emphasis. A blurred secret or partially hidden name is easy to get wrong. For a public demonstration, the safer approach is to insert fictional records, run the real workflow, capture the genuine output, and then remove the test records.
The most valuable part of the system is not the geofence or the notification. It is the continuity between a conversation today and a useful prompt in a future context.
Several design lessons stood out:
If recording a follow-up requires opening a CRM and completing a form, I will postpone it. A natural-language message in Discord is quick enough to use immediately after a call.
“John is in Toronto” is weak context. “You asked yourself to message John the next time you were at the Toronto office because you discussed arranging a coffee” is actionable context.
Approximate timing should remain approximate. Leaving an exact date unset is better than creating false certainty.
The rest of the system does not need my live coordinates. A stable logical ID is enough to retrieve the intention I associated with a place.
The external path can trigger one well-defined capability without exposing a shell, an arbitrary file reader, or the wider Hermes environment.
The end-to-end path has been tested with a controlled external request: the Worker accepted the authorized event, Hermes processed the signed webhook, and the expected briefing reached Discord.
The remaining real-world test is the iOS arrival trigger itself. Geofence behaviour can vary, and duplicate arrival events are possible. I want to observe that behaviour before adding state or a cooldown. If deduplication becomes necessary, the Worker is the most appropriate place to add it because it can suppress repeated events before they reach Hermes.
Other possible extensions include:
time-aware reminders that combine a broad month with a location;
a conversational way to mark a follow-up complete or postpone it;
clearer priority rules when several explicit reminders match one place;
private backup and recovery validation for the contact store; and
additional locations that reuse the same Shortcut and secured ingress pattern.
The goal is not to turn every contact into a notification. The system should stay selective. Its value comes from reminding me about the intentions I deliberately captured, not from creating more noise.
This project started with a simple problem: good intentions disappear between the end of a conversation and the next time I am in the right place to act on them.
Hermes gives those intentions a little continuity. I can describe a conversation when it happens, preserve the reason I want to reconnect, and let the relevant place bring that promise back to me later.
That is a small automation, but it reflects the kind of agent system I want to build: conversational where interpretation helps, deterministic where trust matters, private by design, and useful at exactly the right moment.