> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Run the UI Locally

> Launch the Cognee Cloud UI on your own machine — no account required

The Cognee Cloud UI can run entirely on your local machine using `cognee.start_ui()`. This gives you the same interface as Cognee Cloud without needing an account or any cloud infrastructure.

**Before you start:**

* Complete the [Quickstart](/getting-started/quickstart) to make sure your environment is set up
* Have a valid LLM and embedding provider configured (see [Setup Configuration](/setup-configuration/overview)). You don't have to pre-configure the LLM API key — in local mode you can paste it into the UI after launch (see below).

## Start the local UI

<Steps>
  <Step title="Install Cognee">
    ```bash theme={null}
    pip install cognee
    ```
  </Step>

  <Step title="Store some memory">
    Store content with [`remember()`](/python-api/remember) before launching the UI — it ingests the data and builds the knowledge graph in one call, so the interface has something to show.

    ```python theme={null}
    import asyncio
    import cognee

    async def main():
        await cognee.remember(
            [
                "Natural language processing (NLP) is an interdisciplinary subfield of computer science.",
                "Machine learning (ML) is a subset of artificial intelligence.",
            ]
        )

    asyncio.run(main())
    ```
  </Step>

  <Step title="Launch the UI server">
    Call `cognee.start_ui()` to start the local frontend and backend servers. Setting `open_browser=True` opens the interface in your default browser automatically.

    ```python theme={null}
    import os
    import signal
    import time
    import cognee

    child_pids = []
    server = cognee.start_ui(
        pid_callback=child_pids.append,
        port=3000,
        open_browser=True,
        start_backend=True,
        backend_port=8000,
    )

    if server:
        print("UI available at http://localhost:3000")
        try:
            while server.poll() is None:
                time.sleep(1)
        except KeyboardInterrupt:
            server.terminate()
            server.wait()
            for pid in child_pids:
                if pid != server.pid:
                    os.kill(pid, signal.SIGTERM)
    ```

    The UI is available at **[http://localhost:3000](http://localhost:3000)**, and the backend API is available at **[http://localhost:8000](http://localhost:8000)**. Press `Ctrl+C` to stop the server when you are done.

    <Note>
      `start_ui()` launches the frontend in local mode. If you didn't configure an LLM API key beforehand, the Overview shows a banner with an **Add your LLM API key** modal — paste your key there and it is applied to the running backend immediately, with no `.env` edit or restart. See [LLM API key (local mode)](/cognee-cloud/ui/dashboard#llm-api-key-local-mode).
    </Note>
  </Step>
</Steps>

### Run it with Docker instead

If you have the [cognee repository](https://github.com/topoteretes/cognee) checked out, the bundled Compose file ships a `ui` profile that starts the frontend and backend together — no `pip install` or `start_ui()` call needed:

```bash theme={null}
docker compose --profile ui up
```

The UI is served on **[http://localhost:3000](http://localhost:3000)** and the backend on **[http://localhost:8000](http://localhost:8000)**, the same ports `start_ui()` uses.

## Full example

The complete script below combines all three steps:

```python theme={null}
import asyncio
import os
import signal
import time
import cognee


async def main():
    # Store sample data — ingests it and builds the knowledge graph
    await cognee.remember(
        [
            "Natural language processing (NLP) is an interdisciplinary subfield of computer science and information retrieval.",
            "Machine learning (ML) is a subset of artificial intelligence that focuses on algorithms and statistical models.",
        ]
    )

    # Start the UI and backend
    child_pids = []
    server = cognee.start_ui(
        pid_callback=child_pids.append,
        port=3000,
        open_browser=True,
        start_backend=True,
        backend_port=8000,
    )

    if server:
        print("UI available at http://localhost:3000")
        print("Press Ctrl+C to stop...")
        try:
            while server.poll() is None:
                time.sleep(1)
        except KeyboardInterrupt:
            server.terminate()
            server.wait()
            for pid in child_pids:
                if pid != server.pid:
                    os.kill(pid, signal.SIGTERM)
    else:
        print("Failed to start the UI server.")


if __name__ == "__main__":
    asyncio.run(main())
```

<Note>
  `cognee.start_ui()` launches the same frontend that powers Cognee Cloud. Data stays on your machine — nothing is sent to any external service.
</Note>

## Add an LLM API key from the dashboard

Cognee needs an LLM API key to process uploads. If you launch `cognee.start_ui()` or `cognee-cli -ui` without `LLM_API_KEY` set in your environment, the dashboard detects the missing key on load and shows a yellow warning banner:

> No LLM API key configured — Cognee can't process uploads until you add one.

Click **Add your API key now →** to open a modal, paste your key, and save. The UI sends the key to the running backend via `POST /v1/settings`, which also exports it as `LLM_API_KEY` into the backend process environment — the next upload works immediately, with no restart or `.env` edit required.

The modal uses whatever provider and model the backend is currently configured with (defaults to `openai` / `gpt-5-mini`). To use a different provider or model, set `LLM_PROVIDER` and `LLM_MODEL` in your environment before launching the UI, then paste the matching API key in the modal.

Saving from this modal requires the signed-in account to be a [superuser](/core-concepts/multi-user-mode/permissions-system/users#superuser-privileges). The default user Cognee creates for you is one, so the local single-user flow above works as described. In a multi-user deployment, a non-superuser account gets `403 Forbidden` from `POST /v1/settings` — have an administrator save the key, or set `LLM_API_KEY` in the backend's environment instead.

<Note>
  The pasted key lives in the backend process only. It is not persisted to a `.env` file, so it will be lost when the backend restarts. For a permanent setup, add `LLM_API_KEY` (and any other provider variables) to your `.env` before starting the UI.
</Note>

## Connect the UI to the backend

The local UI and the Cognee backend API are separate servers. When you use `cognee.start_ui(..., start_backend=True)` or `cognee-cli -ui`, the UI runs on **port 3000** and the backend runs on **port 8000** by default. If you run either service on a different host or port, configure both the frontend's backend URL and the backend's allowed browser origins.

| Variable                    | Read by           | Default                                                                                                   | Purpose                                                                                                                          |
| --------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_LOCAL_API_URL` | Local UI frontend | In the browser, the page's own protocol and hostname on port `8000`; server-side, `http://localhost:8000` | Backend API base URL used by the local UI. Set this when the backend is not reachable at the default local address.              |
| `UI_APP_URL`                | Backend API       | `http://localhost:3000`                                                                                   | Origin allowed through the backend's CORS policy. Set this to the UI's URL when you serve the UI on a different host or port.    |
| `CORS_ALLOWED_ORIGINS`      | Backend API       | —                                                                                                         | Comma-separated list of allowed origins. When set, it takes precedence over `UI_APP_URL` — use it to allow more than one origin. |

When `NEXT_PUBLIC_LOCAL_API_URL` is not set, the UI resolves the backend address in the browser from the page you are on, so API calls stay on the host you typed in the address bar. The resolution order is:

1. `NEXT_PUBLIC_LOCAL_API_URL`, if set — used verbatim, in the browser and on the server.
2. In the browser — the current page's protocol and hostname, with the port pinned to `8000`. Loading the UI on `http://127.0.0.1:3000` targets `http://127.0.0.1:8000`; on `http://localhost:3000` it targets `http://localhost:8000`.
3. During server-side rendering, where there is no browser location — `http://localhost:8000`.

Only the protocol and hostname come from the browser; the port is always `8000` unless you override the variable. Set `NEXT_PUBLIC_LOCAL_API_URL` when the backend lives on a different machine than the UI, or on a port other than `8000`.

Deriving the host in the browser keeps the auth cookie on the host you are browsing, but it does not exempt you from the backend's CORS policy. `start_ui()` and `cognee-cli -ui` start the backend with the default allowed origin `http://localhost:3000`, so browsing the UI on any other host — `http://127.0.0.1:3000` included — needs a matching `UI_APP_URL` (or `CORS_ALLOWED_ORIGINS`) on the backend:

```dotenv theme={null}
# .env — browsing the UI on 127.0.0.1 instead of localhost
UI_APP_URL=http://127.0.0.1:3000
```

For example, if the UI and backend are served from different machines:

```dotenv theme={null}
# .env
NEXT_PUBLIC_LOCAL_API_URL=http://192.168.1.20:8000
UI_APP_URL=http://192.168.1.50:3000
```

Restart the UI and backend after changing these values so both processes read the updated environment.

<Note>
  `UI_APP_URL` is unrelated to the MCP server's `API_URL` variable, which instead points the [Cognee MCP server](/cognee-mcp/mcp-quickstart#api-mode-shared-knowledge-graph) at a self-hosted backend. The two are easy to confuse because both wire a component to the Cognee API.
</Note>

## Troubleshooting the local UI

<AccordionGroup>
  <Accordion title="&#x22;Cognee frontend is not available&#x22; / prompted to download">
    In a pip-installed package, the frontend is not bundled in the runtime environment. On first launch, `start_ui()` looks for a local `cognee-frontend` directory and, if it can't find one, prints:

    > The cognee frontend is not available on your system.

    It then asks `Would you like to download the frontend now? (y/N)`. Answer `y` to download the frontend that matches your installed version from GitHub releases and cache it in `~/.cognee/ui-cache/` (a one-time setup per cognee version, reused offline afterwards).

    To skip the prompt and download automatically, pass `auto_download=True` to `cognee.start_ui()`. The `cognee-cli -ui` command already sets this, so it never prompts.

    If the download fails with a `404`, the release for your version does not exist on GitHub yet or the installed version is a development/mismatched build. Install a stable release of cognee (`pip install -U cognee`) and try again.
  </Accordion>

  <Accordion title="Signing in bounces straight back to the login page, or fails on 127.0.0.1">
    The auth cookie is host-scoped, and `localhost` and `127.0.0.1` are distinct hosts to the browser even though they resolve to the same machine. If the page and the API are not on the same host, the cookie never applies to the requests that check it: the `GET /api/v1/users/me` check comes back `401` and the UI sends you back to `/local-login` on every attempt.

    The UI now derives the API host from the page you loaded, so the cookie is always set on the host you are browsing. What it does not do is widen the backend's CORS policy. If you sign in on a host other than `localhost`, work through these in order:

    * **Allow the origin you browse to.** `start_ui()` and `cognee-cli -ui` start the backend allowing only `http://localhost:3000`, so signing in on `http://127.0.0.1:3000` is refused before the cookie is ever set — the login form reports `Cannot connect to local backend at http://127.0.0.1:8000. Is it running?`. Set `UI_APP_URL` (or `CORS_ALLOWED_ORIGINS`) to the exact origin in your address bar and restart the backend — see [Connect the UI to the backend](#connect-the-ui-to-the-backend).
    * **Check `NEXT_PUBLIC_LOCAL_API_URL`.** An explicit value always wins over the browser-derived host. If it points at a different hostname than the one in your address bar, either unset it or make the two match.
    * **Clear stale cookies** for the old host after changing any of this, then sign in again.

    The simplest fix is to browse the UI on `http://localhost:3000`, which every default already covers.
  </Accordion>

  <Accordion title="localhost refuses to connect (ERR_CONNECTION_REFUSED)">
    If the browser can't reach `http://localhost:3000`, the frontend server isn't running. Check these in order:

    * **Node.js and npm are installed.** The UI runs on Next.js and needs Node.js. If either tool is missing, `start_ui()` first tries to install `nvm` and Node.js automatically on supported platforms; if that fails, it logs `Cannot start UI` and you should install Node.js from [nodejs.org](https://nodejs.org/) before relaunching.
    * **The port is free.** `start_ui()` returns `None` and logs `ports already in use` if port `3000` (frontend) or `8000` (backend) is taken. Stop the conflicting process, or pass a different `port` / `backend_port`.
    * **Give Next.js time to compile.** After launch the server prints `The UI will be available once Next.js finishes compiling`. The first compile takes a few seconds — reload once you see the `[FRONTEND]` logs report it's ready.
    * **Watch the `[FRONTEND]` logs.** If the process exits early, `start_ui()` logs `Frontend server failed to start` — the streamed `[FRONTEND]` output above it shows the underlying error (for example a failed `npm install`).
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Cognee Cloud" href="/cognee-cloud/overview" icon="cloud">
    Move to the hosted version for managed infrastructure and collaboration features.
  </Card>

  <Card title="Core Concepts" href="/core-concepts/overview" icon="brain">
    Learn about remember, recall, improve, and forget operations.
  </Card>
</CardGroup>
