chore: anonymize deployment URL in docs and UI

Replace hardcoded memory.dnspegasus.net references throughout README
with the generic memory.example.com placeholder (matches .env.example).

In tokens-manager.tsx, the claude-mcp-add snippet shown to users now
derives the host from PUBLIC_URL via a server-side prop instead of a
hardcoded literal, so any deployer sees their own URL in the snippet.

Prepares the repo for public mirroring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 08:58:57 -07:00
co-authored by Claude Opus 4.7
parent d1d4c60f2d
commit 0afa9e86ae
3 changed files with 23 additions and 15 deletions
+11 -11
View File
@@ -134,7 +134,7 @@ Copy `.env.example` and fill in the values below.
| Variable | Mode | What it is |
|---|---|---|
| `PUBLIC_URL` | both | Full external URL of this app, e.g. `https://memory.dnspegasus.net`. Used by Auth.js for callbacks and by the MCP route for resource metadata. |
| `PUBLIC_URL` | both | Full external URL of this app, e.g. `https://memory.example.com`. Used by Auth.js for callbacks and by the MCP route for resource metadata. |
| `APP_PORT` | A | Host port the app listens on for the external proxy. Default `3000`. |
| `APP_BIND` | A | Interface to bind on. Use `127.0.0.1` to only accept traffic from a proxy on the same host. Default `0.0.0.0`. |
| `APP_HOSTNAME` | B | Hostname only (no scheme). Caddy uses it for the TLS site block. |
@@ -257,7 +257,7 @@ shape is the same on any OIDC provider; the UI labels differ:
- **Client Secret:** auto-generated → copy to `.env` as `OIDC_CLIENT_SECRET_WEB`
- **Redirect URIs / Origins:**
```
https://memory.dnspegasus.net/api/auth/callback/oidc
https://memory.example.com/api/auth/callback/oidc
```
(replace with your `PUBLIC_URL`)
- **Signing Key:** select your `authentik Self-signed Certificate`
@@ -267,7 +267,7 @@ Save. Then **Admin → Applications → Applications → Create**:
- **Name / Slug:** `shared-memory` (the slug becomes the path in the issuer URL)
- **Provider:** `shared-memory-web`
- **Launch URL:** `https://memory.dnspegasus.net/`
- **Launch URL:** `https://memory.example.com/`
The slug is what makes `OIDC_ISSUER` end with `.../application/o/shared-memory/`.
@@ -330,7 +330,7 @@ Two paths, in order of preference:
claude mcp add --transport http --scope user \
--client-id <OIDC_CLIENT_ID_MCP> \
--callback-port 33418 \
shared-memory https://memory.dnspegasus.net/api/mcp
shared-memory https://memory.example.com/api/mcp
```
What happens:
@@ -359,23 +359,23 @@ in this case is hosted by *this* server:
claude mcp add --transport http --scope user \
--client-id <OIDC_CLIENT_ID_MCP> \
--callback-port 0 \
shared-memory https://memory.dnspegasus.net/api/mcp
shared-memory https://memory.example.com/api/mcp
```
When the loopback listener times out, Claude Code prompts you to paste the
callback URL. Open the authorize URL Claude Code printed in your browser,
sign in, and your IdP redirects to
`https://memory.dnspegasus.net/auth/cli-callback?code=…`. That page shows
`https://memory.example.com/auth/cli-callback?code=…`. That page shows
the `code` and the full URL with copy buttons — paste either back into
Claude Code's prompt to complete the flow.
The manual-fallback URI must be registered on your MCP client too:
`https://memory.dnspegasus.net/auth/cli-callback`.
`https://memory.example.com/auth/cli-callback`.
### C. Static bearer token (no browser at all)
For fully headless / CI scenarios, mint a long-lived HMAC token at
`https://memory.dnspegasus.net/connect` and pass it via `--header`. See
`https://memory.example.com/connect` and pass it via `--header`. See
the `/connect` page for the exact `claude mcp add` command it generates
for you.
@@ -441,12 +441,12 @@ config for this app looks like:
```haproxy
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/memory.dnspegasus.net.pem alpn h2,http/1.1
bind *:443 ssl crt /etc/haproxy/certs/memory.example.com.pem alpn h2,http/1.1
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Host %[req.hdr(host)]
http-request set-header X-Forwarded-For %[src]
acl host_memory hdr(host) -i memory.dnspegasus.net
acl host_memory hdr(host) -i memory.example.com
use_backend shared_memory if host_memory
backend shared_memory
@@ -464,7 +464,7 @@ Things to verify:
the OIDC callback URL — without them, the callback may point at
`http://...:3000` and Authentik will reject it.
- The Authentik Web-UI provider's **Redirect URI** is the public callback,
not the internal one. E.g. `https://memory.dnspegasus.net/api/auth/callback/oidc`.
not the internal one. E.g. `https://memory.example.com/api/auth/callback/oidc`.
If your HAProxy lives on a different host than Docker, change `127.0.0.1`
to the Docker host's address (and confirm `APP_BIND=0.0.0.0` so the port
@@ -1,6 +1,7 @@
import { revalidatePath } from "next/cache";
import { and, asc, desc, eq, isNull } from "drizzle-orm";
import { auth } from "@/auth";
import { env } from "@/lib/env";
import { db } from "@/lib/db/client";
import { cliTokens, projects, users } from "@/lib/db/schema";
import {
@@ -156,6 +157,7 @@ export default async function TokensPage() {
key: p.key,
displayName: p.displayName,
}))}
publicUrl={env().PUBLIC_URL}
/>
</CardBody>
</Card>
@@ -28,11 +28,12 @@ interface Props {
action: (prev: CreateTokenState, formData: FormData) => Promise<CreateTokenState>;
ttlDays: number;
projects: ProjectOption[];
publicUrl: string;
}
const initial: CreateTokenState = { token: null, error: null, projectKey: null };
export default function TokensManager({ action, ttlDays, projects }: Props) {
export default function TokensManager({ action, ttlDays, projects, publicUrl }: Props) {
const [state, formAction, pending] = useActionState(action, initial);
if (state.token) {
@@ -49,7 +50,7 @@ export default function TokensManager({ action, ttlDays, projects }: Props) {
</pre>
<details className="text-xs text-fg-muted">
<summary className="cursor-pointer">claude mcp add command</summary>
<pre className="mt-2">{buildMcpAddSnippet(state.token, state.projectKey)}</pre>
<pre className="mt-2">{buildMcpAddSnippet(state.token, state.projectKey, publicUrl)}</pre>
</details>
<p className="text-xs text-fg-subtle">
Valid for {ttlDays} days. Revoke individually below if it leaks.
@@ -120,14 +121,19 @@ function ProjectSelect({ projects }: { projects: ProjectOption[] }) {
);
}
function buildMcpAddSnippet(token: string, projectKey: string | null): string {
function buildMcpAddSnippet(
token: string,
projectKey: string | null,
publicUrl: string,
): string {
const headerLines = [` --header "Authorization: Bearer ${token}"`];
if (projectKey) {
headerLines.push(` --header "X-Project-Key: ${projectKey}"`);
}
const base = publicUrl.replace(/\/+$/, "");
return [
"claude mcp add --transport http --scope user \\",
...headerLines.map((l) => `${l} \\`),
" shared-memory https://memory.dnspegasus.net/api/mcp",
` shared-memory ${base}/api/mcp`,
].join("\n");
}