All apps

Phone a Friend

For when your agent would rather ask than guess.

A small MCP server you run yourself. Your AI agent asks people questions, they answer through a link in the browser, and the agent reads the answers when it gets back to the work.

Your agent, over MCP

ask_questions({
  questions: [{
    text: "Should guest checkout ask for a phone number?"
  }]
})
// later…
list_answers()

Pat, in the browser

Should guest checkout ask for a phone number?

Only if they pick delivery. Couriers need it, nobody else does.

Pat Example · 4 min ago

Answered

How it works

Agents are great until they hit a question only a person can answer. Then they either guess, or someone ends up playing postman, copying questions out to people and answers back in. This gives the agent somewhere to ask directly, without anyone sitting in the chat waiting.

The agent asks

It opens a session, attaches the docs or screenshots it's asking about, posts its questions and makes a share link.

People answer

Anyone with the link types their name once and answers, or says they don't know. No account, no app to install.

The agent follows up

Next time it checks, it reads the answers, asks follow-ups in the same thread, and accepts or closes each question.

Get started

You need Docker, and an MCP client such as Claude Code or VS Code with GitHub Copilot.

  1. 1

    Run the container

    Everything it keeps (the database, screenshots and its cookie secret) lives in the feedback-data volume, so you can stop, upgrade and restart it without losing anything.

    docker run -d --name feedback -p 8080:8080 -v feedback-data:/data \
      ghcr.io/nickmza/curly-octo-journey:latest

    Check it's up with curl http://localhost:8080/healthz.

  2. 2

    Create a project and an API key

    A project groups an agent's sessions, and its API key is what the agent connects with. The key is shown once.

    docker exec feedback feedback create-project --name "My team"
    # Created project "My team" (3dd9…)
    # API key (shown once, store it safely): afk_…

    If you'd rather click: start the container with ADMIN_KEY set to 16 or more random characters and open /admin, or turn on sign-in (below) so people create their own projects.

  3. 3

    Connect your agent

    The MCP endpoint is /mcp over Streamable HTTP, with the API key as a bearer token. For Claude Code:

    claude mcp add --transport http feedback http://localhost:8080/mcp \
      --header "Authorization: Bearer afk_…"

    For VS Code with GitHub Copilot, add this to .vscode/mcp.json. VS Code asks for the key the first time the server starts and stores it securely, so it stays out of git. Then switch Copilot Chat to Agent mode and start the feedback server.

    {
      "inputs": [
        { "type": "promptString", "id": "feedback-api-key", "description": "Phone a Friend API key (afk_…)", "password": true }
      ],
      "servers": {
        "feedback": {
          "type": "http",
          "url": "http://localhost:8080/mcp",
          "headers": { "Authorization": "Bearer ${input:feedback-api-key}" }
        }
      }
    }

    Clients that only start local (stdio) servers can reach it through mcp-remote:

    {
      "mcpServers": {
        "feedback": {
          "command": "npx",
          "args": ["mcp-remote", "http://localhost:8080/mcp", "--allow-http", "--header", "Authorization: Bearer afk_…"]
        }
      }
    }
  4. 4

    Ask something

    Talk to the agent in plain words and it picks the tools. For example:

    Use the feedback tools to ask me whether the setup steps in the README
    are clear, and what's missing. Then give me the share link.

    Open the link it gives you, type your name, and answer.

  5. 5

    Put it where your people can reach it

    Reviewers open share links in their own browser, so the server has to be reachable from their machines. localhost is fine for trying it on your own. For a team, run it on a shared host, or behind a reverse proxy or a tunnel, and set PUBLIC_URL to that address, since share links are built from it. With an https:// address the reviewer cookie is marked Secure too.

    docker run -d --name feedback -p 8080:8080 -v feedback-data:/data \
      -e PUBLIC_URL=https://feedback.example.com \
      ghcr.io/nickmza/curly-octo-journey:latest

Optional: let people sign in

Point it at Keycloak or any OpenID Connect provider (Entra ID, Google, Auth0, Authentik, Zitadel) and anyone who can sign in can create and manage their own projects on My projects. Answering questions never needs a sign-in.

  1. Find your provider's issuer URL: the issuer value at <issuer>/.well-known/openid-configuration, for example https://keycloak.example.com/realms/acme. Copy it exactly; the app checks it character for character.
  2. Register a web application (in Keycloak: an OpenID Connect client with Client authentication on and only Standard flow ticked). Set the redirect URI to <PUBLIC_URL>/auth/callback and the post-logout redirect URI to <PUBLIC_URL>/.
  3. Optionally require PKCE with S256. The app always sends it.
  4. Copy the client secret and start the container with sign-in on:
docker run -d --name feedback -p 8080:8080 -v feedback-data:/data \
  -e PUBLIC_URL=https://feedback.example.com \
  -e OIDC_ISSUER=https://keycloak.example.com/realms/acme \
  -e OIDC_CLIENT_ID=phone-a-friend \
  -e OIDC_CLIENT_SECRET=<the secret> \
  ghcr.io/nickmza/curly-octo-journey:latest

To check it, open <PUBLIC_URL>/api/account: it should say "signInEnabled":true, and a Sign in button appears at the top right. If the provider uses a certificate from your company's own CA, mount its root certificate and set NODE_EXTRA_CA_CERTS to its path. Behind a proxy, add the provider's domain to NO_PROXY. docker logs feedback says why a sign-in failed.

What else is in the box

Screenshots both ways

The agent can show a screenshot with a question, and reviewers can attach one to an answer. Images are re-encoded, which strips location data.

Webhooks

New links, questions and replies post a small JSON message you can route to Teams, Slack, Zapier or your own code.

Reviewer threads

Reviewers can raise their own questions, ideas and bugs. The agent sees them but never acts on them by itself.

One SQLite file

No database to run. Rate limits on links and replies, and a strict Content-Security-Policy, are on by default.

The agent's tools:

create_sessionattach_docsask_questionscreate_share_linkrevoke_share_linklist_sessionsget_sessionlist_answersget_screenshotpost_followupaccept_answerclose_questionarchive_session

I built this because I got tired of playing postman between my agents and everyone else. Here's how that went.

Free to use, at your own risk. It comes with no warranty and no promise of support.