From 9d859d7e59777d9740190ede582c6af0eafb1128 Mon Sep 17 00:00:00 2001 From: Iliia_Veselov Date: Mon, 4 May 2026 14:33:24 +0300 Subject: [PATCH 1/3] feat: Add StatGPT MCP documentation --- README.md | 5 + architecture/README.md | 5 +- .../content/architecture_detailed.svg | 3 +- .../content/architecture_high_level.svg | 3 +- architecture/content/diagrams.drawio | 144 ++++++++++------- architecture/overview.md | 10 ++ architecture/services.md | 9 ++ architecture/tools.md | 9 ++ mcp/README.md | 146 ++++++++++++++++++ mcp/auth.md | 138 +++++++++++++++++ 10 files changed, 413 insertions(+), 59 deletions(-) create mode 100644 mcp/README.md create mode 100644 mcp/auth.md diff --git a/README.md b/README.md index 1573af7..6596d41 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,11 @@ StatGPT bridges the gap between complex statistical databases and everyday users - [Architecture Overview](./architecture/overview.md) - Solution overview and core requirements - [SDMX Compatibility](./architecture/sdmx-compatibility.md) - SDMX integration details +### [Application MCP](./mcp/README.md) +Programmatic tool access via the Model Context Protocol: +- Channel tools exposed to DIAL applications and other MCP-aware clients +- [Authentication & Authorization](./mcp/auth.md) - DIAL Application config, MCP-spec discovery, IDP OAuth flow + ### Guides - [Admin Guide](./guides/admin-guide.md) - System administration and configuration - [GTDC Portal Guide](./guides/gtdc-portal-guide.md) - Instructions for using the GTDC (Global Trusted Data Commons) Portal diff --git a/architecture/README.md b/architecture/README.md index b8326c5..f4f8096 100644 --- a/architecture/README.md +++ b/architecture/README.md @@ -12,6 +12,7 @@ design, services, tools, and integration requirements. | **[๐Ÿ“‹ Overview](./overview.md)** | Complete platform overview with requirements and features | โ€ข Natural language querying
โ€ข Data accuracy & reliability
โ€ข Security & governance
โ€ข Performance & scalability | | **[๐Ÿญ Services](./services.md)** | Core services and dependencies architecture | โ€ข Chat Backend (DIAL app)
โ€ข Admin Backend & Frontend
โ€ข Portal Frontend
โ€ข Third-party integrations | | **[๐Ÿ”ง Tools](./tools.md)** | Agent tools and capabilities documentation | โ€ข Data query tools
โ€ข Publications RAG
โ€ข Glossary management
โ€ข Web search integration | +| **[๐Ÿ”Œ Application MCP](../mcp/README.md)** | Programmatic tool access via Model Context Protocol | โ€ข Channel tools over MCP
โ€ข DIAL Application registration
โ€ข MCP-spec discovery + IDP OAuth flow | | **[๐Ÿ“Š SDMX Compatibility](./sdmx-compatibility.md)** | SDMX standards and requirements guide | โ€ข Version support (2.1/3.0)
โ€ข Metadata requirements
โ€ข Performance standards
โ€ข Quality checklist | ### Design Documentation @@ -100,7 +101,3 @@ All architecture documentation follows these principles: - **Navigation**: Internal links and cross-references for easy browsing - **Completeness**: Comprehensive coverage of technical requirements - **Maintenance**: Regular updates as the platform evolves - ---- - -*Last updated: September 2025* diff --git a/architecture/content/architecture_detailed.svg b/architecture/content/architecture_detailed.svg index 4af69ab..df57389 100644 --- a/architecture/content/architecture_detailed.svg +++ b/architecture/content/architecture_detailed.svg @@ -1,3 +1,4 @@ + -
Common Services (**)
Container Orchestration (Kubernetes, OCP, etc.)
Azure
AI DIAL
StatGPT
Icon-identity-230 BusinessUser
HTTP
HTTP
StatGPT App Backend
TCP
HTTP
HTTP
StatGPT Admin Backend
PostgreSQL (*)
Elasticsearch (*)
Request flow
TCP
HTTP
HTTP
DIAL Core
HTTP
DIAL OpenAI Adapter
HTTP
DIAL Realtime Analytics
HTTP
Reads
Logs
HTTP
Vector
InfluxDBRedis (*)
End user Communication Channels
DIAL Chat StatGPT Portal
TCP
HTTP
DIAL Admin Backend
Admin Communication Channels
Grafana DIALAdmin FE StatGPTAdmin FE
HTTP
HTTP
HTTP
HTTP
Azureย OpenAIBlob Storage Icon-identity-230 AdminUser
Logging
Monitoring
(OTEL)
External Services
Secretย 
management
SSO
(*) - cloud-managed versions of services can be used
(**) - Common Services can be located either in Container orchestration or in different Clouds
SDMX API (HTTP)
SDMX Registries
(External)
SDMX API (HTTP)
+
Common Services (**)
Container Orchestration (Kubernetes, OCP, etc.)
Azure
AI DIAL
StatGPT
Icon-identity-230 BusinessUser
HTTP
HTTP
StatGPT App Backend
TCP
HTTP
HTTP
StatGPT Admin Backend
PostgreSQL (*)
Elasticsearch (*)
Request flow
TCP
HTTP
HTTP
DIAL Core
HTTP
DIAL OpenAI Adapter
HTTP
DIAL Realtime Analytics
HTTP
Reads
Logs
HTTP
Vector
InfluxDBRedis (*)
End user Communication Channels
DIAL Chat StatGPT PortalMCP Client
TCP
HTTP
DIAL Admin Backend
Admin Communication Channels
Grafana DIALAdmin FE StatGPTAdmin FE
HTTP
HTTP
HTTP
HTTP
Azureย OpenAIBlob Storage Icon-identity-230 AdminUser
Logging
Monitoring
(OTEL)
External Services
Secretย 
management
SSO
(*) - cloud-managed versions of services can be used
(**) - Common Services can be located either in Container orchestration or in different Clouds
SDMX API (HTTP)
SDMX Registries
(External)
SDMX API (HTTP)
StatGPT App MCP
HTTP
HTTP
diff --git a/architecture/content/architecture_high_level.svg b/architecture/content/architecture_high_level.svg index a9b9f30..7e09332 100644 --- a/architecture/content/architecture_high_level.svg +++ b/architecture/content/architecture_high_level.svg @@ -1,3 +1,4 @@ + -
External Services
Application Services
Icon-identity-230 Business User
StatGPT Application
AI DIAL
Communication Channels
AI DIAL Chat StatGPT Portal
Request flow
SDMX Registries
Icon-identity-230 Admin User
Admin Communication Channels
DIAL Admin StatGPT Admin
Azure
Azure OpenAIGrafana
+
External Services
Application Services
Icon-identity-230 Business User
StatGPT Application
AI DIAL
Communication Channels
AI DIAL Chat StatGPT PortalMCP Client
Request flow
SDMX Registries
Icon-identity-230 Admin User
Admin Communication Channels
DIAL Admin StatGPT Admin
Azure
Azure OpenAIGrafana
diff --git a/architecture/content/diagrams.drawio b/architecture/content/diagrams.drawio index 61394e4..26ee1bf 100644 --- a/architecture/content/diagrams.drawio +++ b/architecture/content/diagrams.drawio @@ -1,11 +1,11 @@ - + - + @@ -35,13 +35,16 @@ - + - + + + + - + @@ -131,38 +134,38 @@ - + - + - + - + - + - + - + - + @@ -170,13 +173,13 @@ - - + + - + @@ -187,30 +190,30 @@ - - + + - + - - + + - + - + - + - + @@ -258,7 +261,7 @@ - + @@ -274,9 +277,10 @@ - + + - + @@ -284,37 +288,45 @@ - + - + - + - + - + - + + + + - + + + + + + - + - + @@ -338,10 +350,11 @@ - + + - - + + @@ -351,9 +364,10 @@ - - - + + + + @@ -367,7 +381,7 @@ - + @@ -376,7 +390,7 @@ - + @@ -385,29 +399,53 @@ - + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + diff --git a/architecture/overview.md b/architecture/overview.md index a77b853..1bf7104 100644 --- a/architecture/overview.md +++ b/architecture/overview.md @@ -199,6 +199,16 @@ The AI agent is explicitly instructed to: โ†’ See [AI DIAL Access Control](https://docs.dialx.ai/platform/core/access-control-intro) for configuration. +### Programmatic Access via MCP + +In addition to the chat UI, StatGPT exposes a channel's configured tools (data query, RAG, glossary, web search, โ€ฆ) +over the [Model Context Protocol](https://modelcontextprotocol.io/) via **Application MCP**, mounted on the Chat +Backend. AI DIAL fronts the endpoint as the `mcpEndpoint` of a DIAL Application; DIAL handles MCP-spec +authorization-server discovery and forwards the user's bearer + per-request key to StatGPT, so DIAL applications and +other MCP-aware clients can invoke the tools under their own LLM control. + +โ†’ See the [Application MCP documentation](../mcp/README.md) for the endpoint, tool catalog, and authentication flow. + ### Security & Privacy **Data Protection**: diff --git a/architecture/services.md b/architecture/services.md index f8bd2c3..4e59d5e 100644 --- a/architecture/services.md +++ b/architecture/services.md @@ -96,6 +96,15 @@ with [DIAL API Specification](https://dialx.ai/dial_api#operation/sendChatComple | **External AI Models** | LLM capabilities (e.g., Azure OpenAI) | | **SDMX Providers** | Statistical data sources (IMF, World Bank, Eurostat) | +#### MCP Endpoint + +The Chat Backend exposes channel tools over the [Model Context Protocol](https://modelcontextprotocol.io/) at +`POST /api/v1/{deployment_id}/mcp`. The tool list is dynamic per channel and is fronted by AI DIAL as the +`mcpEndpoint` of a DIAL Application; DIAL handles MCP-spec authorization-server discovery and forwards user +credentials to the endpoint. + +โ†’ See [Application MCP](../mcp/README.md) for the tools catalog and request flow. + ### โš™๏ธ StatGPT Admin Backend #### Technology Stack diff --git a/architecture/tools.md b/architecture/tools.md index 2a17b1b..7efe002 100644 --- a/architecture/tools.md +++ b/architecture/tools.md @@ -223,3 +223,12 @@ Returns: - Provides static content to agent or users **Example Use Case**: Portal guides with dynamic information about available pages and features. + +## ๐Ÿ”Œ Programmatic Access + +The same tool catalog above is also exposed over the [Model Context Protocol](https://modelcontextprotocol.io/) by +StatGPT's **Application MCP** server, so DIAL applications and other MCP-aware clients can invoke them under their +own LLM control. The MCP tool surface for a given channel is whatever its YAML enables. + +โ†’ See [Application MCP](../mcp/README.md) for the endpoint, sample MCP exchanges, and the end-to-end client +walkthrough. diff --git a/mcp/README.md b/mcp/README.md new file mode 100644 index 0000000..fbe1a99 --- /dev/null +++ b/mcp/README.md @@ -0,0 +1,146 @@ +# Application MCP + +MCP server hosted by the **Chat Backend** that republishes a channel's StatGPT tools (data query, RAG, glossary, web +search, โ€ฆ) over the [Model Context Protocol](https://modelcontextprotocol.io/), so DIAL applications and other +MCP-aware clients can invoke them under their own LLM control. + +## ๐ŸŽฏ Scope + +- **Does**: Exposes the same primitives the StatGPT supreme agent uses internally. +- **Does not**: Replace the supreme agent's `/chat/completions` endpoint, pick tools, or compose multi-tool answers. +- **Configuration**: Tools surfaced for `deployment_id=foo` come directly from `foo`'s channel YAML โ€” no + MCP-specific override. + +## ๐Ÿ”Œ Endpoint + +| Property | Value | +|------------|--------------------------------------------------------| +| Path | `POST /api/v1/{deployment_id}/mcp` on Chat Backend | +| Mounted in | `statgpt/app/application/app_factory.py` | +| Transport | `streamable-http`, `stateless_http=True` | +| Bootstrap | `statgpt/app/mcp/app.py` | +| Provider | `statgpt/app/mcp/provider.py` (`ChannelToolProvider`) | + +`{deployment_id}` selects the channel; tools and config differ per channel. + +The server's `instructions=` field (sent to clients during MCP `initialize`) reads: + +> *This server provides tools from the StatGPT platform for querying official statistics data, searching publications, +> looking up glossary terms, and more. Tools are channel-specific and depend on the deployment configuration.* + +## โš™๏ธ Dynamic Tool Surface + +On every `tools/list` and `tools/call`, `ChannelToolProvider`: + +1. Reads `Authorization` + `api-key` from headers and builds an `AuthContext`. +2. Resolves `{deployment_id}` to a `ChannelServiceFacade` and loads `ChannelConfig`. +3. Wraps each `StatGptTool` in `_McpToolAdapter`, exposing it as an MCP tool. + +The MCP tool **name** and **description** come from the channel YAML; the **parameter schema** comes from each tool's +`get_public_args_schema()`. + +## ๐Ÿ› ๏ธ Tools Catalog + +Tool types registerable in a channel +([`statgpt/common/schemas/enums.py::ToolTypes`](https://github.com/epam/statgpt-backend)): + +| Tool type | Implementation class | Purpose | +|--------------------------|-----------------------------|----------------------------------------------------------------------| +| `AVAILABLE_DATASETS` | `AvailableDatasetsTool` | List datasets available to the channel. | +| `DATASETS_METADATA` | `DatasetsMetadataTool` | Metadata for a specific set of datasets. | +| `DATASET_STRUCTURE` | `DatasetStructureTool` | Dimensions and attributes of a dataset. | +| `AVAILABLE_PUBLICATIONS` | `AvailablePublicationsTool` | List publication types. | +| `AVAILABLE_TERMS` | `AvailableTermsTool` | List glossary terms. | +| `TERM_DEFINITIONS` | `TermDefinitionsTool` | Look up glossary definitions. | +| `DATA_QUERY` | `DataQueryTool` | Translate NL into SDMX, execute, return text + CSV resource. | +| `FILE_RAG` | `FileRagTool` | RAG over publication content. | +| `PLAIN_CONTENT` | `PlainContentTool` | Static content with env-var substitution. | +| `WEB_SEARCH` | `WebSearchTool` | Web search with summarized results. | +| `WEB_SEARCH_AGENT` | `WebSearchAgentTool` | Web search routed through an agent. | + +Functional details โ†’ [Architecture / Tools](../architecture/tools.md). + +## ๐Ÿ“ Configuring the Tool Surface + +Channel YAML excerpt (from +[`tools.yaml`](https://github.com/epam/statgpt-backend/blob/development/configurations/clients/sample/tools.yaml)): + +```yaml +tools: + - type: available_datasets + name: "Available_Datasets" + description: >- + Provides a list of all available datasets โ€ฆ This tool does not accept any arguments. + details: + version: full + include_indicator_count: true + + - type: data_query + name: "Query_Data" + description: >- + Translates a natural-language question into an SDMX query and executes it. + details: + # ... model deployments, prompts, etc. +``` + +| Field | Becomes | +|---------------|-----------------------------------------------| +| `type` | Implementation class (Tools Catalog above). | +| `name` | MCP tool name surfaced via `tools/list`. | +| `description` | MCP tool description fed to the calling LLM. | + +Channel-level config (LLM models, glossaries, supreme-agent settings) lives in `channels.yaml` โ€” see +[Admin Guide](../guides/admin-guide.md). The MCP server inherits from there automatically. + +## ๐Ÿ“ฆ Returning Data Resources + +`DATA_QUERY` is the only tool emitting non-text results. In addition to a textual summary it returns one or more +`text/csv` resources via `data_query_artifact_to_resources()` (`statgpt/app/mcp/attachments.py`): + +``` +URI: statgpt://data_query/{path}/{timestamp}.csv +``` + +## ๐Ÿ” Authentication + +DIAL terminates auth and forwards `Authorization: Bearer ` and `api-key: `. +`DialAuthCredentials.from_headers` (`statgpt/app/security/credentials.py`) is wrapped by `create_auth_context` +(`statgpt/app/security/auth_context.py`); the MCP provider calls it with the default `bearer_token_required=False`, +so the result is always a `UserAuthContext`: + +- **Bearer present** โ€” JWT is reused for callbacks into DIAL via `UserAuthContext.dial_access_token`. +- **Bearer absent** โ€” `dial_access_token` is `None`; any tool that needs the JWT fails at use time, and a missing + `api-key` raises `MissingApiKeyError` lazily during channel resolution. + +`SystemUserAuthContext` is **not reached from MCP** โ€” it requires `bearer_token_required=True` at the call site, +which `statgpt/app/mcp/provider.py` does not pass. Auth failures during channel resolution cause `tools/list` to +return an empty list and `tools/call` to error. Full flow โ†’ [auth.md](./auth.md). + +## ๐Ÿค– End-to-End: LLM Client Walkthrough + +1. **Operator** registers StatGPT in DIAL as a **DIAL Application** with `mcpEndpoint`. + See [auth.md ยง1](./auth.md#1-registration-dial-application). +2. **MCP client** issues `tools/list` against DIAL. DIAL responds with `401 Unauthorized` + Protected Resource + Metadata (RFC 9728) pointing at the IDP. The client runs OAuth 2.1 + PKCE directly against + the IDP โ€” DIAL is *not* in the OAuth path. +3. **Authenticated tool list.** Client retries `tools/list` with `Authorization: Bearer `. DIAL forwards + the bearer plus its own `api-key: ` to the StatGPT MCP endpoint. +4. **LLM** picks a tool (e.g. `Available_Datasets`), issues `tools/call`; DIAL forwards both headers. +5. For data questions the LLM picks `Query_Data`; the response includes text + CSV resource (above). +6. **Multi-tool reasoning is the client's job, not the MCP's.** For supreme-agent orchestration use the Chat Backend's + `/chat/completions` instead. + +For local-dev setups without DIAL, see the FastMCP HTTP-transport docs and the +[MCP authorization spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization). + +## ๐Ÿš€ Deployment + +Part of the Chat Backend image; no enable flag. Reachable through DIAL by registering StatGPT as a **DIAL Application** +with the MCP endpoint URL set on the `mcpEndpoint` field. See [auth.md](./auth.md) for the full configuration and +auth model. + +## ๐Ÿ”— See Also + +- [auth.md](./auth.md) โ€” DIAL Application config, auth flow, MCP-spec relationship +- [Architecture / Tools](../architecture/tools.md) +- [Architecture / Services](../architecture/services.md) diff --git a/mcp/auth.md b/mcp/auth.md new file mode 100644 index 0000000..d53e77f --- /dev/null +++ b/mcp/auth.md @@ -0,0 +1,138 @@ +# ๐Ÿ” MCP Authentication & Authorization + +[Application MCP](./README.md) is wired into AI DIAL as a **DIAL Application**. StatGPT itself runs no OAuth flow. +DIAL Core acts as the MCP-spec authorization-server discovery layer in front of the MCP endpoint, points clients at +the configured IDP, and forwards the resulting bearer + per-request key on every proxied tool call. + +## ๐Ÿงฉ 1. Registration: DIAL Application + +StatGPT is registered with DIAL as a **DIAL Application**. A DIAL Application can declare both a chat-completion +endpoint and an MCP endpoint side-by-side; DIAL Core proxies traffic to either through its routing layer. + +Authoritative DIAL docs: + +- Application administration UI / fields โ†’ [docs.dialx.ai entities-applications](https://docs.dialx.ai/tutorials/admin/entities-applications) + (the page explicitly defines "Chat Endpoint" and "MCP Endpoint" as Application properties). +- Application config schema โ†’ [DIAL Core applications.md](https://github.com/epam/ai-dial-core/blob/development/docs/dynamic-settings/applications.md) +- Per-request keys โ†’ [docs.dialx.ai per-request-keys](https://docs.dialx.ai/platform/core/per-request-keys). + +Relevant fields on the StatGPT Application: + +| Field | Value | Effect | +|-----------------------------|--------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------| +| `mcpEndpoint` | `https:///api/v1/{deployment_id}/mcp` | The MCP endpoint DIAL Core proxies to. | +| `endpoint` (chat completion)| (separate StatGPT chat endpoint) | Listed for completeness; not relevant to MCP traffic. | +| `forwardAuthToken` | `true` | DIAL forwards the caller's `Authorization: Bearer โ€ฆ` header to the application unchanged on every proxied call. | +| `accessibleByPerRequestKey` | `true` | Enables DIAL's per-request key forwarding in the `api-key` header. | + +There is no per-application OAuth client config (no `client_id`, no `redirect_uri`, no DIAL-side signin endpoint). +DIAL's job is discovery + forwarding, not running OAuth itself. + +## ๐Ÿ” 2. Auth Flow + +The flow is just the canonical [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) +discovery dance, with two architectural details: + +- **DIAL plays the resource-server-front role.** It returns the 401 + `WWW-Authenticate`, hosts + `/.well-known/oauth-protected-resource` (RFC 9728), and points clients at the IDP via the `authorization_servers` + field. StatGPT MCP itself has no `/.well-known` endpoints and does not return 401s โ€” it never sees a request + without a bearer. +- **DIAL is not in the OAuth path.** The OAuth 2.1 + PKCE handshake happens directly between the MCP client and the + IDP (Keycloak, Entra ID, โ€ฆ). DIAL holds no PKCE verifier, no authorization code, no refresh token, no per-app + client credentials. + +After the client has a bearer: + +1. Client โ†’ DIAL: `tools/call` with `Authorization: Bearer `. +2. DIAL โ†’ StatGPT MCP: same call, with the bearer forwarded (because `forwardAuthToken=true`) and an additional + `api-key: ` header. +3. StatGPT MCP processes the call (see ยง3). + +## ๐Ÿชช 3. How Application MCP Consumes the Forwarded Auth + +`DialAuthCredentials.from_headers` (`statgpt/app/security/credentials.py`) reads `api-key` and +`Authorization: Bearer โ€ฆ`. `create_auth_context` (`statgpt/app/security/auth_context.py`) is invoked by the MCP +provider with the default `bearer_token_required=False`, which means it always returns a `UserAuthContext`: + +| Context | When | Notes | +|-------------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `UserAuthContext` | Always (on the MCP entry path) | If a bearer is present the JWT is reused for callbacks into DIAL via `UserAuthContext.dial_access_token`. If absent, `dial_access_token` is `None` and any tool that needs the JWT will fail at use time. | +| `SystemUserAuthContext` | Not reached from MCP | Would require `bearer_token_required=True` at the call site, which `statgpt/app/mcp/provider.py` does not pass. Reserved for chat-completion / DIAL-SDK paths that opt in to that flag. | + +Subsequent failures are lazy: a missing `api-key` raises `MissingApiKeyError` when first dereferenced; an +authentication or authorization error during channel resolution causes `_list_tools` to swallow it and return an +empty tool list (`tools/call` errors). + +## ๐Ÿ“œ 4. Relationship to the MCP Authorization Specification + +At the wire level StatGPT's MCP authorization is **spec-compliant** โ€” a spec-compliant MCP client (one that +implements the discovery dance described in +[MCP Authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization)) works against the +StatGPT MCP endpoint without modification. The architectural twist is that the OAuth resource-server role is **split +across two HTTP participants**: + +| Role | Who handles it | +|-----------------------------------------------------|---------------------------------| +| Returns `401 Unauthorized` with `WWW-Authenticate` | DIAL | +| Hosts `/.well-known/oauth-protected-resource` (RFC 9728) | DIAL | +| Validates and uses the presented bearer | StatGPT MCP (after DIAL forwards it) | +| Acts as the OAuth authorization server | The IDP (Keycloak, Entra ID, โ€ฆ) | + +This split is invisible to MCP clients โ€” they see one logical resource server that behaves correctly under +[RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728), and run their handshake against whatever +`authorization_servers` URL DIAL advertised. + +### Why this split + +- **Single IDP across the platform** โ€” DIAL Core terminates discovery for every DIAL Application; StatGPT MCP + doesn't reimplement RFC 9728 / RFC 8414 endpoints. +- **Smaller StatGPT auth surface** โ€” StatGPT processes never run the OAuth dance, so they cannot leak codes, + PKCE verifiers, or client secrets. +- **One audit / per-request-key enforcement layer** โ€” DIAL Core handles both, consistent with how it handles every + other DIAL Application. + +## ๐Ÿ” 5. Refresh Tokens & Session Lifecycle + +Refresh tokens are **owned by the MCP client** and live in its OAuth session against the IDP. DIAL is not in the +refresh path: + +- When the client's access token expires, the client runs the refresh-token grant directly against the IDP and gets + a new access token. +- The new bearer is presented to DIAL on the next call; DIAL forwards it, same as before. +- StatGPT MCP never sees refresh tokens โ€” it only ever sees a current access token in the `Authorization` header. +- If the IDP rejects a refresh (session revoked, etc.), the client gets a fresh 401 from DIAL on its next call and + the discovery dance starts over from ยง2 step 1. + +The MCP server runs with `stateless_http=True` (`statgpt/app/mcp/app.py`), so token freshness is established per +request from the headers; nothing is cached across calls. + +## ๐Ÿ“š 6. Authoritative References + +### Model Context Protocol + +- Protocol home: +- Authorization specification: +- Security best practices: +- FastMCP framework: + +### OAuth / IETF (referenced by MCP) + +- OAuth 2.1 (IETF draft): +- RFC 9728 โ€” Protected Resource Metadata: +- RFC 8414 โ€” Authorization Server Metadata: +- RFC 7591 โ€” Dynamic Client Registration: +- RFC 8707 โ€” Resource Indicators: + +### AI DIAL + +- Homepage: +- Documentation: +- Applications administration: +- Application config schema (DIAL Core): +- Per-request keys: +- JWT auth & access control: + +### Internal (this repo) + +- [README.md](./README.md) โ€” Application MCP details +- [Admin Azure Auth Guide](../guides/admin-azure-auth-guide.md) From 385ccf58255638692da97d661ac809ef8760def1 Mon Sep 17 00:00:00 2001 From: Iliia_Veselov Date: Tue, 5 May 2026 10:29:02 +0300 Subject: [PATCH 2/3] feat: Add StatGPT MCP documentation; review fixes --- README.md | 7 +- architecture/README.md | 2 +- architecture/mcp.md | 271 +++++++++++++++++++++++++++++++++++++++ architecture/overview.md | 2 +- architecture/services.md | 2 +- architecture/tools.md | 3 +- mcp/README.md | 146 --------------------- mcp/auth.md | 138 -------------------- 8 files changed, 278 insertions(+), 293 deletions(-) create mode 100644 architecture/mcp.md delete mode 100644 mcp/README.md delete mode 100644 mcp/auth.md diff --git a/README.md b/README.md index 6596d41..ac19c81 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,9 @@ StatGPT bridges the gap between complex statistical databases and everyday users - [Architecture Overview](./architecture/overview.md) - Solution overview and core requirements - [SDMX Compatibility](./architecture/sdmx-compatibility.md) - SDMX integration details -### [Application MCP](./mcp/README.md) -Programmatic tool access via the Model Context Protocol: -- Channel tools exposed to DIAL applications and other MCP-aware clients -- [Authentication & Authorization](./mcp/auth.md) - DIAL Application config, MCP-spec discovery, IDP OAuth flow +### [Application MCP](./architecture/mcp.md) +Programmatic tool access via the Model Context Protocol โ€” channel tools exposed to DIAL applications and other +MCP-aware clients, with DIAL Application registration, MCP-spec discovery, and IDP OAuth flow. ### Guides - [Admin Guide](./guides/admin-guide.md) - System administration and configuration diff --git a/architecture/README.md b/architecture/README.md index f4f8096..104b054 100644 --- a/architecture/README.md +++ b/architecture/README.md @@ -12,7 +12,7 @@ design, services, tools, and integration requirements. | **[๐Ÿ“‹ Overview](./overview.md)** | Complete platform overview with requirements and features | โ€ข Natural language querying
โ€ข Data accuracy & reliability
โ€ข Security & governance
โ€ข Performance & scalability | | **[๐Ÿญ Services](./services.md)** | Core services and dependencies architecture | โ€ข Chat Backend (DIAL app)
โ€ข Admin Backend & Frontend
โ€ข Portal Frontend
โ€ข Third-party integrations | | **[๐Ÿ”ง Tools](./tools.md)** | Agent tools and capabilities documentation | โ€ข Data query tools
โ€ข Publications RAG
โ€ข Glossary management
โ€ข Web search integration | -| **[๐Ÿ”Œ Application MCP](../mcp/README.md)** | Programmatic tool access via Model Context Protocol | โ€ข Channel tools over MCP
โ€ข DIAL Application registration
โ€ข MCP-spec discovery + IDP OAuth flow | +| **[๐Ÿ”Œ Application MCP](./mcp.md)** | Programmatic tool access via Model Context Protocol | โ€ข Channel tools over MCP
โ€ข DIAL Application registration
โ€ข MCP-spec discovery + IDP OAuth flow | | **[๐Ÿ“Š SDMX Compatibility](./sdmx-compatibility.md)** | SDMX standards and requirements guide | โ€ข Version support (2.1/3.0)
โ€ข Metadata requirements
โ€ข Performance standards
โ€ข Quality checklist | ### Design Documentation diff --git a/architecture/mcp.md b/architecture/mcp.md new file mode 100644 index 0000000..1564e76 --- /dev/null +++ b/architecture/mcp.md @@ -0,0 +1,271 @@ +# Application MCP + +MCP server hosted by the **Chat Backend** that exposes a channel's StatGPT tools (data query, RAG, glossary, web +search, โ€ฆ) over the [Model Context Protocol](https://modelcontextprotocol.io/), so DIAL applications and other +MCP-aware clients can invoke them under their own LLM control. + +## ๐ŸŽฏ Scope + +- **Does**: Exposes the same primitives the StatGPT supreme agent uses internally. +- **Does not**: Replace the supreme agent's `/chat/completions` endpoint, pick tools, or compose multi-tool answers. +- **Configuration**: Tools surfaced for `deployment_id=foo` come directly from `foo`'s channel YAML โ€” no + MCP-specific override. + +## ๐Ÿ”Œ Endpoint + +| Property | Value | +|------------|--------------------------------------------------------| +| Path | `POST /api/v1/{deployment_id}/mcp` on Chat Backend | +| Mounted in | `statgpt/app/application/app_factory.py` | +| Transport | `streamable-http`, `stateless_http=True` | +| Bootstrap | `statgpt/app/mcp/app.py` | +| Provider | `statgpt/app/mcp/provider.py` (`ChannelToolProvider`) | + +`{deployment_id}` selects the channel; tools and config differ per channel. The endpoint is part of the Chat Backend +image โ€” there is no separate enable flag. To make it reachable, register StatGPT as a DIAL Application (see +[Authentication & Authorization](#-authentication--authorization) below). + +The server's `instructions=` field (sent to clients during MCP `initialize`) reads: + +> *This server provides tools from the StatGPT platform for querying official statistics data, searching publications, +> looking up glossary terms, and more. Tools are channel-specific and depend on the deployment configuration.* + +## โš™๏ธ Dynamic Tool Surface + +On every `tools/list` and `tools/call`, `ChannelToolProvider`: + +1. Reads `Authorization` + `api-key` from headers and builds an `AuthContext`. +2. Resolves `{deployment_id}` to a `ChannelServiceFacade` and loads `ChannelConfig`. +3. Wraps each `StatGptTool` in `_McpToolAdapter`, exposing it as an MCP tool. + +The MCP tool **name** and **description** come from the channel YAML; the **parameter schema** comes from each tool's +`get_public_args_schema()`. + +## ๐Ÿ› ๏ธ Tools Catalog + +Application MCP exposes whichever tools the channel YAML enables. The full tool catalog and per-tool semantics live +in [Architecture / Tools](./tools.md). The implementation maps each tool config to a class via +[`statgpt/common/schemas/enums.py::ToolTypes`](https://github.com/epam/statgpt-backend). + +## ๐Ÿ“ Configuring the Tool Surface + +Channel YAML excerpt (from +[`tools.yaml`](https://github.com/epam/statgpt-backend/blob/development/configurations/clients/sample/tools.yaml)): + +```yaml +tools: + - type: available_datasets + name: "Available_Datasets" + description: >- + Provides a list of all available datasets โ€ฆ This tool does not accept any arguments. + details: + version: full + include_indicator_count: true + + - type: data_query + name: "Query_Data" + description: >- + Translates a natural-language question into an SDMX query and executes it. + details: + # ... model deployments, prompts, etc. +``` + +| Field | Becomes | +|---------------|---------------------------------------------------------------------------| +| `type` | Implementation class (see [Architecture / Tools](./tools.md)). | +| `name` | MCP tool name surfaced via `tools/list`. | +| `description` | MCP tool description fed to the calling LLM. | + +Channel-level config (LLM models, glossaries, supreme-agent settings) lives in `channels.yaml` โ€” see +[Admin Guide](../guides/admin-guide.md). The MCP server inherits from there automatically. + +## ๐Ÿ“ฆ Returning Data Resources + +`DATA_QUERY` is the only tool emitting non-text results. In addition to a textual summary it returns one or more +`text/csv` resources via `data_query_artifact_to_resources()` (`statgpt/app/mcp/attachments.py`): + +``` +URI: statgpt://data_query/{path}/{timestamp}.csv +``` + +## ๐Ÿ”„ Sample MCP Exchanges + +JSON-RPC over `streamable-http`. Headers populated by DIAL after the OAuth handshake โ€” see +[Authentication & Authorization](#-authentication--authorization) below. + +> **๐Ÿ“ Note**: The `inputSchema` payloads below are illustrative. The real schemas come from each tool's +> `get_public_args_schema()` and may include additional optional fields. + +### `tools/list` + +```http +POST /api/v1/statgpt-sample/mcp HTTP/1.1 +Authorization: Bearer +api-key: +Content-Type: application/json + +{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" } +``` + +```json +{ + "jsonrpc": "2.0", "id": 1, + "result": { + "tools": [ + { "name": "Available_Datasets", + "description": "Provides a list of all available datasets...", + "inputSchema": { "type": "object", "properties": {}, "required": [] } }, + { "name": "Query_Data", + "description": "Translates a natural-language question into an SDMX query...", + "inputSchema": { + "type": "object", + "properties": { "query": { "type": "string" } }, + "required": ["query"] } } + ] + } +} +``` + +### `tools/call` + +```http +POST /api/v1/statgpt-sample/mcp HTTP/1.1 +Authorization: Bearer +api-key: +Content-Type: application/json + +{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", + "params": { + "name": "Query_Data", + "arguments": { "query": "What is the IMF WEO projection for US GDP for the next 2 years?" } } } +``` + +```json +{ + "jsonrpc": "2.0", "id": 2, + "result": { + "content": [ + { "type": "text", "text": "Here is the IMF WEO projection for US GDP ..." }, + { "type": "resource", + "resource": { + "uri": "statgpt://data_query/imf-weo/{YYYYMMDDTHHMMSSZ}.csv", + "mimeType": "text/csv", + "text": "country,year,value\nUSA,2026,...\nUSA,2027,..." } } + ] + } +} +``` + +## ๐Ÿ” Authentication & Authorization + +Application MCP is wired into AI DIAL as a **DIAL Application**. StatGPT itself runs no OAuth flow. DIAL Core acts as +the MCP-spec authorization-server discovery layer in front of the MCP endpoint, points clients at the configured IDP, +and forwards the resulting bearer + per-request key on every proxied tool call. + +### Registration: DIAL Application + +StatGPT is registered with DIAL as a **DIAL Application**. A DIAL Application can declare both a chat-completion +endpoint and an MCP endpoint side-by-side; DIAL Core proxies traffic to either through its routing layer. + +Authoritative DIAL docs: + +- Application administration UI / fields โ†’ [docs.dialx.ai entities-applications](https://docs.dialx.ai/tutorials/admin/entities-applications). +- Application config schema โ†’ [DIAL Core applications.md](https://github.com/epam/ai-dial-core/blob/development/docs/dynamic-settings/applications.md). +- Per-request keys โ†’ [docs.dialx.ai per-request-keys](https://docs.dialx.ai/platform/core/per-request-keys). + +Relevant fields on the StatGPT Application: + +| Field | Value | Effect | +|--------------------|--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------| +| `mcpEndpoint` | `https:///api/v1/{deployment_id}/mcp` | The MCP endpoint DIAL Core proxies to. | +| `forwardAuthToken` | `true` | DIAL forwards the caller's `Authorization: Bearer โ€ฆ` header to the application unchanged on every proxied call. | + +There is no per-application OAuth client config (no `client_id`, no `redirect_uri`, no DIAL-side signin endpoint). +DIAL's job is discovery + forwarding, not running OAuth itself. + +### Auth Flow + +The flow follows the [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) +discovery flow, with two architectural details: + +- **DIAL plays the resource-server-front role.** It returns the 401 + `WWW-Authenticate`, hosts + `/.well-known/oauth-protected-resource` (RFC 9728), and points clients at the IDP via the `authorization_servers` + field. StatGPT MCP itself has no `/.well-known` endpoints and does not return 401s โ€” it never sees a request + without a bearer. +- **DIAL is not in the OAuth path.** The OAuth 2.1 + PKCE handshake happens directly between the MCP client and the + IDP (Keycloak, Entra ID, โ€ฆ). DIAL holds no PKCE verifier, no authorization code, no refresh token, no per-app + client credentials. + +After the client has a bearer: + +1. Client โ†’ DIAL: `tools/call` with `Authorization: Bearer `. +2. DIAL โ†’ StatGPT MCP: same call, with the bearer forwarded (because `forwardAuthToken=true`) and an additional + `api-key: ` header. +3. StatGPT MCP processes the call (see the next subsection). + +### How Application MCP Consumes the Forwarded Auth + +`DialAuthCredentials.from_headers` (`statgpt/app/security/credentials.py`) reads `api-key` and +`Authorization: Bearer โ€ฆ`. `create_auth_context` (`statgpt/app/security/auth_context.py`) is invoked by the MCP +provider with the default `bearer_token_required=False`, which means it always returns a `UserAuthContext`: + +| Context | When | Notes | +|-------------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `UserAuthContext` | Always (on the MCP entry path) | If a bearer is present the JWT is reused for callbacks into DIAL via `UserAuthContext.dial_access_token`. If absent, `dial_access_token` is `None` and any tool that needs the JWT will fail at use time. | +| `SystemUserAuthContext` | Not reached from MCP | Would require `bearer_token_required=True` at the call site, which `statgpt/app/mcp/provider.py` does not pass. Reserved for chat-completion / DIAL-SDK paths that opt in to that flag. | + +Subsequent failures are lazy: a missing `api-key` raises `MissingApiKeyError` when first dereferenced; an +authentication or authorization error during channel resolution causes `_list_tools` to swallow it and return an +empty tool list (`tools/call` errors). + +### Relationship to the MCP Authorization Specification + +At the wire level StatGPT's MCP authorization is **spec-compliant** โ€” a spec-compliant MCP client (one that +implements the discovery flow described in +[MCP Authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization)) works against the +StatGPT MCP endpoint without modification. The architectural twist is that the OAuth resource-server role is **split +across two HTTP participants**: + +| Role | Who handles it | +|-----------------------------------------------------|---------------------------------| +| Returns `401 Unauthorized` with `WWW-Authenticate` | DIAL | +| Hosts `/.well-known/oauth-protected-resource` (RFC 9728) | DIAL | +| Validates and uses the presented bearer | StatGPT MCP (after DIAL forwards it) | +| Acts as the OAuth authorization server | The IDP (Keycloak, Entra ID, โ€ฆ) | + +This split is invisible to MCP clients โ€” they see one logical resource server that behaves correctly under +[RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728), and run their handshake against whatever +`authorization_servers` URL DIAL advertised. + +**Why this split:** + +- **Single IDP across the platform** โ€” DIAL Core terminates discovery for every DIAL Application; StatGPT MCP + doesn't reimplement RFC 9728 / RFC 8414 endpoints. +- **Smaller StatGPT auth surface** โ€” StatGPT processes never run the OAuth handshake, so they cannot leak codes, + PKCE verifiers, or client secrets. +- **One audit / per-request-key enforcement layer** โ€” DIAL Core handles both, consistent with how it handles every + other DIAL Application. + +### Refresh Tokens & Session Lifecycle + +Refresh tokens are **owned by the MCP client** and live in its OAuth session against the IDP. DIAL is not in the +refresh path: + +- When the client's access token expires, the client runs the refresh-token grant directly against the IDP and gets + a new access token. +- The new bearer is presented to DIAL on the next call; DIAL forwards it, same as before. +- StatGPT MCP never sees refresh tokens โ€” it only ever sees a current access token in the `Authorization` header. +- If the IDP rejects a refresh (session revoked, etc.), the client gets a fresh 401 from DIAL on its next call and + the discovery flow starts over. + +The MCP server runs with `stateless_http=True` (`statgpt/app/mcp/app.py`), so token freshness is established per +request from the headers; nothing is cached across calls. + +## ๐Ÿ“š References + +- [MCP Authorization specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) โ€” + the canonical OAuth 2.1 + PKCE discovery flow that DIAL implements in front of the StatGPT MCP endpoint. +- [DIAL Core applications.md](https://github.com/epam/ai-dial-core/blob/development/docs/dynamic-settings/applications.md) โ€” + Application config schema (`mcpEndpoint`, `forwardAuthToken`, โ€ฆ). +- [DIAL per-request keys](https://docs.dialx.ai/platform/core/per-request-keys) โ€” how DIAL Core injects `api-key` + headers on every proxied application call. diff --git a/architecture/overview.md b/architecture/overview.md index 1bf7104..630483c 100644 --- a/architecture/overview.md +++ b/architecture/overview.md @@ -207,7 +207,7 @@ Backend. AI DIAL fronts the endpoint as the `mcpEndpoint` of a DIAL Application; authorization-server discovery and forwards the user's bearer + per-request key to StatGPT, so DIAL applications and other MCP-aware clients can invoke the tools under their own LLM control. -โ†’ See the [Application MCP documentation](../mcp/README.md) for the endpoint, tool catalog, and authentication flow. +โ†’ See the [Application MCP documentation](../architecture/mcp.md) for the endpoint, tool catalog, and authentication flow. ### Security & Privacy diff --git a/architecture/services.md b/architecture/services.md index 4e59d5e..6895194 100644 --- a/architecture/services.md +++ b/architecture/services.md @@ -103,7 +103,7 @@ The Chat Backend exposes channel tools over the [Model Context Protocol](https:/ `mcpEndpoint` of a DIAL Application; DIAL handles MCP-spec authorization-server discovery and forwards user credentials to the endpoint. -โ†’ See [Application MCP](../mcp/README.md) for the tools catalog and request flow. +โ†’ See [Application MCP](./mcp.md) for the tools catalog and request flow. ### โš™๏ธ StatGPT Admin Backend diff --git a/architecture/tools.md b/architecture/tools.md index 7efe002..e13ed19 100644 --- a/architecture/tools.md +++ b/architecture/tools.md @@ -230,5 +230,4 @@ The same tool catalog above is also exposed over the [Model Context Protocol](ht StatGPT's **Application MCP** server, so DIAL applications and other MCP-aware clients can invoke them under their own LLM control. The MCP tool surface for a given channel is whatever its YAML enables. -โ†’ See [Application MCP](../mcp/README.md) for the endpoint, sample MCP exchanges, and the end-to-end client -walkthrough. +โ†’ See [Application MCP](./mcp.md) for the endpoint, sample MCP exchanges, and the end-to-end client walkthrough. diff --git a/mcp/README.md b/mcp/README.md deleted file mode 100644 index fbe1a99..0000000 --- a/mcp/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# Application MCP - -MCP server hosted by the **Chat Backend** that republishes a channel's StatGPT tools (data query, RAG, glossary, web -search, โ€ฆ) over the [Model Context Protocol](https://modelcontextprotocol.io/), so DIAL applications and other -MCP-aware clients can invoke them under their own LLM control. - -## ๐ŸŽฏ Scope - -- **Does**: Exposes the same primitives the StatGPT supreme agent uses internally. -- **Does not**: Replace the supreme agent's `/chat/completions` endpoint, pick tools, or compose multi-tool answers. -- **Configuration**: Tools surfaced for `deployment_id=foo` come directly from `foo`'s channel YAML โ€” no - MCP-specific override. - -## ๐Ÿ”Œ Endpoint - -| Property | Value | -|------------|--------------------------------------------------------| -| Path | `POST /api/v1/{deployment_id}/mcp` on Chat Backend | -| Mounted in | `statgpt/app/application/app_factory.py` | -| Transport | `streamable-http`, `stateless_http=True` | -| Bootstrap | `statgpt/app/mcp/app.py` | -| Provider | `statgpt/app/mcp/provider.py` (`ChannelToolProvider`) | - -`{deployment_id}` selects the channel; tools and config differ per channel. - -The server's `instructions=` field (sent to clients during MCP `initialize`) reads: - -> *This server provides tools from the StatGPT platform for querying official statistics data, searching publications, -> looking up glossary terms, and more. Tools are channel-specific and depend on the deployment configuration.* - -## โš™๏ธ Dynamic Tool Surface - -On every `tools/list` and `tools/call`, `ChannelToolProvider`: - -1. Reads `Authorization` + `api-key` from headers and builds an `AuthContext`. -2. Resolves `{deployment_id}` to a `ChannelServiceFacade` and loads `ChannelConfig`. -3. Wraps each `StatGptTool` in `_McpToolAdapter`, exposing it as an MCP tool. - -The MCP tool **name** and **description** come from the channel YAML; the **parameter schema** comes from each tool's -`get_public_args_schema()`. - -## ๐Ÿ› ๏ธ Tools Catalog - -Tool types registerable in a channel -([`statgpt/common/schemas/enums.py::ToolTypes`](https://github.com/epam/statgpt-backend)): - -| Tool type | Implementation class | Purpose | -|--------------------------|-----------------------------|----------------------------------------------------------------------| -| `AVAILABLE_DATASETS` | `AvailableDatasetsTool` | List datasets available to the channel. | -| `DATASETS_METADATA` | `DatasetsMetadataTool` | Metadata for a specific set of datasets. | -| `DATASET_STRUCTURE` | `DatasetStructureTool` | Dimensions and attributes of a dataset. | -| `AVAILABLE_PUBLICATIONS` | `AvailablePublicationsTool` | List publication types. | -| `AVAILABLE_TERMS` | `AvailableTermsTool` | List glossary terms. | -| `TERM_DEFINITIONS` | `TermDefinitionsTool` | Look up glossary definitions. | -| `DATA_QUERY` | `DataQueryTool` | Translate NL into SDMX, execute, return text + CSV resource. | -| `FILE_RAG` | `FileRagTool` | RAG over publication content. | -| `PLAIN_CONTENT` | `PlainContentTool` | Static content with env-var substitution. | -| `WEB_SEARCH` | `WebSearchTool` | Web search with summarized results. | -| `WEB_SEARCH_AGENT` | `WebSearchAgentTool` | Web search routed through an agent. | - -Functional details โ†’ [Architecture / Tools](../architecture/tools.md). - -## ๐Ÿ“ Configuring the Tool Surface - -Channel YAML excerpt (from -[`tools.yaml`](https://github.com/epam/statgpt-backend/blob/development/configurations/clients/sample/tools.yaml)): - -```yaml -tools: - - type: available_datasets - name: "Available_Datasets" - description: >- - Provides a list of all available datasets โ€ฆ This tool does not accept any arguments. - details: - version: full - include_indicator_count: true - - - type: data_query - name: "Query_Data" - description: >- - Translates a natural-language question into an SDMX query and executes it. - details: - # ... model deployments, prompts, etc. -``` - -| Field | Becomes | -|---------------|-----------------------------------------------| -| `type` | Implementation class (Tools Catalog above). | -| `name` | MCP tool name surfaced via `tools/list`. | -| `description` | MCP tool description fed to the calling LLM. | - -Channel-level config (LLM models, glossaries, supreme-agent settings) lives in `channels.yaml` โ€” see -[Admin Guide](../guides/admin-guide.md). The MCP server inherits from there automatically. - -## ๐Ÿ“ฆ Returning Data Resources - -`DATA_QUERY` is the only tool emitting non-text results. In addition to a textual summary it returns one or more -`text/csv` resources via `data_query_artifact_to_resources()` (`statgpt/app/mcp/attachments.py`): - -``` -URI: statgpt://data_query/{path}/{timestamp}.csv -``` - -## ๐Ÿ” Authentication - -DIAL terminates auth and forwards `Authorization: Bearer ` and `api-key: `. -`DialAuthCredentials.from_headers` (`statgpt/app/security/credentials.py`) is wrapped by `create_auth_context` -(`statgpt/app/security/auth_context.py`); the MCP provider calls it with the default `bearer_token_required=False`, -so the result is always a `UserAuthContext`: - -- **Bearer present** โ€” JWT is reused for callbacks into DIAL via `UserAuthContext.dial_access_token`. -- **Bearer absent** โ€” `dial_access_token` is `None`; any tool that needs the JWT fails at use time, and a missing - `api-key` raises `MissingApiKeyError` lazily during channel resolution. - -`SystemUserAuthContext` is **not reached from MCP** โ€” it requires `bearer_token_required=True` at the call site, -which `statgpt/app/mcp/provider.py` does not pass. Auth failures during channel resolution cause `tools/list` to -return an empty list and `tools/call` to error. Full flow โ†’ [auth.md](./auth.md). - -## ๐Ÿค– End-to-End: LLM Client Walkthrough - -1. **Operator** registers StatGPT in DIAL as a **DIAL Application** with `mcpEndpoint`. - See [auth.md ยง1](./auth.md#1-registration-dial-application). -2. **MCP client** issues `tools/list` against DIAL. DIAL responds with `401 Unauthorized` + Protected Resource - Metadata (RFC 9728) pointing at the IDP. The client runs OAuth 2.1 + PKCE directly against - the IDP โ€” DIAL is *not* in the OAuth path. -3. **Authenticated tool list.** Client retries `tools/list` with `Authorization: Bearer `. DIAL forwards - the bearer plus its own `api-key: ` to the StatGPT MCP endpoint. -4. **LLM** picks a tool (e.g. `Available_Datasets`), issues `tools/call`; DIAL forwards both headers. -5. For data questions the LLM picks `Query_Data`; the response includes text + CSV resource (above). -6. **Multi-tool reasoning is the client's job, not the MCP's.** For supreme-agent orchestration use the Chat Backend's - `/chat/completions` instead. - -For local-dev setups without DIAL, see the FastMCP HTTP-transport docs and the -[MCP authorization spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization). - -## ๐Ÿš€ Deployment - -Part of the Chat Backend image; no enable flag. Reachable through DIAL by registering StatGPT as a **DIAL Application** -with the MCP endpoint URL set on the `mcpEndpoint` field. See [auth.md](./auth.md) for the full configuration and -auth model. - -## ๐Ÿ”— See Also - -- [auth.md](./auth.md) โ€” DIAL Application config, auth flow, MCP-spec relationship -- [Architecture / Tools](../architecture/tools.md) -- [Architecture / Services](../architecture/services.md) diff --git a/mcp/auth.md b/mcp/auth.md deleted file mode 100644 index d53e77f..0000000 --- a/mcp/auth.md +++ /dev/null @@ -1,138 +0,0 @@ -# ๐Ÿ” MCP Authentication & Authorization - -[Application MCP](./README.md) is wired into AI DIAL as a **DIAL Application**. StatGPT itself runs no OAuth flow. -DIAL Core acts as the MCP-spec authorization-server discovery layer in front of the MCP endpoint, points clients at -the configured IDP, and forwards the resulting bearer + per-request key on every proxied tool call. - -## ๐Ÿงฉ 1. Registration: DIAL Application - -StatGPT is registered with DIAL as a **DIAL Application**. A DIAL Application can declare both a chat-completion -endpoint and an MCP endpoint side-by-side; DIAL Core proxies traffic to either through its routing layer. - -Authoritative DIAL docs: - -- Application administration UI / fields โ†’ [docs.dialx.ai entities-applications](https://docs.dialx.ai/tutorials/admin/entities-applications) - (the page explicitly defines "Chat Endpoint" and "MCP Endpoint" as Application properties). -- Application config schema โ†’ [DIAL Core applications.md](https://github.com/epam/ai-dial-core/blob/development/docs/dynamic-settings/applications.md) -- Per-request keys โ†’ [docs.dialx.ai per-request-keys](https://docs.dialx.ai/platform/core/per-request-keys). - -Relevant fields on the StatGPT Application: - -| Field | Value | Effect | -|-----------------------------|--------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------| -| `mcpEndpoint` | `https:///api/v1/{deployment_id}/mcp` | The MCP endpoint DIAL Core proxies to. | -| `endpoint` (chat completion)| (separate StatGPT chat endpoint) | Listed for completeness; not relevant to MCP traffic. | -| `forwardAuthToken` | `true` | DIAL forwards the caller's `Authorization: Bearer โ€ฆ` header to the application unchanged on every proxied call. | -| `accessibleByPerRequestKey` | `true` | Enables DIAL's per-request key forwarding in the `api-key` header. | - -There is no per-application OAuth client config (no `client_id`, no `redirect_uri`, no DIAL-side signin endpoint). -DIAL's job is discovery + forwarding, not running OAuth itself. - -## ๐Ÿ” 2. Auth Flow - -The flow is just the canonical [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) -discovery dance, with two architectural details: - -- **DIAL plays the resource-server-front role.** It returns the 401 + `WWW-Authenticate`, hosts - `/.well-known/oauth-protected-resource` (RFC 9728), and points clients at the IDP via the `authorization_servers` - field. StatGPT MCP itself has no `/.well-known` endpoints and does not return 401s โ€” it never sees a request - without a bearer. -- **DIAL is not in the OAuth path.** The OAuth 2.1 + PKCE handshake happens directly between the MCP client and the - IDP (Keycloak, Entra ID, โ€ฆ). DIAL holds no PKCE verifier, no authorization code, no refresh token, no per-app - client credentials. - -After the client has a bearer: - -1. Client โ†’ DIAL: `tools/call` with `Authorization: Bearer `. -2. DIAL โ†’ StatGPT MCP: same call, with the bearer forwarded (because `forwardAuthToken=true`) and an additional - `api-key: ` header. -3. StatGPT MCP processes the call (see ยง3). - -## ๐Ÿชช 3. How Application MCP Consumes the Forwarded Auth - -`DialAuthCredentials.from_headers` (`statgpt/app/security/credentials.py`) reads `api-key` and -`Authorization: Bearer โ€ฆ`. `create_auth_context` (`statgpt/app/security/auth_context.py`) is invoked by the MCP -provider with the default `bearer_token_required=False`, which means it always returns a `UserAuthContext`: - -| Context | When | Notes | -|-------------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `UserAuthContext` | Always (on the MCP entry path) | If a bearer is present the JWT is reused for callbacks into DIAL via `UserAuthContext.dial_access_token`. If absent, `dial_access_token` is `None` and any tool that needs the JWT will fail at use time. | -| `SystemUserAuthContext` | Not reached from MCP | Would require `bearer_token_required=True` at the call site, which `statgpt/app/mcp/provider.py` does not pass. Reserved for chat-completion / DIAL-SDK paths that opt in to that flag. | - -Subsequent failures are lazy: a missing `api-key` raises `MissingApiKeyError` when first dereferenced; an -authentication or authorization error during channel resolution causes `_list_tools` to swallow it and return an -empty tool list (`tools/call` errors). - -## ๐Ÿ“œ 4. Relationship to the MCP Authorization Specification - -At the wire level StatGPT's MCP authorization is **spec-compliant** โ€” a spec-compliant MCP client (one that -implements the discovery dance described in -[MCP Authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization)) works against the -StatGPT MCP endpoint without modification. The architectural twist is that the OAuth resource-server role is **split -across two HTTP participants**: - -| Role | Who handles it | -|-----------------------------------------------------|---------------------------------| -| Returns `401 Unauthorized` with `WWW-Authenticate` | DIAL | -| Hosts `/.well-known/oauth-protected-resource` (RFC 9728) | DIAL | -| Validates and uses the presented bearer | StatGPT MCP (after DIAL forwards it) | -| Acts as the OAuth authorization server | The IDP (Keycloak, Entra ID, โ€ฆ) | - -This split is invisible to MCP clients โ€” they see one logical resource server that behaves correctly under -[RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728), and run their handshake against whatever -`authorization_servers` URL DIAL advertised. - -### Why this split - -- **Single IDP across the platform** โ€” DIAL Core terminates discovery for every DIAL Application; StatGPT MCP - doesn't reimplement RFC 9728 / RFC 8414 endpoints. -- **Smaller StatGPT auth surface** โ€” StatGPT processes never run the OAuth dance, so they cannot leak codes, - PKCE verifiers, or client secrets. -- **One audit / per-request-key enforcement layer** โ€” DIAL Core handles both, consistent with how it handles every - other DIAL Application. - -## ๐Ÿ” 5. Refresh Tokens & Session Lifecycle - -Refresh tokens are **owned by the MCP client** and live in its OAuth session against the IDP. DIAL is not in the -refresh path: - -- When the client's access token expires, the client runs the refresh-token grant directly against the IDP and gets - a new access token. -- The new bearer is presented to DIAL on the next call; DIAL forwards it, same as before. -- StatGPT MCP never sees refresh tokens โ€” it only ever sees a current access token in the `Authorization` header. -- If the IDP rejects a refresh (session revoked, etc.), the client gets a fresh 401 from DIAL on its next call and - the discovery dance starts over from ยง2 step 1. - -The MCP server runs with `stateless_http=True` (`statgpt/app/mcp/app.py`), so token freshness is established per -request from the headers; nothing is cached across calls. - -## ๐Ÿ“š 6. Authoritative References - -### Model Context Protocol - -- Protocol home: -- Authorization specification: -- Security best practices: -- FastMCP framework: - -### OAuth / IETF (referenced by MCP) - -- OAuth 2.1 (IETF draft): -- RFC 9728 โ€” Protected Resource Metadata: -- RFC 8414 โ€” Authorization Server Metadata: -- RFC 7591 โ€” Dynamic Client Registration: -- RFC 8707 โ€” Resource Indicators: - -### AI DIAL - -- Homepage: -- Documentation: -- Applications administration: -- Application config schema (DIAL Core): -- Per-request keys: -- JWT auth & access control: - -### Internal (this repo) - -- [README.md](./README.md) โ€” Application MCP details -- [Admin Azure Auth Guide](../guides/admin-azure-auth-guide.md) From 3034d4c072eee8ae0eeba351f281a88c438bfd4e Mon Sep 17 00:00:00 2001 From: Iliia_Veselov Date: Tue, 5 May 2026 18:06:25 +0300 Subject: [PATCH 3/3] feat: Add StatGPT MCP documentation; review fixes --- README.md | 4 +- architecture/README.md | 4 +- architecture/mcp.md | 168 +++------------------------------------ architecture/overview.md | 9 +-- architecture/services.md | 6 +- architecture/tools.md | 8 +- 6 files changed, 27 insertions(+), 172 deletions(-) diff --git a/README.md b/README.md index ac19c81..89663a7 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ StatGPT bridges the gap between complex statistical databases and everyday users - [SDMX Compatibility](./architecture/sdmx-compatibility.md) - SDMX integration details ### [Application MCP](./architecture/mcp.md) -Programmatic tool access via the Model Context Protocol โ€” channel tools exposed to DIAL applications and other -MCP-aware clients, with DIAL Application registration, MCP-spec discovery, and IDP OAuth flow. +Agentic access via the Model Context Protocol โ€” channel tools surfaced to AI agents (Claude, Cursor, MCP-aware DIAL +applications). Covers DIAL Application registration, MCP-spec discovery, and IDP OAuth flow in one page. ### Guides - [Admin Guide](./guides/admin-guide.md) - System administration and configuration diff --git a/architecture/README.md b/architecture/README.md index 104b054..ee715de 100644 --- a/architecture/README.md +++ b/architecture/README.md @@ -12,10 +12,10 @@ design, services, tools, and integration requirements. | **[๐Ÿ“‹ Overview](./overview.md)** | Complete platform overview with requirements and features | โ€ข Natural language querying
โ€ข Data accuracy & reliability
โ€ข Security & governance
โ€ข Performance & scalability | | **[๐Ÿญ Services](./services.md)** | Core services and dependencies architecture | โ€ข Chat Backend (DIAL app)
โ€ข Admin Backend & Frontend
โ€ข Portal Frontend
โ€ข Third-party integrations | | **[๐Ÿ”ง Tools](./tools.md)** | Agent tools and capabilities documentation | โ€ข Data query tools
โ€ข Publications RAG
โ€ข Glossary management
โ€ข Web search integration | -| **[๐Ÿ”Œ Application MCP](./mcp.md)** | Programmatic tool access via Model Context Protocol | โ€ข Channel tools over MCP
โ€ข DIAL Application registration
โ€ข MCP-spec discovery + IDP OAuth flow | +| **[๐Ÿ”Œ Application MCP](./mcp.md)** | Agentic access via Model Context Protocol | โ€ข Channel tools surfaced to AI agents
โ€ข DIAL Application registration
โ€ข MCP-spec discovery + IDP OAuth flow | | **[๐Ÿ“Š SDMX Compatibility](./sdmx-compatibility.md)** | SDMX standards and requirements guide | โ€ข Version support (2.1/3.0)
โ€ข Metadata requirements
โ€ข Performance standards
โ€ข Quality checklist | -### Design Documentation +### Design Documentation/res | Document | Description | Key Topics | |-----------------------------------|-----------------------------------------------|-----------------------------------------------------------------------------------| diff --git a/architecture/mcp.md b/architecture/mcp.md index 1564e76..bd4699e 100644 --- a/architecture/mcp.md +++ b/architecture/mcp.md @@ -1,160 +1,30 @@ # Application MCP -MCP server hosted by the **Chat Backend** that exposes a channel's StatGPT tools (data query, RAG, glossary, web -search, โ€ฆ) over the [Model Context Protocol](https://modelcontextprotocol.io/), so DIAL applications and other -MCP-aware clients can invoke them under their own LLM control. +Application MCP gives AI agents โ€” Claude, Cursor, custom DIAL applications, and other MCP-aware LLM clients โ€” +agentic access to a channel's StatGPT tools (data query, RAG, glossary, web search, โ€ฆ) over the +[Model Context Protocol](https://modelcontextprotocol.io/), so the agent can invoke those tools inside its own +reasoning loop. ## ๐ŸŽฏ Scope - **Does**: Exposes the same primitives the StatGPT supreme agent uses internally. - **Does not**: Replace the supreme agent's `/chat/completions` endpoint, pick tools, or compose multi-tool answers. -- **Configuration**: Tools surfaced for `deployment_id=foo` come directly from `foo`'s channel YAML โ€” no - MCP-specific override. +- **Configuration**: Tools surfaced for `deployment_id=foo` come directly from `foo`'s channel YAML โ€” no MCP-specific override. ## ๐Ÿ”Œ Endpoint | Property | Value | |------------|--------------------------------------------------------| | Path | `POST /api/v1/{deployment_id}/mcp` on Chat Backend | -| Mounted in | `statgpt/app/application/app_factory.py` | -| Transport | `streamable-http`, `stateless_http=True` | -| Bootstrap | `statgpt/app/mcp/app.py` | -| Provider | `statgpt/app/mcp/provider.py` (`ChannelToolProvider`) | +| Transport | HTTP streaming (`streamable-http`) | `{deployment_id}` selects the channel; tools and config differ per channel. The endpoint is part of the Chat Backend image โ€” there is no separate enable flag. To make it reachable, register StatGPT as a DIAL Application (see [Authentication & Authorization](#-authentication--authorization) below). -The server's `instructions=` field (sent to clients during MCP `initialize`) reads: +## ๐Ÿ› ๏ธ Tools -> *This server provides tools from the StatGPT platform for querying official statistics data, searching publications, -> looking up glossary terms, and more. Tools are channel-specific and depend on the deployment configuration.* - -## โš™๏ธ Dynamic Tool Surface - -On every `tools/list` and `tools/call`, `ChannelToolProvider`: - -1. Reads `Authorization` + `api-key` from headers and builds an `AuthContext`. -2. Resolves `{deployment_id}` to a `ChannelServiceFacade` and loads `ChannelConfig`. -3. Wraps each `StatGptTool` in `_McpToolAdapter`, exposing it as an MCP tool. - -The MCP tool **name** and **description** come from the channel YAML; the **parameter schema** comes from each tool's -`get_public_args_schema()`. - -## ๐Ÿ› ๏ธ Tools Catalog - -Application MCP exposes whichever tools the channel YAML enables. The full tool catalog and per-tool semantics live -in [Architecture / Tools](./tools.md). The implementation maps each tool config to a class via -[`statgpt/common/schemas/enums.py::ToolTypes`](https://github.com/epam/statgpt-backend). - -## ๐Ÿ“ Configuring the Tool Surface - -Channel YAML excerpt (from -[`tools.yaml`](https://github.com/epam/statgpt-backend/blob/development/configurations/clients/sample/tools.yaml)): - -```yaml -tools: - - type: available_datasets - name: "Available_Datasets" - description: >- - Provides a list of all available datasets โ€ฆ This tool does not accept any arguments. - details: - version: full - include_indicator_count: true - - - type: data_query - name: "Query_Data" - description: >- - Translates a natural-language question into an SDMX query and executes it. - details: - # ... model deployments, prompts, etc. -``` - -| Field | Becomes | -|---------------|---------------------------------------------------------------------------| -| `type` | Implementation class (see [Architecture / Tools](./tools.md)). | -| `name` | MCP tool name surfaced via `tools/list`. | -| `description` | MCP tool description fed to the calling LLM. | - -Channel-level config (LLM models, glossaries, supreme-agent settings) lives in `channels.yaml` โ€” see -[Admin Guide](../guides/admin-guide.md). The MCP server inherits from there automatically. - -## ๐Ÿ“ฆ Returning Data Resources - -`DATA_QUERY` is the only tool emitting non-text results. In addition to a textual summary it returns one or more -`text/csv` resources via `data_query_artifact_to_resources()` (`statgpt/app/mcp/attachments.py`): - -``` -URI: statgpt://data_query/{path}/{timestamp}.csv -``` - -## ๐Ÿ”„ Sample MCP Exchanges - -JSON-RPC over `streamable-http`. Headers populated by DIAL after the OAuth handshake โ€” see -[Authentication & Authorization](#-authentication--authorization) below. - -> **๐Ÿ“ Note**: The `inputSchema` payloads below are illustrative. The real schemas come from each tool's -> `get_public_args_schema()` and may include additional optional fields. - -### `tools/list` - -```http -POST /api/v1/statgpt-sample/mcp HTTP/1.1 -Authorization: Bearer -api-key: -Content-Type: application/json - -{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" } -``` - -```json -{ - "jsonrpc": "2.0", "id": 1, - "result": { - "tools": [ - { "name": "Available_Datasets", - "description": "Provides a list of all available datasets...", - "inputSchema": { "type": "object", "properties": {}, "required": [] } }, - { "name": "Query_Data", - "description": "Translates a natural-language question into an SDMX query...", - "inputSchema": { - "type": "object", - "properties": { "query": { "type": "string" } }, - "required": ["query"] } } - ] - } -} -``` - -### `tools/call` - -```http -POST /api/v1/statgpt-sample/mcp HTTP/1.1 -Authorization: Bearer -api-key: -Content-Type: application/json - -{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", - "params": { - "name": "Query_Data", - "arguments": { "query": "What is the IMF WEO projection for US GDP for the next 2 years?" } } } -``` - -```json -{ - "jsonrpc": "2.0", "id": 2, - "result": { - "content": [ - { "type": "text", "text": "Here is the IMF WEO projection for US GDP ..." }, - { "type": "resource", - "resource": { - "uri": "statgpt://data_query/imf-weo/{YYYYMMDDTHHMMSSZ}.csv", - "mimeType": "text/csv", - "text": "country,year,value\nUSA,2026,...\nUSA,2027,..." } } - ] - } -} -``` +Application MCP exposes whichever tools the channel YAML enables. The full tool catalog and per-tool semantics live in [Architecture / Tools](./tools.md). ## ๐Ÿ” Authentication & Authorization @@ -201,22 +71,8 @@ After the client has a bearer: 1. Client โ†’ DIAL: `tools/call` with `Authorization: Bearer `. 2. DIAL โ†’ StatGPT MCP: same call, with the bearer forwarded (because `forwardAuthToken=true`) and an additional `api-key: ` header. -3. StatGPT MCP processes the call (see the next subsection). - -### How Application MCP Consumes the Forwarded Auth - -`DialAuthCredentials.from_headers` (`statgpt/app/security/credentials.py`) reads `api-key` and -`Authorization: Bearer โ€ฆ`. `create_auth_context` (`statgpt/app/security/auth_context.py`) is invoked by the MCP -provider with the default `bearer_token_required=False`, which means it always returns a `UserAuthContext`: - -| Context | When | Notes | -|-------------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `UserAuthContext` | Always (on the MCP entry path) | If a bearer is present the JWT is reused for callbacks into DIAL via `UserAuthContext.dial_access_token`. If absent, `dial_access_token` is `None` and any tool that needs the JWT will fail at use time. | -| `SystemUserAuthContext` | Not reached from MCP | Would require `bearer_token_required=True` at the call site, which `statgpt/app/mcp/provider.py` does not pass. Reserved for chat-completion / DIAL-SDK paths that opt in to that flag. | - -Subsequent failures are lazy: a missing `api-key` raises `MissingApiKeyError` when first dereferenced; an -authentication or authorization error during channel resolution causes `_list_tools` to swallow it and return an -empty tool list (`tools/call` errors). +3. StatGPT MCP treats both headers as already-validated input โ€” it does no token validation of its own. If neither + header reaches the server, `tools/list` returns empty and `tools/call` errors. ### Relationship to the MCP Authorization Specification @@ -258,8 +114,8 @@ refresh path: - If the IDP rejects a refresh (session revoked, etc.), the client gets a fresh 401 from DIAL on its next call and the discovery flow starts over. -The MCP server runs with `stateless_http=True` (`statgpt/app/mcp/app.py`), so token freshness is established per -request from the headers; nothing is cached across calls. +The MCP server is stateless โ€” token freshness is established per request from the forwarded headers, with nothing +cached across calls. ## ๐Ÿ“š References diff --git a/architecture/overview.md b/architecture/overview.md index 630483c..928d25f 100644 --- a/architecture/overview.md +++ b/architecture/overview.md @@ -199,15 +199,14 @@ The AI agent is explicitly instructed to: โ†’ See [AI DIAL Access Control](https://docs.dialx.ai/platform/core/access-control-intro) for configuration. -### Programmatic Access via MCP +### Agentic Access via MCP In addition to the chat UI, StatGPT exposes a channel's configured tools (data query, RAG, glossary, web search, โ€ฆ) over the [Model Context Protocol](https://modelcontextprotocol.io/) via **Application MCP**, mounted on the Chat -Backend. AI DIAL fronts the endpoint as the `mcpEndpoint` of a DIAL Application; DIAL handles MCP-spec -authorization-server discovery and forwards the user's bearer + per-request key to StatGPT, so DIAL applications and -other MCP-aware clients can invoke the tools under their own LLM control. +Backend. AI DIAL fronts the endpoint as the `mcpEndpoint` of a DIAL Application and handles MCP-spec +authorization-server discovery, so AI agents can invoke StatGPT tools inside their own reasoning loops. -โ†’ See the [Application MCP documentation](../architecture/mcp.md) for the endpoint, tool catalog, and authentication flow. +โ†’ See [Application MCP](./mcp.md) for the endpoint, tool catalog, and authentication flow. ### Security & Privacy diff --git a/architecture/services.md b/architecture/services.md index 6895194..f1c9a17 100644 --- a/architecture/services.md +++ b/architecture/services.md @@ -99,9 +99,9 @@ with [DIAL API Specification](https://dialx.ai/dial_api#operation/sendChatComple #### MCP Endpoint The Chat Backend exposes channel tools over the [Model Context Protocol](https://modelcontextprotocol.io/) at -`POST /api/v1/{deployment_id}/mcp`. The tool list is dynamic per channel and is fronted by AI DIAL as the -`mcpEndpoint` of a DIAL Application; DIAL handles MCP-spec authorization-server discovery and forwards user -credentials to the endpoint. +`POST /api/v1/{deployment_id}/mcp`, fronted by AI DIAL as the `mcpEndpoint` of a DIAL Application. DIAL handles +MCP-spec authorization-server discovery and forwards the user's credentials to the endpoint, so AI agents can +invoke channel tools inside their own reasoning loops. โ†’ See [Application MCP](./mcp.md) for the tools catalog and request flow. diff --git a/architecture/tools.md b/architecture/tools.md index e13ed19..46012a2 100644 --- a/architecture/tools.md +++ b/architecture/tools.md @@ -224,10 +224,10 @@ Returns: **Example Use Case**: Portal guides with dynamic information about available pages and features. -## ๐Ÿ”Œ Programmatic Access +## ๐Ÿ”Œ Agentic Access via MCP The same tool catalog above is also exposed over the [Model Context Protocol](https://modelcontextprotocol.io/) by -StatGPT's **Application MCP** server, so DIAL applications and other MCP-aware clients can invoke them under their -own LLM control. The MCP tool surface for a given channel is whatever its YAML enables. +StatGPT's **Application MCP** server, so AI agents can invoke these tools inside their own reasoning loops. +The MCP tool surface for a given channel is whatever its YAML enables. -โ†’ See [Application MCP](./mcp.md) for the endpoint, sample MCP exchanges, and the end-to-end client walkthrough. +โ†’ See [Application MCP](./mcp.md) for the endpoint and authentication flow.