Files
familiar/doc/getting-started.md
Latte df9e06a3e7
CI / lint (pull_request) Successful in 55s
docker / lint (pull_request) Successful in 56s
CI / test (pull_request) Successful in 1m6s
docker / test (pull_request) Successful in 1m4s
CI / publish (pull_request) Has been skipped
docker / docker (pull_request) Failing after 1m11s
docs: deployment guide + per-client setup + connect matrix
- doc/deployment.md: run familiar as a remote MCP server — secure defaults,
  bearer vs OAuth modes, the full env-var reference, one-time login / token-store
  provisioning, the published images, docker compose, and TLS reverse-proxy
  blocks for nginx (proxy_buffering off + long read timeout), Caddy, and Traefik.
- doc/clients/: one page per client with exact working steps — Claude Code,
  VS Code (.vscode/mcp.json with a masked token input, and the workspace
  .mcp.json header gotcha), Mistral Le Chat, Claude Desktop + Cowork (mcp-remote
  bridge, per-OS config paths), and Claude web (oauth mode + external IdP, with
  "use Desktop + bearer" as the simpler alternative). Plus a clients/ index.
- README: a "Connect a client" matrix (client -> auth -> guide) and a compact
  "Deploy with Docker" section linking to doc/deployment.md; oauth mode noted.
- doc/README.md index: rows for Deployment and Client setup.
- doc/getting-started.md: pointer from the HTTPS quickstart to the full docs.
- CLAUDE.md: FAMILIAR_AUTH_MODE / FAMILIAR_OAUTH_* / FAMILIAR_ALLOW_INSECURE_BIND
  and /healthz in the transport note; the split ci.yml / docker.yml workflows.

Deployment docs live under the existing doc/ tree (the repo uses doc/, not a
separate docs/) to keep a single documentation directory.
2026-07-04 19:26:33 +02:00

7.5 KiB

Getting Started

This guide takes you from a fresh clone to a working AI assistant that can read your EVE Online account and act on it when you ask.

1. Prerequisites

  • uv — the Python project/dependency manager familiar is built around. Install it first (see the uv docs for your platform).
  • Python 3.11+ — uv will fetch a suitable interpreter if you don't have one.
  • An EVE Online account (for the authenticated tools; public market/universe lookups work without one).
  • An MCP-capable client: Claude Code, Claude Desktop, Cowork, or any other MCP client.

2. Install

uv sync          # install the project and all dependencies (incl. the dev group)

There is no separate build step for local use. uv run familiar runs the server straight from source.

3. Log in (EVE SSO)

familiar uses EVE's Single Sign-On with PKCE — no client secret, nothing to configure. Run the login once per character:

uv run familiar login    # opens your browser to the EVE SSO consent page

The browser opens CCP's login page. Approve the requested scopes; the callback lands on localhost:8765, the code is exchanged for tokens, and the (rotating) refresh token is stored encrypted on disk. You'll see a "login complete" page — close the tab and return to the terminal.

To add more characters, switch EVE accounts in the browser and run login again. All characters live in one encrypted store:

uv run familiar status   # list logged-in characters
uv run familiar logout NAME   # forget one character (by name or id)
uv run familiar logout        # forget ALL characters

Changing scopes: if the set of requested scopes changes (e.g. a new familiar version adds tools), you must log in again to grant them.

See Authentication for the full flow and the scope list.

4. Connect to your AI client

Claude Code

claude mcp add familiar -- uv --directory /path/to/familiar run familiar

Claude Desktop

Add this to claude_desktop_config.json (replace the directory with your clone's absolute path):

{
  "mcpServers": {
    "familiar": {
      "command": "uv",
      "args": ["--directory", "/path/to/familiar", "run", "familiar"]
    }
  }
}

The client launches uv run familiar with no arguments, which starts the MCP server over stdio — the transport MCP clients speak.

5. First queries

Ask in natural language. The AI picks the right tools:

  • "Is the familiar server up?" → calls ping.
  • "What's Tritanium worth in Jita?" → get_market_price.
  • "Compare Plex prices across all trade hubs." → compare_hubs.
  • "How much ISK do I have across all my characters?" → wallet tools, per character.
  • "Where are my characters right now?" → location tools.
  • "Set a waypoint to Amarr for my main." → set_waypoint (a write — previewed first; see below).

6. Write actions

Write tools (send mail, set waypoints, edit contacts/fittings, fleet commands, open windows, PI) are enabled by default, but every write is still previewed unless you pass confirm=true, and each executed write is logged. To block all writes globally:

uv run familiar writes disable    # turn writes off
uv run familiar writes enable     # turn them back on
uv run familiar writes            # show current state

Full details in Write Safety.

7. Serve over HTTPS (remote MCP)

Everything above uses stdio — the local transport an MCP client launches on your machine. To reach familiar from a remote MCP client (for example a chat.mistral.ai custom connector), run the opt-in streamable-HTTP transport instead. stdio stays the default; nothing here changes how uv run familiar behaves with no arguments.

This section is a quickstart. For the full production setup — Docker, reverse proxy (nginx / Caddy / Traefik), the bearer vs OAuth modes, and the env-var reference — see deployment, and for exact per-client steps see doc/clients/.

FAMILIAR_HTTP_TOKEN=$(openssl rand -hex 32) uv run familiar serve

familiar serve binds 127.0.0.1:8080/mcp behind a TLS-terminating reverse proxy. It refuses to start without FAMILIAR_HTTP_TOKEN — an internet-reachable account window must never run unauthenticated. A request without a valid Authorization: Bearer <token> gets 401 with a WWW-Authenticate: Bearer header; a valid token lets the MCP handshake through.

Variable Default Meaning
FAMILIAR_HTTP_TOKEN (required) Bearer token the client must send; serve refuses to start without it.
FAMILIAR_HTTP_HOST 127.0.0.1 Bind address. Leave loopback; let the proxy face the internet.
FAMILIAR_HTTP_PORT 8080 Bind port.
FAMILIAR_HTTP_PATH /mcp MCP endpoint path.
FAMILIAR_ENABLE_WRITES (unset) In HTTP mode writes default off; set to 1/true to opt in.

Writes default off over HTTP. A network-reachable, LLM-driven endpoint should not send mail or set waypoints unless you opt in explicitly with FAMILIAR_ENABLE_WRITES=1. (Over stdio they stay on by default, as in section 6.)

nginx location block

Streamable HTTP holds a long-lived response open, so turn off buffering and raise the read timeout:

location /mcp {
    proxy_pass http://127.0.0.1:8080/mcp;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;          # stream events straight through
    proxy_read_timeout 3600s;     # don't cut long-lived MCP sessions
}

Logging in on a headless server

familiar login needs a local browser and the localhost:8765 callback. On a headless box:

  • Headless login — print the SSO URL, authorize in any browser, paste the redirected URL back:

    uv run familiar login --no-browser
    

    The localhost page the browser lands on fails to load — that's expected; copy its address bar (it holds the code) and paste it at the prompt.

  • Copy the store — run familiar login on your desktop, then copy the encrypted store (token.enc + key from your FAMILIAR_DATA_DIR) to the server's data dir.

Run it in Docker

CI publishes a container image on every merge to dev/main (git.hiddenden.cafe/hiddenden/familiar, tags :dev and :main/:latest). It runs familiar serve as a non-root user on port 8080, with a /healthz healthcheck and the encrypted token store under a /data volume. Use the bundled docker-compose.yml: copy .env.example to .env, set FAMILIAR_HTTP_TOKEN, put your logged-in store in ./data, then docker compose up -d. It publishes on 127.0.0.1:8080 only — the nginx block above proxies to it. The container refuses to start without FAMILIAR_HTTP_TOKEN.

Add it in Mistral

In chat.mistral.ai: Intelligence → Connectors → Add custom connector, set the URL to https://your-host/mcp, choose Bearer Token auth, and paste your FAMILIAR_HTTP_TOKEN.

8. Verify everything works

uv run pytest          # full test suite (fails under 80% coverage)
uv run familiar        # start the server manually (Ctrl-C to stop) — it waits on stdio

If uv run familiar starts without error and familiar status shows your characters, you're ready.