Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/AI/agents.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 11
sidebar_position: 14
title: Agents
id: agents
description: "Register AI agents in DreamFactory with their own identity, role-scoped API key, and skills, and route tasks to the right agent with a deterministic capability router"
Expand Down
2 changes: 1 addition & 1 deletion docs/AI/ai-chat.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 7
sidebar_position: 10
title: AI Chat
id: ai-chat
description: Chat with your DreamFactory-governed data using AI and MCP tools. The AI queries databases, calls stored procedures, and accesses MCP services on your behalf.
Expand Down
2 changes: 1 addition & 1 deletion docs/AI/ai-connection.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 6
sidebar_position: 9
title: AI Connection
id: ai-connection
description: Connect DreamFactory to AI/LLM providers (Anthropic, OpenAI, xAI, Ollama, OpenAI-compatible) with built-in rate limiting, cost tracking, prompt logging, and fallback chains.
Expand Down
2 changes: 1 addition & 1 deletion docs/AI/ai-gateway.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 8
sidebar_position: 11
title: AI Gateway Analytics
id: ai-gateway
description: Monitor AI spend, track per-app attribution, view latency percentiles, configure budgets, enable prompt logging, and export audit events to your SIEM.
Expand Down
2 changes: 1 addition & 1 deletion docs/AI/ai-usage-monitoring-and-cost-allocation.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 9
sidebar_position: 12
title: AI Usage Monitoring & Cost Allocation
id: ai-usage-monitoring-and-cost-allocation
description: "Meter every AI request with token counts and estimated cost, attribute spend to apps, users, roles, and models, and build chargeback and showback reports from the AI Usage Analytics console or API."
Expand Down
2 changes: 1 addition & 1 deletion docs/AI/custom-tools.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 4
sidebar_position: 6
title: Custom MCP Tools
id: custom-mcp-tools
description: Create custom tools for your MCP server to extend AI assistant capabilities with API calls and JavaScript functions.
Expand Down
2 changes: 1 addition & 1 deletion docs/AI/github-scripts.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 10
sidebar_position: 13
title: GitHub-Linked Scripts
id: github-scripts
description: Link DreamFactory server scripts to GitHub repositories for version-controlled scripting with cache invalidation.
Expand Down
101 changes: 101 additions & 0 deletions docs/AI/mcp-api-key-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
sidebar_position: 4
title: API Key Authentication for MCP
id: mcp-api-key-auth
description: Let headless MCP clients authenticate to a DreamFactory MCP endpoint with a DreamFactory API key instead of OAuth — a per-service opt-in.
keywords: [MCP, Model Context Protocol, API key, X-DreamFactory-API-Key, authentication, OAuth, session token, RBAC, headless clients]
difficulty: intermediate
---

# API Key Authentication for MCP

By default, a DreamFactory MCP endpoint authenticates clients with OAuth 2.0: the client completes a browser login, obtains a token, and every request carries an `Authorization: Bearer` header. From DreamFactory 7.7.1, each MCP service can **additionally** accept a static DreamFactory API key. The setting is a per-service opt-in and is **off by default** — services that never enable it behave exactly as before.

API keys suit headless and server-to-server MCP clients that cannot complete a browser OAuth flow: CI jobs, backend agents, scheduled scripts, or plain `curl`.

## Quick Reference

| Property | Value |
|----------|-------|
| **Setting** | **Allow API Key Authentication** toggle in Advanced Options (`allow_api_key_auth`) |
| **Default** | Off — OAuth remains the only mechanism until an admin enables it |
| **Header** | `X-DreamFactory-API-Key` |
| **Key** | A standard DreamFactory app API key (64-character hex) |
| **Requirements** | The key's app must be **active** and have a **role assigned** |
| **Access scope** | The app's role, intersected with the service's [Exposed Services](./mcp-exposed-services.md) |
| **Precedence** | An `Authorization: Bearer` header always wins and takes the OAuth path |
| **Optional layering** | `X-DreamFactory-Session-Token` adds user identity on top of the key |

## Enabling it

Log in as an administrator, open the **AI** tab, click **MCP**, and select your MCP service. Under **Advanced Options**, switch on **Allow API Key Authentication** and save:

![MCP service Advanced Options showing the Allow API Key Authentication toggle next to the Custom Login URL field, with the Exposed Services selection showing Local SQL Database and the top of the Built-in Tools section below](/img/ai/mcp-access/allow-api-key-auth-toggle.png)

The key you hand to clients is an ordinary DreamFactory application [API key](../api-generation-and-connections/api-keys.md). For MCP the key's app must be **active** and must have a **role assigned** — keys whose app has no role are rejected, because that role is what scopes every tool call.

## Making requests

Send the key in the `X-DreamFactory-API-Key` header on every request. Initialize as usual:

```bash
curl -i -X POST https://your-dreamfactory-host/mcp/{service-name} \
-H "Content-Type: application/json" \
-H "X-DreamFactory-API-Key: YOUR_APP_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {"name": "my-client", "version": "1.0.0"}
}
}'
```

The response includes an `MCP-Session-Id` header. Include it — together with the API key header — on subsequent calls:

```bash
curl -X POST https://your-dreamfactory-host/mcp/{service-name} \
-H "Content-Type: application/json" \
-H "MCP-Session-Id: YOUR_SESSION_ID" \
-H "X-DreamFactory-API-Key: YOUR_APP_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {"name": "list_apis", "arguments": {}}
}'
```

## How access is scoped

- **Key-only requests run under the key app's role** — the same way API-key-only calls to the REST API are authorized. The tool catalog the session sees is the intersection of that role's service access and the MCP service's [Exposed Services](./mcp-exposed-services.md) list.
- **Bearer always wins.** A request carrying an `Authorization: Bearer` header goes through the unchanged OAuth path, regardless of any API-key headers it also carries.
- **With the toggle off** (the default), requests without a Bearer token receive `401` with OAuth discovery info — exactly the behavior on instances prior to 7.7.1.

### Layering a session token

Alongside the key, a client may also send a DreamFactory session JWT in the `X-DreamFactory-Session-Token` header. The request then runs with that **user's identity and role mapping on top of the app context** — user-specific RBAC wins over the bare app role, matching how the combination behaves against the REST API. An invalid or expired session token is rejected rather than silently ignored.

## Security guidance

:::warning Treat app keys as secrets
Once the toggle is on, anyone holding the app's API key can open MCP sessions with that app's role — there is no interactive login in front of it. Distribute keys like passwords, keep them out of source control, and prefer OAuth for interactive clients.
:::

- **Scope tightly.** Give the app a least-privilege role, and keep the MCP service's Exposed Services list to the backends the key actually needs.
- **Revoke deliberately.** To cut off access: refresh the app's API key, unassign its role, deactivate the app, or switch **Allow API Key Authentication** back off for the service.
- **Keys stay out of the logs.** Keys are format-checked before any lookup, and the key value is not written to DreamFactory's log at the default log level — the auth-success line (visible only at `LOG_LEVEL=debug`) records the app, not the key.
- **Calls are audited.** API-key-authenticated tool calls are recorded in the `mcp_request_log` audit table like OAuth calls, attributed to the key's app and role (with no OAuth client).

:::note
The toggle also exists on System API MCP Server (`system_mcp`) services — the config model is shared. Such an endpoint stays OAuth-only until an admin opts it in, and a key-authenticated session's role gates System API calls exactly as it gates them through the REST API.
:::

## See also

- [Scoping Tools with Exposed Services](./mcp-exposed-services.md) — what the session's role is intersected with
- [MCP Server](./mcp-service.md#required-headers) — request format and required headers
- [Creating an MCP Server Service](./mcp-service-creation.md) — OAuth setup and the rest of Advanced Options
2 changes: 1 addition & 1 deletion docs/AI/mcp-custom-login-page.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 3
sidebar_position: 5
title: Custom Login Page for MCP
id: mcp-custom-login-page
description: "How to build a branded, self-hosted login page for DreamFactory's MCP OAuth flow while keeping OAuth 2.0 and PKCE security intact."
Expand Down
110 changes: 110 additions & 0 deletions docs/AI/mcp-exposed-services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
sidebar_position: 3
title: Scoping Tools with Exposed Services
id: mcp-exposed-services
description: Control which database and file services each DreamFactory MCP endpoint advertises as tools using the per-service Exposed Services allowlist.
keywords: [MCP, Model Context Protocol, exposed services, tool scoping, allowlist, MCP_SCOPE_TOOLS, disabled tools, least privilege, AI security]
difficulty: intermediate
---

# Scoping Tools with Exposed Services

Starting with DreamFactory 7.7.1, every MCP service carries a per-endpoint allowlist called **Exposed Services**: the database and file services that endpoint turns into MCP tools. Connecting to `/mcp/storefront` no longer dumps every other database on the instance into `tools/list` — each MCP endpoint advertises exactly the backends you attach to it. That keeps AI clients focused on the data they are meant to work with, and keeps unrelated services invisible to them.

## Quick Reference

| Property | Value |
|----------|-------|
| **Setting** | **Exposed Services** multi-select in the MCP service's Advanced Options |
| **Stores** | Database and file service names (`exposed_services` in the service config) |
| **Empty selection** | No auto-generated database or file tools — deliberate, never a fallback to "everything" |
| **New services** | Start with nothing selected — pick at least one service before connecting a client |
| **Upgraded services** | Backfilled with every database and file service that existed at upgrade time |
| **Renames / deletes** | Followed automatically — the list is rewritten when a backend is renamed or deleted |
| **Instance-wide off switch** | `MCP_SCOPE_TOOLS=false` in `.env` (restores the legacy instance-wide catalog) |

## Selecting services in the admin interface

Log in as an administrator, open the **AI** tab, and click **MCP** to see your MCP services:

![AI MCP Servers list page showing three MCP services with their active status, names, labels, types, and health status columns](/img/ai/mcp-access/mcp-servers-list.png)

Open the service, scroll to **Advanced Options**, and use the **Exposed Services** multi-select to check the database and file services this endpoint should expose. Save when done:

![MCP service edit screen with the Exposed Services multi-select open, showing Local SQL Database checked and DB2 sqlite, Local File Storage, and Local Log Storage unchecked, with the Allow API Key Authentication toggle visible above](/img/ai/mcp-access/exposed-services-multi-select.png)

:::note Reconnect after changing the selection
The tool list is fixed for the life of an MCP session — the server never sends `tools/list_changed`, since that invalidates the client's prompt cache. After changing Exposed Services, reconnect your MCP clients to pick up the new catalog.
:::

## Empty means none

An MCP service with no Exposed Services selected serves **no auto-generated database or file tools at all** — only [custom tools](./custom-tools.md), the built-in `search`/`fetch` pair, and global tools register. An empty selection does not fall back to every service on the instance.

This is deliberate: a custom-tools-only MCP service is a valid setup, so an empty selection is not a validation error. DreamFactory does log a warning when a service is saved with scoping in effect and nothing selected, so an admin wondering why a client sees no table tools can find the cause in the logs.

## Roles still apply

Exposed Services narrows the catalog; it never widens it. The tools a connected client actually receives cover the **intersection** of the Exposed Services list and the services the authenticated identity's role grants access to — the connecting user's role for OAuth sessions, or the app's role for [API-key sessions](./mcp-api-key-auth.md). Administrators see every exposed service.

## `scope_tools` and `MCP_SCOPE_TOOLS`

Scoping is on by default. Two switches exist for restoring the pre-7.7.1 instance-wide catalog:

- **`MCP_SCOPE_TOOLS`** (`.env`, default `true`) — the instance-wide default for MCP services that have not set `scope_tools` themselves.
- **`scope_tools`** (per-service config) — a tri-state override (`true` / `false` / unset). It is intentionally not shown in the admin interface, because a checkbox cannot represent "unset"; set it through the system API if you need a per-service override.

How the pieces combine:

| `exposed_services` | `scope_tools` | `MCP_SCOPE_TOOLS` | `tools/list` contains |
|---|---|---|---|
| Non-empty | any | any | Only the listed services |
| Empty | unset | `true` (default) | No database/file tools |
| Empty | `true` | any | No database/file tools |
| Empty | unset | `false` | Every accessible database/file service (legacy) |
| Empty | `false` | any | Every accessible database/file service (legacy) |

:::note A non-empty list always applies
Turning scoping off (`MCP_SCOPE_TOOLS=false` or `scope_tools=false`) only matters for services whose Exposed Services list is **empty**. A service with services selected is always scoped to that selection, regardless of either flag.
:::

## Upgrade behavior

Upgrading to 7.7.1 must not shrink anyone's tool catalog, so the upgrade migration backfills every existing MCP service's Exposed Services with the names of **all database and file services that existed at migrate time** — including MCP services that were created through the API without any explicit configuration. Their `tools/list` is unchanged after the upgrade.

The snapshot is frozen at upgrade time. Database or file services you create **later** are not advertised automatically — open the MCP service and add them to Exposed Services yourself. New MCP services created after the upgrade always start with an empty selection.

## Service renames and deletes

Exposed Services stores service **names**, and from 7.7.1 DreamFactory keeps them in step automatically:

- **Renaming** a database or file service rewrites the old name to the new one (case-insensitively) in every MCP service's list, so the backend stays exposed under its new name.
- **Deleting** a service removes its name from every list. A list emptied this way stays empty — it does not fall back to the full catalog — and a service later recreated under the same name does not silently inherit the old exposure.

A failure in this sync is logged as a warning and never blocks the rename or delete itself.

## Combining with Built-in Tools

Exposed Services and the per-tool toggles under **Built-in Tools** are complementary, and they apply in order:

1. **Exposed Services** decides which backends get tools at all.
2. **Built-in Tools** (the `disabled_tools` config) then disables individual tools within an exposed service — for example, keep `db_get_table_data` but switch off `db_delete_records`.

![MCP service Built-in Tools section with the Local SQL Database group expanded, showing per-tool enable toggles for db_get_tables, db_get_table_schema, db_get_table_data, db_create_records, db_update_records, db_delete_records, and db_get_table_fields](/img/ai/mcp-access/built-in-tools-per-tool-toggles.png)

Disabling every tool of a service is not the same as removing the service from Exposed Services — use Exposed Services to take a backend out of the catalog entirely, and Built-in Tools to trim verbs from a backend that stays in.

## Leaner tool catalogs

Alongside scoping, 7.7.1 reduces what each advertised tool costs your AI client: tool descriptions are shorter, with query syntax documented once in the server instructions rather than repeated per tool, and the cross-service `all_*` aggregator tools (such as `all_get_tables` and `all_list_files`) only register when **two or more** services of that category are in the catalog — a single-database endpoint no longer carries cross-database aggregators it cannot use.

:::note
Exposed Services applies to the data-plane **MCP Server** service type. MCP service types that have no database/file tool catalog — such as the System API MCP Server (`system_mcp`) — hide the picker and ignore `exposed_services`, `scope_tools`, and `MCP_SCOPE_TOOLS`.
:::

## See also

- [Creating an MCP Server Service](./mcp-service-creation.md) — creating the service and the rest of Advanced Options
- [API Key Authentication for MCP](./mcp-api-key-auth.md) — how API-key sessions compose with Exposed Services
- [Deploying the MCP Server](./mcp-server-deployment.md) — upgrade notes and the export/import caveat
- [Custom MCP Tools](./custom-tools.md) — tools that register regardless of Exposed Services
Loading