> ## 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.

# Apps

Apps are the **organizational units** for capabilities in FrontMCP. Each app groups related **tools**, **resources**, and **prompts** into a cohesive domain, along with **providers**, **adapters**, and **plugins** that support them.

## Why Apps?

In FrontMCP, apps provide domain boundaries and enable multi-tenant architectures:

| Aspect       | App                       | Server                 | Tool                 |
| ------------ | ------------------------- | ---------------------- | -------------------- |
| **Purpose**  | Group capabilities        | Host apps              | Execute actions      |
| **Scope**    | Feature/domain boundary   | Process entry point    | Single operation     |
| **Contains** | Tools, resources, prompts | Apps, global providers | Input → Output logic |

Apps are ideal for:

* **Feature domains** — billing, users, analytics as separate concerns
* **Team boundaries** — each team owns their app
* **Multi-tenant** — isolate per customer with `splitByApp: true`
* **Third-party integrations** — wrap OpenAPI adapters per service

***

## Minimal App

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { App } from '@frontmcp/sdk';

@App({
  id: 'hello',
  name: 'Hello App',
  tools: [],
})
export default class HelloApp {}
```

Add it to your server:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@FrontMcp({ info: { name: 'Demo', version: '0.1.0' }, apps: [HelloApp] })
export default class Server {}
```

***

## App options

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@App({
  id?: string,
  name: string,
  description?: string,
  providers?: ProviderType[],
  authProviders?: AuthProviderType[],
  plugins?: PluginType[],
  adapters?: AdapterType[],
  tools?: ToolType[],
  resources?: ResourceType[],
  prompts?: PromptType[],
  auth?: AuthOptions,                 // app‑default auth (overrides server auth)
  standalone?: 'includeInParent' | boolean, // isolate scope / expose separately
})
```

**Field descriptions:**

| Field           | Description                                             |
| --------------- | ------------------------------------------------------- |
| `id`            | Unique identifier; used in URLs when `splitByApp: true` |
| `name`          | Human-readable display name                             |
| `description`   | Optional description for documentation                  |
| `providers`     | DI providers scoped to this app                         |
| `authProviders` | Authentication providers for this app                   |
| `plugins`       | Plugins attached at app scope                           |
| `adapters`      | Adapters (e.g., OpenAPI) that generate tools/resources  |
| `tools`         | Tool classes registered to this app                     |
| `resources`     | Resource classes registered to this app                 |
| `prompts`       | Prompt classes registered to this app                   |
| `auth`          | App-level auth config (overrides server auth)           |
| `standalone`    | Isolation mode: `true`, `false`, or `'includeInParent'` |

**Scoping & auth**

* If the server uses **`splitByApp: true`**, each app is isolated and **must** configure its own auth (server-level `auth` is disallowed).
* `standalone: true` makes the app expose its own scope/entry; `'includeInParent'` lists it under the parent while keeping isolation.

**Dependency resolution**

* Providers resolve **tool → app → server**.
* Plugins/adapters attach at app scope; generated items inherit the app’s policies and provenance.

***

## Example: app with adapter + providers

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@App({
  id: 'billing',
  name: 'Billing',
  providers: [DbProvider, CacheProvider],
  adapters: [
    // e.g. OpenAPI adapter that generates tools/resources from a spec
    BillingOpenApiAdapter,
  ],
})
export default class BillingApp {}
```

***

## Remote Apps

Connect to external MCP servers and proxy their tools, resources, and prompts through your gateway:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@FrontMcp({
  info: { name: 'Gateway', version: '1.0.0' },
  apps: [
    // Remote MCP server connected via URL
    {
      name: 'mintlify-docs',
      urlType: 'url',
      url: 'https://mintlify.com/docs/mcp',
      namespace: 'mintlify', // Tools prefixed as 'mintlify:ToolName'
      transportOptions: {
        timeout: 60000,
        retryAttempts: 2,
      },
      standalone: false,
    },
    // Local MCP server on different port
    {
      name: 'local-service',
      urlType: 'url',
      url: 'http://localhost:3099/',
      namespace: 'local',
      transportOptions: {
        timeout: 30000,
        retryAttempts: 3,
      },
    },
  ],
})
export default class GatewayServer {}
```

### Remote App Options

| Option             | Type      | Description                                                             |
| ------------------ | --------- | ----------------------------------------------------------------------- |
| `name`             | `string`  | Unique identifier for the remote app                                    |
| `urlType`          | `'url'`   | Must be `'url'` for remote apps                                         |
| `url`              | `string`  | MCP server endpoint URL                                                 |
| `namespace`        | `string`  | Prefix for tool/resource/prompt names (e.g., `mintlify:SearchMintlify`) |
| `transportOptions` | `object`  | Connection settings (timeout, retry attempts)                           |
| `standalone`       | `boolean` | If `true`, don't merge with parent scope                                |

### Transport Options

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
transportOptions: {
  timeout: 60000,      // Request timeout in milliseconds
  retryAttempts: 3,    // Number of retry attempts on failure
}
```

### Caching Remote Tools

Remote tools don't have cache metadata, so use the `toolPatterns` option in CachePlugin:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@FrontMcp({
  apps: [
    {
      name: 'external-api',
      urlType: 'url',
      url: 'https://api.example.com/mcp',
      namespace: 'api',
    },
  ],
  plugins: [
    CachePlugin.init({
      type: 'memory',
      defaultTTL: 300,
      toolPatterns: ['api:*'], // Cache all tools from this namespace
    }),
  ],
})
```

See the [Cache Plugin documentation](/frontmcp/plugins/cache-plugin#caching-remote-tools) for more details on pattern-based caching.

### Use Cases for Remote Apps

<CardGroup cols={2}>
  <Card title="MCP Gateway" icon="diagram-project">
    Aggregate multiple MCP servers behind a single endpoint with unified authentication
  </Card>

  <Card title="Service Mesh" icon="network-wired">
    Connect to internal microservices running as separate MCP servers
  </Card>

  <Card title="Third-Party Integration" icon="plug">
    Proxy external MCP services like Mintlify, adding caching and rate limiting
  </Card>

  <Card title="Development" icon="code">
    Test against local MCP servers running on different ports
  </Card>
</CardGroup>

***

## Best Practices

**Do:**

* Use descriptive `id` values that work as URL segments
* Group related tools, resources, and prompts in the same app
* Configure `standalone: true` when apps need isolated auth
* Use adapters to generate tools from OpenAPI specs

**Don't:**

* Put unrelated functionality in the same app
* Mix authentication strategies within a single app
* Create apps with only one tool (use the server directly)
