Synodic Studio github ↗

Patchbay · a small tool

Patchbay Go

Chat apps won't turn obsidian:// or things:// into a link. They arrive as dead text. Patchbay Go wraps them in a plain https:// URL so Telegram makes them a single tap, straight into the app.

What the app sends
obsidian://open?vault=Notes&file=today.md
Dead text in Telegram. Tapping does nothing.
What Patchbay Go sends
One tap → a tiny redirect page → Obsidian opens on your phone.

How it works

The chat app is the gatekeeper: its rule is "a link looks like a web address." So you give it exactly that, and do the scheme swap one hop later in the browser, where custom schemes are allowed.

https://go.synodic.co/obsidian/MyVault/notes/today.md
  → serves a one-line redirect page
  → obsidian://open?vault=MyVault&file=notes/today.md
  → the app opens

No auth, no logging, no server state. One file, zero runtime dependencies, free tier on Cloudflare Pages.

Named routes, so nothing needs encoding

/obsidian/<vault>/<path>
Obsidian note
/remind/<title>
Apple Reminders
/cal/<yyyy-mm-dd>
Calendar.app
/things/<title>
Things to-do
/fantastical/<sentence>
Fantastical event
/raw/<base64url>
any native scheme

…plus /todoist, /bear, /drafts, /shortcuts, /whatsapp, /telegram, /googlemaps, /waze, /zoom and launchers like /slack and /music. A language model writes go.synodic.co/things/Buy%20milk correctly on the first try; /raw covers the long tail, and refuses browser-privileged schemes, so a wrapped link can only ever open a native app, never run in the browser.

One secret, without a chat log

The /key paste form

An agent sends a /key/<uuid> link. Tap it, paste an API key into a small labeled form, and it is encrypted in your browser, to the agent's own key, before it's sent. The relay only ever stores ciphertext and never holds the key to read it; the agent decrypts it on its own machine. A quiet way to move a secret into your automation without it ever sitting in a chat, or in anyone else's hands.

If you are an agent

Wrapping needs nothing but the route: put the value after the name and percent-encode it, as in go.synodic.co/things/Buy%20milk. The full route list is APP_ROUTES in the worker, and anything without a named route goes through /raw.

Asking for a secret takes four calls. Generate an RSA-OAEP-2048 keypair, then:

POST /key/register
{label, publicKey, webhook?} → {uuid, secret, url}
GET /key/<uuid>
the form you send a human
POST /key/<uuid>
the browser posts the envelope
GET /key/<uuid>/result
one-shot ciphertext, deleted on read

publicKey is base64 SPKI. The envelope is {v:1, alg:"RSA-OAEP+A256GCM", wrappedKey, iv, ciphertext}, all base64, and it is rejected at registration if the key will not import. Supply a webhook and the ciphertext is delivered to you instead, signed with X-Patchbay-Signature. Rather than implement it, take the reference client or install the skill; SECRET-HANDOFF.md is the whole protocol.