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

# Authentication Demo Servers

> Run the Nx sample servers that showcase public, transparent, and orchestrated authentication modes.

FrontMCP bundles three ready-to-serve authentication demos under `apps/e2e/**`. Each project runs the same Notes + Tasks apps but wires a different auth mode, transport policy, and consent experience so you can validate clients before touching your own code.

## Projects at a glance

| Project                 | Mode                   | Default port | Highlights                                                                      | Serve command                                     |
| ----------------------- | ---------------------- | ------------ | ------------------------------------------------------------------------------- | ------------------------------------------------- |
| `demo-e2e-public`       | `public`               | `3003`       | Anonymous sessions with scoped tools, Streamable HTTP + JSON fallback           | `pnpm nx serve demo-e2e-public --port 3003`       |
| `demo-e2e-orchestrated` | `orchestrated` (local) | `3005`       | Stateful sessions, consent UI, incremental auth controls                        | `pnpm nx serve demo-e2e-orchestrated --port 3005` |
| `demo-e2e-transparent`  | `transparent`          | `3004`       | Proxies tokens to a remote IdP while keeping local consent + transport policies | `pnpm nx serve demo-e2e-transparent --port 3004`  |

<Note>
  All commands assume `pnpm install` has already been run at the repo root. Replace the port if it conflicts with another service.
</Note>

## Run a demo locally

<Steps>
  <Step title="Pick a project">
    Decide which auth mode to explore (`demo-e2e-public`, `demo-e2e-transparent`, or `demo-e2e-orchestrated`).
  </Step>

  <Step title="Configure environment">
    Transparent mode needs an upstream IdP. Export `IDP_PROVIDER_URL` and `IDP_EXPECTED_AUDIENCE` before serving:

    ```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    export IDP_PROVIDER_URL="https://auth.example.com"
    export IDP_EXPECTED_AUDIENCE="https://api.example.com"
    ```
  </Step>

  <Step title="Serve the project">
    Run `pnpm nx serve <project> --port <port>` and wait for the `Listening on` log. Requests are available at `http://localhost:<port>`.

    <Check>
      `curl http://localhost:<port>/health` returns `ok` when the server is ready.
    </Check>
  </Step>
</Steps>

***

## demo-e2e-public: instant anonymous access

```ts title="apps/e2e/demo-e2e-public/src/main.ts" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@FrontMcp({
  auth: {
    mode: 'public',
    sessionTtl: 3600,
    anonymousScopes: ['anonymous'],
  },
  transport: {
    protocol: 'full',  // All protocols enabled, relaxed sessions for testing
  },
});
```

* Exercises the `auth.publicAccess` path without any login UI.
* Uses the `full` protocol preset—all transports enabled with relaxed session requirements—for easy smoke tests.

<Tip>
  Use this project with `@frontmcp/testing` when you want fast, anonymous fixtures that still cover transport-level behavior.
</Tip>

***

## demo-e2e-orchestrated: built-in OAuth server

```ts title="apps/e2e/demo-e2e-orchestrated/src/main.ts" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@FrontMcp({
  auth: {
    mode: 'orchestrated',
    type: 'local',
    consent: {
      enabled: true,
      groupByApp: true,
      showDescriptions: true,
      requireSelection: true,
    },
    allowDefaultPublic: false,
  },
  transport: {
    protocol: 'full',  // All protocols enabled, relaxed sessions for testing
    sessionMode: 'stateful',
  },
});
```

* Spins up the full OAuth 2.1 stack (authorization code + PKCE) entirely inside FrontMCP.
* Shows the consent UI grouping tools by app, plus incremental auth defaults.
* Uses the same transport defaults documented in [Transport controls](/frontmcp/servers/server#transport) so you can compare behavior with production builds.

<Warning>
  The demo login accepts any email address. Replace it with a real IdP before exposing the flow to users.
</Warning>

***

## demo-e2e-transparent: pass-through tokens

```ts title="apps/e2e/demo-e2e-transparent/src/main.ts" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@FrontMcp({
  auth: {
    mode: 'transparent',
    remote: {
      provider: process.env.IDP_PROVIDER_URL!,
      dcrEnabled: false,
    },
    expectedAudience: process.env.IDP_EXPECTED_AUDIENCE!,
    requiredScopes: [],
    allowAnonymous: false,
  },
  transport: {
    protocol: 'full',  // All protocols enabled, relaxed sessions for testing
  },
});
```

* Validates upstream JWTs while reusing the same consent UI and transport policies.
* Demonstrates how to forward-declare an IdP without shipping secrets—set `IDP_PROVIDER_URL`/`IDP_EXPECTED_AUDIENCE` per environment.
* Keeps anonymous access off so every tool call requires a verified token.

<Note>
  If your IdP exposes a JWKS file, frontload the URL in `remote.jwksUri` to skip metadata discovery during tests.
</Note>

***

## Test with @frontmcp/testing

You can point the Jest fixtures at any demo by spinning it up through the built-in `TestServer` helper:

```ts title="demo-public.e2e.ts" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { test, expect, TestServer } from '@frontmcp/testing';

let serverProcess;

test.beforeAll(async () => {
  serverProcess = await TestServer.startNx('demo-e2e-public', { port: 4001 });
});

test.afterAll(async () => {
  await serverProcess?.stop();
});

test.use({
  server: serverProcess?.info.baseUrl ?? 'http://localhost:4001',
  transport: 'streamable-http',
});

test('lists demo tools', async ({ mcp }) => {
  const tools = await mcp.tools.list();
  expect(tools).toContainTool('create-note');
});
```

Pair this with the [Transport controls reference](/frontmcp/servers/server#transport) to mirror the exact transports your production server exposes.

***

## What to read next

<CardGroup cols={2}>
  <Card title="Authentication Modes" icon="layer-group" href="/frontmcp/authentication/modes">
    Understand when to reach for public, transparent, or orchestrated auth.
  </Card>

  <Card title="Transport controls" icon="server" href="/frontmcp/servers/server#transport-controls">
    Dive deeper into Streamable, stateful, and stateless HTTP settings.
  </Card>
</CardGroup>
