diff --git a/docs/AI/agents.md b/docs/AI/agents.md index a2f3637..f895d8f 100644 --- a/docs/AI/agents.md +++ b/docs/AI/agents.md @@ -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" diff --git a/docs/AI/ai-chat.md b/docs/AI/ai-chat.md index c5d7e5b..52f7b8d 100644 --- a/docs/AI/ai-chat.md +++ b/docs/AI/ai-chat.md @@ -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. diff --git a/docs/AI/ai-connection.md b/docs/AI/ai-connection.md index c9e855d..1a4fdf1 100644 --- a/docs/AI/ai-connection.md +++ b/docs/AI/ai-connection.md @@ -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. diff --git a/docs/AI/ai-gateway.md b/docs/AI/ai-gateway.md index ea85329..87a8dbf 100644 --- a/docs/AI/ai-gateway.md +++ b/docs/AI/ai-gateway.md @@ -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. diff --git a/docs/AI/ai-usage-monitoring-and-cost-allocation.md b/docs/AI/ai-usage-monitoring-and-cost-allocation.md index c4e964f..e912990 100644 --- a/docs/AI/ai-usage-monitoring-and-cost-allocation.md +++ b/docs/AI/ai-usage-monitoring-and-cost-allocation.md @@ -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." diff --git a/docs/AI/custom-tools.md b/docs/AI/custom-tools.md index 9830732..ae518bc 100644 --- a/docs/AI/custom-tools.md +++ b/docs/AI/custom-tools.md @@ -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. diff --git a/docs/AI/github-scripts.md b/docs/AI/github-scripts.md index 53fce9d..078eea3 100644 --- a/docs/AI/github-scripts.md +++ b/docs/AI/github-scripts.md @@ -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. diff --git a/docs/AI/mcp-api-key-auth.md b/docs/AI/mcp-api-key-auth.md new file mode 100644 index 0000000..b30f2b9 --- /dev/null +++ b/docs/AI/mcp-api-key-auth.md @@ -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 diff --git a/docs/AI/mcp-custom-login-page.md b/docs/AI/mcp-custom-login-page.md index fcacdce..1d88166 100644 --- a/docs/AI/mcp-custom-login-page.md +++ b/docs/AI/mcp-custom-login-page.md @@ -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." diff --git a/docs/AI/mcp-exposed-services.md b/docs/AI/mcp-exposed-services.md new file mode 100644 index 0000000..7631570 --- /dev/null +++ b/docs/AI/mcp-exposed-services.md @@ -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 diff --git a/docs/AI/mcp-faq.md b/docs/AI/mcp-faq.md index 73c71d5..f46fdc8 100644 --- a/docs/AI/mcp-faq.md +++ b/docs/AI/mcp-faq.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 7 title: MCP FAQ id: mcp-faq description: Frequently asked questions about DreamFactory's Model Context Protocol (MCP) server — what it is, what tools it provides, and how to use it. @@ -16,17 +16,17 @@ In DreamFactory, MCP means you can connect an AI assistant directly to all your ## What is DreamFactory's MCP Server service? -DreamFactory's MCP Server service is a built-in feature that exposes your DreamFactory APIs as MCP-compatible tools. When an AI client connects, it automatically discovers all database and file storage services in your DreamFactory instance and can interact with them using the MCP protocol over Streamable HTTP (JSON-RPC). +DreamFactory's MCP Server service is a built-in feature that exposes your DreamFactory APIs as MCP-compatible tools. When an AI client connects, it can interact with the database and file storage services that MCP service [exposes](mcp-exposed-services.md) using the MCP protocol over Streamable HTTP (JSON-RPC). Key facts: -- **One MCP service covers all your APIs** — no need to create one per database -- **Authentication** uses OAuth 2.0 with auto-generated Client ID and Client Secret +- **One MCP service can cover all your APIs** — you select which databases and file services it exposes; no need to create one per database +- **Authentication** uses OAuth 2.0 with auto-generated Client ID and Client Secret (with an optional per-service [API key mode](mcp-api-key-auth.md)) - **Transport** is Streamable HTTP with Server-Sent Events (SSE) for streaming - **Created in the admin UI** under the AI tab ## What tools does the MCP server provide? -Tools are automatically generated for every connected database and file service. All tool names are prefixed with the API name (e.g., `mysql_get_tables`, `s3_list_files`). +Tools are automatically generated for every database and file service the MCP service [exposes](mcp-exposed-services.md). All tool names are prefixed with the API name (e.g., `mysql_get_tables`, `s3_list_files`). ### Discovery tools - `list_apis` — list all available APIs accessible through this MCP server @@ -92,3 +92,11 @@ Any MCP-compatible client: **ChatGPT**, **Claude Desktop**, **Cursor**, or any c ## Can I use a custom login page for MCP OAuth? Yes. Set the **Custom Login URL** field in the MCP service's Advanced Options. See [Custom Login Page for MCP](mcp-custom-login-page.md). + +## Why doesn't my MCP server show any database or file tools? + +From DreamFactory 7.7.1, each MCP service only advertises the backends selected under **Exposed Services** in its Advanced Options — and an empty selection deliberately means none. New MCP services (and services imported from a pre-7.7.1 export) start with nothing selected. Open the service, check the databases and file services it should expose, save, and reconnect your client (the tool list is fixed for the life of a session). See [Scoping Tools with Exposed Services](mcp-exposed-services.md). + +## Can a client authenticate with an API key instead of OAuth? + +Yes, from DreamFactory 7.7.1 — as a per-service opt-in. Enable **Allow API Key Authentication** in the MCP service's Advanced Options, then send a DreamFactory app API key in the `X-DreamFactory-API-Key` header. The key's app must be active and have a role assigned; that role scopes every tool call. OAuth Bearer tokens always take precedence when both are sent. See [API Key Authentication for MCP](mcp-api-key-auth.md). diff --git a/docs/AI/mcp-server-deployment.md b/docs/AI/mcp-server-deployment.md index 0535a94..9e3d834 100644 --- a/docs/AI/mcp-server-deployment.md +++ b/docs/AI/mcp-server-deployment.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 8 title: Deploying the MCP Server id: mcp-server-deployment description: Install, daemonize, and configure the DreamFactory MCP server, including running behind a reverse proxy or load balancer. @@ -118,6 +118,8 @@ Set these in your DreamFactory `.env`: | `APP_URL` | `https://df.example.com` | The external URL clients use. Not `http://localhost`. | | `DF_FRONTEND_URL` | *(optional)* | Override only if the admin SPA is on a different host. | | `LOG_LEVEL` | `warning` | Set to `debug` while troubleshooting OAuth, then revert. | +| `MCP_INTERNAL_BASE_URL` | *(optional)* | URL the daemon calls DreamFactory back on. **Required when the external port differs from the internal one** (typical Docker port mapping) — see [below](#daemon-callback-url-mcp_internal_base_url). | +| `MCP_SCOPE_TOOLS` | *(optional)* | Default `true`. Set to `false` to restore the pre-7.7.1 instance-wide tool catalog for services with no [Exposed Services](./mcp-exposed-services.md) selection. | :::warning `APP_URL` must be the **external HTTPS URL** clients reach. It drives the OAuth discovery and callback URLs as well as server-side session validation. If it is left as `http://localhost` (or any value clients can't reach), MCP authentication fails — typically as a login page that loops. @@ -129,6 +131,19 @@ Verify the value actually in use: php artisan tinker --execute="echo config('app.url');" ``` +### Daemon callback URL (`MCP_INTERNAL_BASE_URL`) + +The daemon executes every tool by calling DreamFactory's REST API back. By default it calls the same origin the client's request arrived on. When that origin is not reachable from where the daemon runs, set `MCP_INTERNAL_BASE_URL` to an address that is. + +The classic case is Docker port mapping: with `-p 8084:80`, clients reach DreamFactory at `http://host:8084`, but inside the container it listens on port 80 — so the daemon's callback to `:8084` fails. The symptom is distinctive: **connecting and `tools/list` succeed, but every tool call fails**, because only tool execution needs the callback. + +```bash +# in .env — an address that reaches DreamFactory from where the daemon runs +MCP_INTERNAL_BASE_URL=http://127.0.0.1 +``` + +In a compose stack with a separate daemon container, use the web service's internal address instead (e.g. `http://web`). Then run `php artisan config:clear` and restart PHP-FPM. + ## Applying configuration changes DreamFactory caches configuration, so editing `.env` alone is not enough: @@ -237,10 +252,26 @@ sudo tail -f /var/log/nginx/access.log | grep -E "oauth-callback|user/session" | `redirect_uri is not registered` | Rotating loopback port — free/reuse the client's fixed port and reconnect | | 404 on all `/mcp/*` | Confirm the package is installed, then `php artisan route:clear` | | Config change has no effect | Run `config:clear` (not just a PHP-FPM restart); ensure cache files aren't root-owned | +| Connecting and `tools/list` work, but every tool call fails | The daemon can't reach DreamFactory on the request's origin (external port ≠ internal port). Set [`MCP_INTERNAL_BASE_URL`](#daemon-callback-url-mcp_internal_base_url) | +| Client sees no database/file tools | No [Exposed Services](./mcp-exposed-services.md) selected on the MCP service (new services and pre-7.7.1 imports start empty) — select services, save, reconnect the client | + +## Upgrading to 7.7.1 + +DreamFactory 7.7.1 adds [Exposed Services scoping](./mcp-exposed-services.md) and [API key authentication](./mcp-api-key-auth.md) to MCP services. The package migrations run as part of the normal upgrade (`php artisan migrate`) and are designed so nothing shrinks: + +- Every existing MCP service is backfilled with the database and file services that exist at migrate time, so its `tools/list` is unchanged. Services created **after** the upgrade start with an empty Exposed Services selection. +- **Allow API Key Authentication** defaults to off everywhere — OAuth behavior is unchanged until an admin opts a service in. +- After changing a service's Exposed Services, **reconnect its MCP clients** — the tool list is fixed for the life of a session. + +:::caution Service export/import across versions +The new fields travel with MCP service exports. Importing a scoped 7.7.1 service into a **pre-7.7.1** instance silently drops `exposed_services`, `scope_tools`, and `allow_api_key_auth` — the older instance doesn't know those fields. In the other direction, importing a **pre-7.7.1** export into 7.7.1 creates an MCP service with **no exposure** (the export carries no `exposed_services`, and empty means none) — open the service and select its Exposed Services after the import. +::: ## See also - [MCP Server](./mcp-service.md) — protocol overview, tools, and request format - [Creating an MCP Server Service](./mcp-service-creation.md) +- [Scoping Tools with Exposed Services](./mcp-exposed-services.md) +- [API Key Authentication for MCP](./mcp-api-key-auth.md) - [Custom Login Page for MCP](./mcp-custom-login-page.md) - [Web Server — TLS](../getting-started/optimizing-dreamfactory/webserver.md#tls) — reverse-proxy scheme, `FORCE_HTTPS`, and redirects diff --git a/docs/AI/mcp-service-creation.md b/docs/AI/mcp-service-creation.md index 0ca3ba6..21f7c2d 100644 --- a/docs/AI/mcp-service-creation.md +++ b/docs/AI/mcp-service-creation.md @@ -15,15 +15,15 @@ keywords: [MCP, Model Context Protocol, AI integration, ChatGPT, Claude, Cursor, | **Service Type** | MCP Server | | **Required Fields** | Service Name | | **Auto-Generated** | OAuth Client ID, OAuth Client Secret | -| **Authentication** | OAuth 2.0 | -| **API Discovery** | Automatic — all database and file services are detected at connection time | +| **Authentication** | OAuth 2.0 (default); optional per-service [API key authentication](./mcp-api-key-auth.md) | +| **Exposed APIs** | The database and file services you select under [Exposed Services](./mcp-exposed-services.md) | | **Supported AI Clients** | ChatGPT, Claude, Cursor, any MCP-compatible client | ## Overview The Model Context Protocol (MCP) is a standardized protocol that enables AI assistants and development tools to interact with your DreamFactory services through a consistent interface. Despite the growing popularity of direct API integrations, MCP-based connections remain an essential part of modern development workflows, allowing AI assistants like ChatGPT, Claude, and Cursor to seamlessly query and manipulate your resources. -But incorporating MCP functionality into your development environment can be challenging. Fortunately, you can use DreamFactory to easily create a full-featured MCP server that exposes your services through the Model Context Protocol. A single MCP server automatically discovers and provides access to **all** database and file storage services configured in your DreamFactory instance. This includes: +But incorporating MCP functionality into your development environment can be challenging. Fortunately, you can use DreamFactory to easily create a full-featured MCP server that exposes your services through the Model Context Protocol. A single MCP server can provide access to **any number** of the database and file storage services configured in your DreamFactory instance — you choose which ones under [Exposed Services](./mcp-exposed-services.md). This includes: - Exploring database schemas, tables, and relationships - Querying and filtering table data with advanced options @@ -54,9 +54,11 @@ Next, you'll scroll down to the **Advanced options** section. There you'll find | **OAuth Client ID** | The OAuth Client ID is generated by DreamFactory for you. This is the field that MCP Server users are going to provide to the MCP client during connection creation. | | **OAuth Client Secret** | The OAuth Client Secret is also generated by DreamFactory for you. This is the field that MCP Server users are going to provide to the MCP client during connection creation. | | **Custom Login URL** | Optional field that you could use in order to have a custom MCP login page. DreamFactory's login page would be used if nothing is provided in this field. [How to configure?](../AI/mcp-custom-login-page)| +| **Exposed Services** | Multi-select of the database and file services this MCP endpoint exposes as tools. An empty selection means no database or file tools. [How does scoping work?](./mcp-exposed-services.md) | +| **Allow API Key Authentication** | Off by default. When enabled, clients can authenticate with a DreamFactory app API key in the `X-DreamFactory-API-Key` header instead of OAuth. [How to use it?](./mcp-api-key-auth.md) | -:::tip No API selection needed -You no longer need to select a specific database service. The MCP server **automatically discovers all database and file storage services** available in your DreamFactory instance when an AI client connects. This means a single MCP server gives your AI assistant access to every configured service. +:::tip Pick the services to expose +A single MCP server can expose any number of database and file storage services — you choose which ones under **Exposed Services**. New MCP services start with **nothing selected**, and an empty selection deliberately serves no database or file tools, so check at least one service before connecting a client. See [Scoping Tools with Exposed Services](./mcp-exposed-services.md). ::: After saving your changes, head over to the **API Docs** tab to review the generated documentation. You'll be presented with information about the MCP endpoint by running the GET request: diff --git a/docs/AI/mcp-service.md b/docs/AI/mcp-service.md index bd21879..1e90a36 100644 --- a/docs/AI/mcp-service.md +++ b/docs/AI/mcp-service.md @@ -16,8 +16,8 @@ The MCP (Model Context Protocol) server is a powerful feature in DreamFactory th The Model Context Protocol (MCP) is a standardized way for tools and services to communicate with AI assistants and development environments. DreamFactory's MCP server implements the Streamable HTTP transport, which allows for efficient bidirectional communication between clients and your services. **Key Features:** -- **Automatic Service Discovery**: Automatically discovers and exposes all database and file storage services configured in your DreamFactory instance -- **Multiple API Support**: A single MCP server provides tools for all your connected services — no need to create separate MCP services per database or file API +- **Scoped Service Catalog**: Exposes the database and file storage services you select per endpoint via [Exposed Services](./mcp-exposed-services.md) +- **Multiple API Support**: A single MCP server provides tools for all its exposed services — no need to create separate MCP services per database or file API - **Session Management**: Each MCP connection maintains its own session with stored credentials and tool context - **Tool Registration**: Automatically exposes DreamFactory operations as MCP tools, prefixed per API for clarity - **Streaming Support**: Supports Server-Sent Events (SSE) for real-time data streaming @@ -25,7 +25,7 @@ The Model Context Protocol (MCP) is a standardized way for tools and services to ## Available Tools -The MCP server automatically discovers all database and file storage services in your DreamFactory instance and registers tools for each one. All tools are **prefixed with the API name** to distinguish between services. For example, if you have a database service named `mysql` and a file service named `s3`, the tools would be `mysql_get_tables`, `s3_list_files`, etc. +The MCP server registers tools for every database and file storage service the connected MCP service exposes (see [Scoping Tools with Exposed Services](./mcp-exposed-services.md)). All tools are **prefixed with the API name** to distinguish between services. For example, if you have a database service named `mysql` and a file service named `s3`, the tools would be `mysql_get_tables`, `s3_list_files`, etc. ### Discovery & Overview Tools @@ -149,6 +149,7 @@ Every MCP request requires only standard HTTP headers: How a request is authenticated depends on how the MCP service is connected: - **AI clients** (VS Code, Claude, Cursor) authenticate the connection using **OAuth 2.0**. The OAuth handshake establishes the session, and tools are filtered to the services the connecting user's role grants access to. See [Creating an MCP Server Service](./mcp-service-creation.md) and [Deploying the MCP Server](./mcp-server-deployment.md) for OAuth setup. +- **Headless clients** can authenticate with a DreamFactory app API key in the `X-DreamFactory-API-Key` header when the MCP service has opted in — see [API Key Authentication for MCP](./mcp-api-key-auth.md). - **Direct API calls** like the examples above don't require an authentication header when the MCP service is bound to an application with a default role — DreamFactory applies that role's permissions internally. Otherwise, include an `X-DreamFactory-Session-Token` (or API key) header. ## Use Cases diff --git a/static/img/ai/mcp-access/allow-api-key-auth-toggle.png b/static/img/ai/mcp-access/allow-api-key-auth-toggle.png new file mode 100644 index 0000000..3c61438 Binary files /dev/null and b/static/img/ai/mcp-access/allow-api-key-auth-toggle.png differ diff --git a/static/img/ai/mcp-access/built-in-tools-per-tool-toggles.png b/static/img/ai/mcp-access/built-in-tools-per-tool-toggles.png new file mode 100644 index 0000000..d339784 Binary files /dev/null and b/static/img/ai/mcp-access/built-in-tools-per-tool-toggles.png differ diff --git a/static/img/ai/mcp-access/exposed-services-multi-select.png b/static/img/ai/mcp-access/exposed-services-multi-select.png new file mode 100644 index 0000000..34ae9c9 Binary files /dev/null and b/static/img/ai/mcp-access/exposed-services-multi-select.png differ diff --git a/static/img/ai/mcp-access/mcp-servers-list.png b/static/img/ai/mcp-access/mcp-servers-list.png new file mode 100644 index 0000000..028cb27 Binary files /dev/null and b/static/img/ai/mcp-access/mcp-servers-list.png differ