diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 000000000..e7f32e65e
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1 @@
+**/schema.json
\ No newline at end of file
diff --git a/docs/docs.json b/docs/docs.json
index f3658ac8f..cbaa84d89 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -1,316 +1,306 @@
{
- "$schema": "https://mintlify.com/docs.json",
- "theme": "willow",
- "name": "Model Context Protocol",
- "colors": {
- "primary": "#09090b",
- "light": "#FAFAFA",
- "dark": "#09090b"
- },
- "favicon": "/favicon.svg",
- "navigation": {
- "tabs": [
- {
- "tab": "User Guide",
- "groups": [
- {
- "group": "Get Started",
- "pages": [
- "introduction",
- {
- "group": "Quickstart",
- "pages": [
- "quickstart/server",
- "quickstart/client",
- "quickstart/user"
+ "$schema": "https://mintlify.com/docs.json",
+ "theme": "willow",
+ "name": "Model Context Protocol",
+ "colors": { "primary": "#09090b", "light": "#FAFAFA", "dark": "#09090b" },
+ "favicon": "/favicon.svg",
+ "navigation": {
+ "tabs": [
+ {
+ "tab": "User Guide",
+ "groups": [
+ {
+ "group": "Get Started",
+ "pages": [
+ "introduction",
+ {
+ "group": "Quickstart",
+ "pages": [
+ "quickstart/server",
+ "quickstart/client",
+ "quickstart/user"
+ ]
+ },
+ "examples",
+ "clients",
+ "faqs"
+ ]
+ },
+ {
+ "group": "Tutorials",
+ "pages": [
+ "tutorials/building-mcp-with-llms",
+ "docs/tools/debugging",
+ "docs/tools/inspector"
+ ]
+ },
+ {
+ "group": "Concepts",
+ "pages": [
+ "docs/concepts/architecture",
+ "docs/concepts/resources",
+ "docs/concepts/prompts",
+ "docs/concepts/tools",
+ "docs/concepts/sampling",
+ "docs/concepts/roots",
+ "docs/concepts/transports"
+ ]
+ },
+ {
+ "group": "Development",
+ "pages": [
+ "development/roadmap",
+ "development/contributing"
+ ]
+ }
]
- },
- "examples",
- "clients",
- "faqs"
- ]
- },
- {
- "group": "Tutorials",
- "pages": [
- "tutorials/building-mcp-with-llms",
- "docs/tools/debugging",
- "docs/tools/inspector"
- ]
- },
- {
- "group": "Concepts",
- "pages": [
- "docs/concepts/architecture",
- "docs/concepts/resources",
- "docs/concepts/prompts",
- "docs/concepts/tools",
- "docs/concepts/sampling",
- "docs/concepts/roots",
- "docs/concepts/transports"
- ]
- },
- {
- "group": "Development",
- "pages": [
- "development/roadmap",
- "development/contributing"
- ]
- }
- ]
- },
- {
- "tab": "SDKs",
- "icon": "book-open",
- "groups": [
- {
- "group": "Java",
- "pages": [
- "sdk/java/mcp-overview",
- "sdk/java/mcp-client",
- "sdk/java/mcp-server"
- ]
- }
- ]
- },
- {
- "tab": "Specification",
- "icon": "book",
- "groups": [
- {
- "group": "2025-03-26 (Latest)",
- "pages": [
- "specification/2025-03-26/index",
- "specification/2025-03-26/changelog",
- "specification/2025-03-26/architecture/index",
- {
- "group": "Base Protocol",
- "pages": [
- "specification/2025-03-26/basic/index",
- "specification/2025-03-26/basic/lifecycle",
- "specification/2025-03-26/basic/transports",
- "specification/2025-03-26/basic/authorization",
- {
- "group": "Utilities",
- "pages": [
- "specification/2025-03-26/basic/utilities/cancellation",
- "specification/2025-03-26/basic/utilities/ping",
- "specification/2025-03-26/basic/utilities/progress"
- ]
- }
+ },
+ {
+ "tab": "SDKs",
+ "icon": "book-open",
+ "groups": [
+ {
+ "group": "Java",
+ "pages": [
+ "sdk/java/mcp-overview",
+ "sdk/java/mcp-client",
+ "sdk/java/mcp-server"
+ ]
+ }
]
- },
- {
- "group": "Client Features",
- "pages": [
- "specification/2025-03-26/client/roots",
- "specification/2025-03-26/client/sampling"
+ },
+ {
+ "tab": "Specification",
+ "icon": "book",
+ "groups": [
+ {
+ "group": "2025-03-26 (Latest)",
+ "pages": [
+ "specification/2025-03-26/index",
+ "specification/2025-03-26/changelog",
+ "specification/2025-03-26/architecture/index",
+ {
+ "group": "Base Protocol",
+ "pages": [
+ "specification/2025-03-26/basic/index",
+ "specification/2025-03-26/basic/lifecycle",
+ "specification/2025-03-26/basic/transports",
+ "specification/2025-03-26/basic/authorization",
+ {
+ "group": "Utilities",
+ "pages": [
+ "specification/2025-03-26/basic/utilities/cancellation",
+ "specification/2025-03-26/basic/utilities/ping",
+ "specification/2025-03-26/basic/utilities/progress"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Client Features",
+ "pages": [
+ "specification/2025-03-26/client/roots",
+ "specification/2025-03-26/client/sampling"
+ ]
+ },
+ {
+ "group": "Server Features",
+ "pages": [
+ "specification/2025-03-26/server/index",
+ "specification/2025-03-26/server/prompts",
+ "specification/2025-03-26/server/resources",
+ "specification/2025-03-26/server/tools",
+ {
+ "group": "Utilities",
+ "pages": [
+ "specification/2025-03-26/server/utilities/completion",
+ "specification/2025-03-26/server/utilities/logging",
+ "specification/2025-03-26/server/utilities/pagination"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "group": "2024-11-05",
+ "pages": [
+ "specification/2024-11-05/index",
+ "specification/2024-11-05/architecture/index",
+ {
+ "group": "Base Protocol",
+ "pages": [
+ "specification/2024-11-05/basic/index",
+ "specification/2024-11-05/basic/lifecycle",
+ "specification/2024-11-05/basic/messages",
+ "specification/2024-11-05/basic/transports",
+ {
+ "group": "Utilities",
+ "pages": [
+ "specification/2024-11-05/basic/utilities/cancellation",
+ "specification/2024-11-05/basic/utilities/ping",
+ "specification/2024-11-05/basic/utilities/progress"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Client Features",
+ "pages": [
+ "specification/2024-11-05/client/roots",
+ "specification/2024-11-05/client/sampling"
+ ]
+ },
+ {
+ "group": "Server Features",
+ "pages": [
+ "specification/2024-11-05/server/index",
+ "specification/2024-11-05/server/prompts",
+ "specification/2024-11-05/server/resources",
+ "specification/2024-11-05/server/tools",
+ {
+ "group": "Utilities",
+ "pages": [
+ "specification/2024-11-05/server/utilities/completion",
+ "specification/2024-11-05/server/utilities/logging",
+ "specification/2024-11-05/server/utilities/pagination"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "group": "draft",
+ "pages": [
+ "specification/draft/index",
+ "specification/draft/changelog",
+ "specification/draft/architecture/index",
+ {
+ "group": "Base Protocol",
+ "pages": [
+ "specification/draft/basic/index",
+ "specification/draft/basic/lifecycle",
+ "specification/draft/basic/transports",
+ "specification/draft/basic/authorization",
+ "specification/draft/basic/security_best_practices",
+ {
+ "group": "Utilities",
+ "pages": [
+ "specification/draft/basic/utilities/cancellation",
+ "specification/draft/basic/utilities/ping",
+ "specification/draft/basic/utilities/progress"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Client Features",
+ "pages": [
+ "specification/draft/client/roots",
+ "specification/draft/client/sampling",
+ "specification/draft/client/elicitation",
+ "specification/draft/client/user_interaction"
+ ]
+ },
+ {
+ "group": "Server Features",
+ "pages": [
+ "specification/draft/server/index",
+ "specification/draft/server/prompts",
+ "specification/draft/server/resources",
+ "specification/draft/server/tools",
+ {
+ "group": "Utilities",
+ "pages": [
+ "specification/draft/server/utilities/completion",
+ "specification/draft/server/utilities/logging",
+ "specification/draft/server/utilities/pagination"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Resources",
+ "pages": [
+ "specification/versioning",
+ "specification/contributing"
+ ]
+ }
]
- },
- {
- "group": "Server Features",
- "pages": [
- "specification/2025-03-26/server/index",
- "specification/2025-03-26/server/prompts",
- "specification/2025-03-26/server/resources",
- "specification/2025-03-26/server/tools",
- {
- "group": "Utilities",
- "pages": [
- "specification/2025-03-26/server/utilities/completion",
- "specification/2025-03-26/server/utilities/logging",
- "specification/2025-03-26/server/utilities/pagination"
- ]
- }
- ]
- }
+ }
+ ],
+ "global": {
+ "anchors": [
+ {
+ "anchor": "C# SDK",
+ "href": "https://github.com/modelcontextprotocol/csharp-sdk",
+ "icon": "square-c"
+ },
+ {
+ "anchor": "Java SDK",
+ "href": "https://github.com/modelcontextprotocol/java-sdk",
+ "icon": "java"
+ },
+ {
+ "anchor": "Kotlin SDK",
+ "href": "https://github.com/modelcontextprotocol/kotlin-sdk",
+ "icon": "square-k"
+ },
+ {
+ "anchor": "Python SDK",
+ "href": "https://github.com/modelcontextprotocol/python-sdk",
+ "icon": "python"
+ },
+ {
+ "anchor": "Ruby SDK",
+ "href": "https://github.com/modelcontextprotocol/ruby-sdk",
+ "icon": "gem"
+ },
+ {
+ "anchor": "Swift SDK",
+ "href": "https://github.com/modelcontextprotocol/swift-sdk",
+ "icon": "swift"
+ },
+ {
+ "anchor": "TypeScript SDK",
+ "href": "https://github.com/modelcontextprotocol/typescript-sdk",
+ "icon": "square-js"
+ }
]
- },
- {
- "group": "2024-11-05",
- "pages": [
- "specification/2024-11-05/index",
- "specification/2024-11-05/architecture/index",
- {
- "group": "Base Protocol",
- "pages": [
- "specification/2024-11-05/basic/index",
- "specification/2024-11-05/basic/lifecycle",
- "specification/2024-11-05/basic/messages",
- "specification/2024-11-05/basic/transports",
- {
- "group": "Utilities",
- "pages": [
- "specification/2024-11-05/basic/utilities/cancellation",
- "specification/2024-11-05/basic/utilities/ping",
- "specification/2024-11-05/basic/utilities/progress"
- ]
- }
- ]
- },
- {
- "group": "Client Features",
- "pages": [
- "specification/2024-11-05/client/roots",
- "specification/2024-11-05/client/sampling"
- ]
- },
- {
- "group": "Server Features",
- "pages": [
- "specification/2024-11-05/server/index",
- "specification/2024-11-05/server/prompts",
- "specification/2024-11-05/server/resources",
- "specification/2024-11-05/server/tools",
- {
- "group": "Utilities",
- "pages": [
- "specification/2024-11-05/server/utilities/completion",
- "specification/2024-11-05/server/utilities/logging",
- "specification/2024-11-05/server/utilities/pagination"
- ]
- }
- ]
- }
- ]
- },
- {
- "group": "draft",
- "pages": [
- "specification/draft/index",
- "specification/draft/changelog",
- "specification/draft/architecture/index",
- {
- "group": "Base Protocol",
- "pages": [
- "specification/draft/basic/index",
- "specification/draft/basic/lifecycle",
- "specification/draft/basic/transports",
- "specification/draft/basic/authorization",
- "specification/draft/basic/security_best_practices",
- {
- "group": "Utilities",
- "pages": [
- "specification/draft/basic/utilities/cancellation",
- "specification/draft/basic/utilities/ping",
- "specification/draft/basic/utilities/progress"
- ]
- }
- ]
- },
- {
- "group": "Client Features",
- "pages": [
- "specification/draft/client/roots",
- "specification/draft/client/sampling",
- "specification/draft/client/elicitation"
- ]
- },
- {
- "group": "Server Features",
- "pages": [
- "specification/draft/server/index",
- "specification/draft/server/prompts",
- "specification/draft/server/resources",
- "specification/draft/server/tools",
- {
- "group": "Utilities",
- "pages": [
- "specification/draft/server/utilities/completion",
- "specification/draft/server/utilities/logging",
- "specification/draft/server/utilities/pagination"
- ]
- }
- ]
- }
- ]
- },
- {
- "group": "Resources",
- "pages": ["specification/versioning", "specification/contributing"]
- }
- ]
- }
- ],
- "global": {
- "anchors": [
- {
- "anchor": "C# SDK",
- "href": "https://github.com/modelcontextprotocol/csharp-sdk",
- "icon": "square-c"
- },
- {
- "anchor": "Java SDK",
- "href": "https://github.com/modelcontextprotocol/java-sdk",
- "icon": "java"
- },
- {
- "anchor": "Kotlin SDK",
- "href": "https://github.com/modelcontextprotocol/kotlin-sdk",
- "icon": "square-k"
- },
- {
- "anchor": "Python SDK",
- "href": "https://github.com/modelcontextprotocol/python-sdk",
- "icon": "python"
- },
- {
- "anchor": "Ruby SDK",
- "href": "https://github.com/modelcontextprotocol/ruby-sdk",
- "icon": "gem"
+ }
+ },
+ "logo": { "light": "/logo/light.svg", "dark": "/logo/dark.svg" },
+ "navbar": {
+ "links": [],
+ "primary": {
+ "type": "button",
+ "label": "GitHub",
+ "href": "https://github.com/modelcontextprotocol"
+ }
+ },
+ "seo": {
+ "metatags": {
+ "og:image": "https://raw.githubusercontent.com/modelcontextprotocol/docs/2eb6171ddbfeefde349dc3b8d5e2b87414c26250/images/og-image.png"
},
+ "indexing": "navigable"
+ },
+ "footer": {
+ "socials": { "github": "https://github.com/modelcontextprotocol" }
+ },
+ "redirects": [
{
- "anchor": "Swift SDK",
- "href": "https://github.com/modelcontextprotocol/swift-sdk",
- "icon": "swift"
+ "source": "/tutorials/building-a-client",
+ "destination": "/quickstart/client"
},
+ { "source": "/quickstart", "destination": "/quickstart/server" },
{
- "anchor": "TypeScript SDK",
- "href": "https://github.com/modelcontextprotocol/typescript-sdk",
- "icon": "square-js"
+ "source": "/specification/latest",
+ "destination": "/specification/2025-03-26",
+ "permanent": false
}
- ]
- }
- },
- "logo": {
- "light": "/logo/light.svg",
- "dark": "/logo/dark.svg"
- },
- "navbar": {
- "links": [],
- "primary": {
- "type": "button",
- "label": "GitHub",
- "href": "https://github.com/modelcontextprotocol"
- }
- },
- "seo": {
- "metatags": {
- "og:image": "https://raw.githubusercontent.com/modelcontextprotocol/docs/2eb6171ddbfeefde349dc3b8d5e2b87414c26250/images/og-image.png"
- },
- "indexing": "navigable"
- },
- "footer": {
- "socials": {
- "github": "https://github.com/modelcontextprotocol"
- }
- },
- "redirects": [
- {
- "source": "/tutorials/building-a-client",
- "destination": "/quickstart/client"
- },
- {
- "source": "/quickstart",
- "destination": "/quickstart/server"
- },
- {
- "source": "/specification/latest",
- "destination": "/specification/2025-03-26",
- "permanent": false
- }
- ],
- "contextual": {
- "options": ["copy", "view"]
- }
+ ],
+ "contextual": { "options": ["copy", "view"] }
}
diff --git a/docs/specification/draft/basic/lifecycle.mdx b/docs/specification/draft/basic/lifecycle.mdx
index 58aa184fa..4f0c6315b 100644
--- a/docs/specification/draft/basic/lifecycle.mdx
+++ b/docs/specification/draft/basic/lifecycle.mdx
@@ -62,7 +62,10 @@ The client **MUST** initiate this phase by sending an `initialize` request conta
"listChanged": true
},
"sampling": {},
- "elicitation": {}
+ "elicitation": {},
+ "userInteraction": {
+ "types": ["ua"]
+ }
},
"clientInfo": {
"name": "ExampleClient",
@@ -150,6 +153,7 @@ Key capabilities include:
| Client | `roots` | Ability to provide filesystem [roots](/specification/draft/client/roots) |
| Client | `sampling` | Support for LLM [sampling](/specification/draft/client/sampling) requests |
| Client | `elicitation` | Support for server [elicitation](/specification/draft/client/elicitation) requests |
+| Client | `userInteraction` | Support for [user interactions](/specification/draft/client/user_interaction) |
| Client | `experimental` | Describes support for non-standard experimental features |
| Server | `prompts` | Offers [prompt templates](/specification/draft/server/prompts) |
| Server | `resources` | Provides readable [resources](/specification/draft/server/resources) |
diff --git a/docs/specification/draft/changelog.mdx b/docs/specification/draft/changelog.mdx
index d09e798b8..512fddcf6 100644
--- a/docs/specification/draft/changelog.mdx
+++ b/docs/specification/draft/changelog.mdx
@@ -15,6 +15,8 @@ the previous revision, [2025-03-26](/specification/2025-03-26).
4. Clarified [security considerations](https://modelcontextprotocol.io/specification/draft/basic/authorization#3-security-considerations) and best practices in the authorization spec and in a new [security best practices page](https://modelcontextprotocol.io/specification/draft/basic/security_best_practices).
5. Added support for **[elicitation](/specification/draft/client/elicitation)**, enabling
servers to request additional information from users during interactions. (PR [#382](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/382))
+6. Added support for **[user interaction](/specification/draft/client/user_interaction)** (PR
+ [#475](https://github.com/modelcontextprotocol/specification/pull/475))
## Other schema changes
diff --git a/docs/specification/draft/client/user_interaction.mdx b/docs/specification/draft/client/user_interaction.mdx
new file mode 100644
index 000000000..79c69b106
--- /dev/null
+++ b/docs/specification/draft/client/user_interaction.mdx
@@ -0,0 +1,410 @@
+---
+title: User Interaction
+---
+
+**Protocol Revision**: draft
+
+The Model Context Protocol (MCP) provides a standardized way for servers to interact
+directly with end-users without data passing through the client or the LLM. This allows
+servers to maintain control over user interactions and data sharing while dynamically
+gathering necessary information.
+
+The interaction itself is fully under the control of the MCP server and the MCP client is
+only responsible for providing an affordance to start it (typically by presenting a URL to
+the end-user, and opening it in a user agent such as a web browser). Within this model,
+the client's responsibilities remain minimal and the server has the flexibility to
+implement a wide range of interactions involving the end-user. For example:
+
+- A productivity MCP server might request a user to authorize a third-party service to
+ access their documents.
+- A news MCP server might request a user to upgrade their subscription to access more features.
+- A banking MCP server might request a user to verify their account to access a new feature.
+
+## Terminology
+
+- **End-user**: The human who is interacting with with the MCP server through their MCP client.
+- **User agent**: a client, such as a web browser, that is capable of
+ interacting with the end-user. Broadly, it is used as defined in
+ [RFC 9110 Section 3.5](https://datatracker.ietf.org/doc/html/rfc9110#section-3.5).
+
+## Capabilities
+
+MCP clients that support user interaction **MUST** declare the `userInteraction` capability during
+[initialization](/specification/draft/basic/lifecycle#initialization):
+
+```json
+{
+ "capabilities": {
+ "userInteraction": {
+ "types": ["ua"]
+ }
+ }
+}
+```
+
+Clients supporting the `userInteraction` capability **MUST** support at least one
+interaction type, and **MUST** list all the interaction types they support in the `types`
+array. The acceptable values are defined in the [Interaction Types](#interaction-types)
+section below.
+
+The MCP server **MUST NOT** send an interaction request to the client of a type that is not
+explicitly declared by the client.
+
+
+
+For trust and safety, there **SHOULD** always
+be a human in the loop with the ability to deny interaction requests.
+
+MCP clients **MUST**:
+
+- Provide a way for the end-user to consent to the interaction.
+- Clearly communicate which server is requesting an interaction.
+
+MCP clients **SHOULD**:
+
+- Allow the end-user to cancel the interaction.
+
+
+
+Using the `userInteraction` capability means that the MCP server **MUST** be stateful, if
+it is not already. At a minimum, the MCP server **MUST** keep track of the interactions it
+has created for each MCP client.
+
+
+
+## Protocol Messages
+
+### Server-Initiated Interaction Requests
+
+When the MCP client indicates support for user interactions, the MCP server **MAY** request a user
+interaction from the client at any time. To request a user interaction, the server sends an
+`interaction/create` message to the client.
+
+The request includes the following fields as part of the `params` object:
+
+- `id`: The ID of the interaction that **MUST** be unique across the server's concurrent
+ interactions.
+- `type`: The type of interaction, which **MUST** be one of the types negotiated during
+ [initialization](/specification/draft/basic/lifecycle#initialization).
+- `interaction`: The interaction object, the schema of which depends on the type of
+ interaction. Each schema is defined in the [Interaction Types](#interaction-types)
+ section below.
+
+The following is an example of a `interaction/create` message for a `ua` interaction:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 123,
+ "method": "interaction/create",
+ "params": {
+ "id": "c8ec9a71-c475-4a88-a774-e9cd154bc7f8",
+ "type": "ua",
+ "interaction": {
+ "url": "https://oauth.example.com/authorize?client_id=abc123&...",
+ "message": {
+ "type": "text",
+ "text": "Authorization is required to access your Example Co files."
+ }
+ }
+ }
+}
+```
+
+The following flow diagram illustrates the `ua` interaction type across the server, the client, and the end-user:
+
+```mermaid
+sequenceDiagram
+ participant U as End-User
+ participant B as User Agent (Browser)
+ participant C as MCP Client
+ participant S as MCP Server
+
+ Note over S,C: Server initiates prompt interaction
+ S->>C: interaction/create type=ua
+
+ C->>U: Present consent to open URL
+ U-->>C: Provide consent
+
+ C->>B: Open URL
+ C->>S: Send response
+ Note over U,B: Human interaction
+ B-->>S: Perform interaction
+
+ Note over S: Continue operations
+```
+
+
+
+### Requiring Interaction as an Error Response
+
+The MCP server **MAY** require a user interaction as an error response to a client
+request. This is useful when interaction is required as a pre-condition for a request. For
+example, a [tool call](/specification/draft/server/tools#calling-tools) or [resource read](/specification/draft/server/resources#reading-resources)
+request that requires the end-user to authorize a third-party service before the request
+can be completed.
+
+The MCP server **MUST** send an
+[error response](/specification/draft/basic/lifecycle#error-handling) with the `code` equal to
+`-32003` and the `message` equal to `interaction_required`.
+
+The error response **MUST** include an `data` object consistent with one of the defined
+[interaction types](#interaction-types).
+
+The following is an example of an error response containing a `ua` interaction:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 123,
+ "error": {
+ "code": -32003,
+ "message": "interaction_required",
+ "data": {
+ "id": "c8ec9a71-c475-4a88-a774-e9cd154bc7f8",
+ "type": "ua",
+ "url": "https://oauth.example.com/authorize?client_id=abc123&...",
+ "message": {
+ "type": "text",
+ "text": "Authorization is required to access your Example Co files."
+ }
+ }
+ }
+}
+```
+
+The following flow diagram illustrates a client request (tool call) that requires interaction with a third-party service:
+
+```mermaid
+sequenceDiagram
+ participant U as End-User
+ participant B as User Agent (Browser)
+ participant C as MCP Client
+ participant S as MCP Server
+ participant T as Third-Party Service
+
+ C->>S: tools/call name=send_email
+
+ Note over S: Server determines interaction is required
+ S->>C: error code=-32003
+
+ C->>U: Present consent to open URL
+ U-->>C: Provide consent
+
+ C->>B: Open URL
+ B->>T: Navigate to URL
+ Note over T: Human interaction
+ T-->>S: Redirect to MCP server
+
+ Note over S: Completed interaction
+
+ Note over C: At a later time, retry request
+ C->>S: tools/call name=send_email
+ Note over S: Continue operations
+```
+
+## Interaction Types
+
+When a user interaction is requested by the server and supported by the client, the MCP client **MUST** present
+the user with an interaction flow. The type of flow is defined by the MCP server, and the client's behavior
+is specific to the interaction type.
+
+This specification defines one type of user interaction:
+
+- **`ua`**: A user agent interaction that involves making a request via a
+ client application that acts on behalf of the user, such as a web browser.
+
+The client and server **MAY** negotiate additional interaction types.
+
+
+### User Agent Interactions
+
+A user agent interaction is a user interaction that involves the MCP client facilitating
+navigation to a URL in a client application such as a web browser. This allows the MCP server to
+obtain data without involving the MCP client. The MCP server can, as a result, control the
+entire interaction from start to finish, including the user experience, and guarantee the
+security of sensitive data, such as API keys or access tokens.
+
+This flow requires the client to support the `ua` user interaction type:
+```json
+{
+ "capabilities": {
+ "userInteraction": {
+ "types": ["ua"]
+ }
+ }
+}
+```
+
+The MCP client **MUST** facilitate the opening of the URL in a user agent, such as the default web browser.
+
+#### Server Request
+
+For `ua` interactions, the `interaction` object has the following properties:
+
+- `url`: The URL that the user should interact with.
+- `message`: An optional `TextContent` object used to provide an explanation to the user about the interaction.
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 123,
+ "method": "interaction/create",
+ "params": {
+ "id": "c8ec9a71-c475-4a88-a774-e9cd154bc7f8",
+ "type": "ua",
+ "interaction": {
+ "url": "https://example.com/mcp?state=1234567890&...",
+ "message": {
+ "type": "text",
+ "text": "Please sign in to your account."
+ }
+ }
+ }
+}
+```
+
+#### Client Response
+
+When the client facilitates the opening of the URL, it **MUST** send a response to the server:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 123,
+ "result": {}
+}
+```
+
+Alternatively, if the end-user cancels or declines the interaction, the client **MUST**
+send an error response to the server:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 123,
+ "error": {
+ "code": -32099,
+ "message": "User did not consent to the interaction."
+ }
+}
+```
+
+## Tracking Progress
+The [Progress capability](/specification/draft/basic/utilities/progress) provides a way
+for MCP clients to track progress for user interactions. By tracking the progress of an
+interaction, the MCP client can provide a better user experience. For example, the MCP
+client could:
+
+- Update the UI when the interaction is complete.
+- Automatically retry a tool call that required interaction.
+
+Tracking progress for user interactions is optional. MCP clients **MAY** send an
+`interaction/track` message to the MCP server along with a [progress token](/specification/draft/basic/utilities/progress#progress-flow)
+to track the progress of an interaction. The MCP client **MUST** include the interaction
+ID in the `id` field for which it wants to track. This `id` **MUST** refer to an
+interaction the server sent to the client.
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 123,
+ "method": "interaction/track",
+ "params": {
+ "_meta": {
+ "progressToken": "progress-token-123"
+ },
+ "id": "c8ec9a71-c475-4a88-a774-e9cd154bc7f8"
+ }
+}
+```
+
+MCP servers **MUST NOT** send progress notifications related to the interaction if:
+
+- The `id` is not an interaction the server created.
+- The `id` is not an interaction associated with the client.
+- The `id` is not an interaction associated with the current MCP session, if session management is in use.
+
+MCP servers that receive a valid `interaction/track` request **SHOULD** send at least 1
+`notifications/progress` message, even if the interaction is already complete.
+
+The following is an example of a progress notification sent by the MCP server:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "notifications/progress",
+ "params": {
+ "progressToken": "progress-token-123",
+ "progress": 100,
+ "total": 100,
+ "message": "Consent granted."
+ }
+}
+```
+
+## Cancelling an Interaction
+
+The MCP server **MAY** cancel an interaction at any time by sending a
+`notifications/cancelled` message to the client, as described in [Cancellation](/specification/draft/basic/utilities/cancellation).
+The MCP client **SHOULD NOT** send a response.
+
+
+## Security Considerations
+
+### Handling Sensitive Information
+
+MCP servers **MUST** use the `ua` interaction type for sensitive information, such as
+auth credentials or authorization grants. The MCP client **MUST NOT** send sensitive
+information to the MCP server in any other way.
+
+### User Consent
+
+The MCP client **SHOULD** clearly communicate the purpose of the interaction to the end-user,
+and provide a way for the end-user to consent to the interaction before continuing.
+
+### Identifying the User
+
+The MCP server **MUST NOT** rely on input from the client or end-user to identify the
+end-user, as this untrusted input can be forged and lead to impersonation attacks.
+
+Instead, the MCP server **SHOULD** follow [security best practices](/specification/draft/basic/security_best_practices).
+
+### Server-side Request Forgery
+
+With the `ua` interaction type, the MCP client is expected to make a request via a user agent
+based on the value of the `url` parameter in the interaction object. Since MCP enables clients
+to interoperate with MCP servers it has no prior knowledge of, this opens a risk for Server-Side
+Request Forgery (SSRF) attacks by malicious MCP servers. MCP clients **SHOULD** take appropriate
+precautions against SSRF attacks, such as blocking requests to internal IP address ranges and
+requiring TLS.
+
+Additionally, the MCP client **SHOULD** validate the `url` parameter in the interaction object and
+provide sufficient context to the user about the request that will be made, before it is opened in
+a User Agent.
+
+Further recommendations can be found in the Open Worldwide Application Security
+Project (OWASP) [SSRF Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html).
+
+### Phishing
+
+The `ua` interaction type may be used in a way where the `url` parameter in the
+interaction object points to a URL on a domain that is not the MCP server's domain. For
+example, the URL may be an authorization URL of a third-party service that the MCP server
+needs the user to authorize access to. If that third-party service is malicious or
+compromised, it could trick the user into revealing their account credentials or other
+sensitive information.
+
+To mitigate this risk, MCP clients **SHOULD** take appropriate precautions, such as verifying the
+authenticity of the URL and clearly presenting the destination of the request to the user.
+
+### Impersonation attacks
+
+Since MCP enables clients to interoperate with MCP servers it has no prior knowledge of,
+this opens a risk for impersonation attacks by malicious MCP clients. MCP servers
+**SHOULD** take appropriate precautions against impersonation attacks, such as:
+
+- Implementing [Authorization](/specification/draft/basic/authorization)
+- Identifying the end-user in trusted (server) code
+- Ensuring that user interaction requests are bound to the MCP session to prevent Insecure
+ Direct Object Reference (IDOR) attacks
diff --git a/docs/specification/draft/index.mdx b/docs/specification/draft/index.mdx
index ebba5d4f5..ec254bcc6 100644
--- a/docs/specification/draft/index.mdx
+++ b/docs/specification/draft/index.mdx
@@ -63,6 +63,7 @@ Clients may offer the following features to servers:
- **Sampling**: Server-initiated agentic behaviors and recursive LLM interactions
- **Elicitation**: Server-initiated requests for additional information from users
+- **User Interaction**: Server-initiated out-of-band interactions with end-users
### Additional Utilities
diff --git a/package.json b/package.json
index a3dfd568c..fab3aee69 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,12 @@
"printWidth": 89,
"proseWrap": "always"
}
+ },
+ {
+ "files": "*.json",
+ "options": {
+ "tabWidth": 4
+ }
}
]
},
diff --git a/schema/draft/schema.json b/schema/draft/schema.json
index 05552b38d..93fd5902c 100644
--- a/schema/draft/schema.json
+++ b/schema/draft/schema.json
@@ -227,6 +227,22 @@
"description": "Present if the client supports sampling from an LLM.",
"properties": {},
"type": "object"
+ },
+ "userInteraction": {
+ "description": "Present if the client supports user interaction.",
+ "properties": {
+ "types": {
+ "description": "An array of supported user interaction types. Clients must support at least one type.\n\nThis specification defines one interaction type:\n- \"ua\": A user agent interaction involving making a request via a User Agent (e.g. a Web browser)\n\nAdditional interaction types may be negotiated between client and server.",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "required": [
+ "types"
+ ],
+ "type": "object"
}
},
"type": "object"
@@ -287,6 +303,9 @@
},
{
"$ref": "#/definitions/CompleteRequest"
+ },
+ {
+ "$ref": "#/definitions/TrackUserInteractionRequest"
}
]
},
@@ -303,6 +322,9 @@
},
{
"$ref": "#/definitions/ElicitResult"
+ },
+ {
+ "$ref": "#/definitions/CreateUserInteractionResult"
}
]
},
@@ -499,6 +521,62 @@
],
"type": "object"
},
+ "CreateUserInteractionRequest": {
+ "description": "A request from the server to the client to create a user interaction.",
+ "properties": {
+ "method": {
+ "const": "interaction/create",
+ "type": "string"
+ },
+ "params": {
+ "properties": {
+ "id": {
+ "description": "The ID of the interaction.",
+ "type": "string"
+ },
+ "interaction": {
+ "anyOf": [
+ {
+ "additionalProperties": true,
+ "properties": {},
+ "type": "object"
+ },
+ {
+ "$ref": "#/definitions/UAInteraction"
+ }
+ ],
+ "description": "The interaction object. The schema of the interaction object is dependent on the type of\ninteraction."
+ },
+ "type": {
+ "description": "The type of interaction.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "interaction",
+ "type"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "method",
+ "params"
+ ],
+ "type": "object"
+ },
+ "CreateUserInteractionResult": {
+ "description": "The client's response to a user interaction/create request from the server.",
+ "properties": {
+ "_meta": {
+ "additionalProperties": {},
+ "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.",
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
"Cursor": {
"description": "An opaque token used to represent a cursor for pagination.",
"type": "string"
@@ -2069,6 +2147,9 @@
},
{
"$ref": "#/definitions/ElicitRequest"
+ },
+ {
+ "$ref": "#/definitions/CreateUserInteractionRequest"
}
]
},
@@ -2103,6 +2184,9 @@
},
{
"$ref": "#/definitions/CompleteResult"
+ },
+ {
+ "$ref": "#/definitions/TrackUserInteractionResult"
}
]
},
@@ -2362,6 +2446,74 @@
],
"type": "object"
},
+ "TrackUserInteractionRequest": {
+ "description": "A request from the client to the server to track the progress of a user interaction.",
+ "properties": {
+ "_meta": {
+ "properties": {
+ "progressToken": {
+ "$ref": "#/definitions/ProgressToken",
+ "description": "The progress token which was given in the initial request, used to associate this notification with the request that is proceeding."
+ }
+ },
+ "required": [
+ "progressToken"
+ ],
+ "type": "object"
+ },
+ "method": {
+ "const": "interaction/track",
+ "type": "string"
+ },
+ "params": {
+ "properties": {
+ "id": {
+ "description": "The ID of the interaction.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "_meta",
+ "method",
+ "params"
+ ],
+ "type": "object"
+ },
+ "TrackUserInteractionResult": {
+ "description": "The server's response to a user interaction/track request from the client.",
+ "properties": {
+ "_meta": {
+ "additionalProperties": {},
+ "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.",
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "UAInteraction": {
+ "description": "Defines the interaction object for \"ua\" (user agent) type interactions.",
+ "properties": {
+ "message": {
+ "$ref": "#/definitions/TextContent",
+ "description": "An optional message to provide an explanation to the user about the interaction."
+ },
+ "url": {
+ "description": "The URL that the user should interact with.",
+ "format": "uri",
+ "type": "string"
+ }
+ },
+ "required": [
+ "url"
+ ],
+ "type": "object"
+ },
"UnsubscribeRequest": {
"description": "Sent from the client to request cancellation of resources/updated notifications from the server. This should follow a previous resources/subscribe request.",
"properties": {
diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts
index 0852bad4b..b5ea9eaab 100644
--- a/schema/draft/schema.ts
+++ b/schema/draft/schema.ts
@@ -220,10 +220,26 @@ export interface ClientCapabilities {
* Present if the client supports sampling from an LLM.
*/
sampling?: object;
+
/**
* Present if the client supports elicitation from the server.
*/
elicitation?: object;
+
+ /**
+ * Present if the client supports user interaction.
+ */
+ userInteraction?: {
+ /**
+ * An array of supported user interaction types. Clients must support at least one type.
+ *
+ * This specification defines one interaction type:
+ * - "ua": A user agent interaction involving making a request via a User Agent (e.g. a Web browser)
+ *
+ * Additional interaction types may be negotiated between client and server.
+ */
+ types: string[];
+ };
}
/**
@@ -1258,7 +1274,7 @@ export interface ElicitRequest extends Request {
* Restricted schema definitions that only allow primitive types
* without nested objects or arrays.
*/
-export type PrimitiveSchemaDefinition =
+export type PrimitiveSchemaDefinition =
| StringSchema
| NumberSchema
| BooleanSchema
@@ -1307,7 +1323,7 @@ export interface ElicitResult extends Result {
* - "cancel": User dismissed without making an explicit choice
*/
action: "accept" | "decline" | "cancel";
-
+
/**
* The submitted form data, only present when action is "accept".
* Contains values matching the requested schema.
@@ -1315,6 +1331,76 @@ export interface ElicitResult extends Result {
content?: { [key: string]: unknown };
}
+/* User Interaction */
+/**
+ * A request from the server to the client to create a user interaction.
+ */
+export interface CreateUserInteractionRequest extends Request {
+ method: "interaction/create";
+ params: {
+ /**
+ * The ID of the interaction.
+ */
+ id: string;
+ /**
+ * The type of interaction.
+ */
+ type: string;
+ /**
+ * The interaction object. The schema of the interaction object is dependent on the type of
+ * interaction.
+ */
+ interaction: UAInteraction | object;
+ };
+}
+
+/**
+ * Defines the interaction object for "ua" (user agent) type interactions.
+ */
+export interface UAInteraction {
+ /**
+ * The URL that the user should interact with.
+ *
+ * @format uri
+ */
+ url: string;
+
+ /**
+ * An optional message to provide an explanation to the user about the interaction.
+ */
+ message?: TextContent;
+}
+
+/**
+ * The client's response to a user interaction/create request from the server.
+ */
+export interface CreateUserInteractionResult extends Result { }
+
+/**
+ * A request from the client to the server to track the progress of a user interaction.
+ */
+export interface TrackUserInteractionRequest extends Request {
+ method: "interaction/track";
+ params: {
+ /**
+ * The ID of the interaction.
+ */
+ id: string;
+ };
+ _meta: {
+ /**
+ * The progress token which was given in the initial request, used to associate this notification with the request that is proceeding.
+ */
+ progressToken: ProgressToken;
+ };
+}
+
+
+/**
+ * The server's response to a user interaction/track request from the client.
+ */
+export interface TrackUserInteractionResult extends Result { }
+
/* Client messages */
export type ClientRequest =
| PingRequest
@@ -1329,7 +1415,8 @@ export type ClientRequest =
| SubscribeRequest
| UnsubscribeRequest
| CallToolRequest
- | ListToolsRequest;
+ | ListToolsRequest
+ | TrackUserInteractionRequest;
export type ClientNotification =
| CancelledNotification
@@ -1337,14 +1424,15 @@ export type ClientNotification =
| InitializedNotification
| RootsListChangedNotification;
-export type ClientResult = EmptyResult | CreateMessageResult | ListRootsResult | ElicitResult;
+export type ClientResult = EmptyResult | CreateMessageResult | ListRootsResult | ElicitResult | CreateUserInteractionResult;
/* Server messages */
export type ServerRequest =
| PingRequest
| CreateMessageRequest
| ListRootsRequest
- | ElicitRequest;
+ | ElicitRequest
+ | CreateUserInteractionRequest;
export type ServerNotification =
| CancelledNotification
@@ -1365,4 +1453,5 @@ export type ServerResult =
| ListResourcesResult
| ReadResourceResult
| CallToolResult
- | ListToolsResult;
+ | ListToolsResult
+ | TrackUserInteractionResult;