> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Elicitation

> Request user input during server operations per MCP 2025-11-25

# MCP Elicitation

Elicitation allows MCP servers to request additional information from users during tool execution. This enables interactive workflows where servers can collect structured data or direct users to external URLs.

## Protocol Version

This feature implements **MCP Protocol Version 2025-11-25**.

## Elicitation Modes

| Mode   | Description                              | Use Case                                   |
| ------ | ---------------------------------------- | ------------------------------------------ |
| `form` | Structured data with JSON schema         | Collecting user preferences, confirmations |
| `url`  | External URL for out-of-band interaction | OAuth flows, payments, sensitive data      |

## Action Values

| Action    | Description                     |
| --------- | ------------------------------- |
| `accept`  | User accepted and provided data |
| `decline` | User explicitly declined        |
| `cancel`  | User cancelled the request      |

## Python API

### Form Mode Elicitation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import asyncio
from praisonai.mcp_server.elicitation import (
    ElicitationHandler,
    ElicitationResult,
    create_form_request,
)

async def main():
    # Create handler (use ci_mode=True for non-interactive)
    handler = ElicitationHandler(
        ci_mode=True,
        ci_defaults={"name": "John", "email": "john@example.com"}
    )
    
    # Create form request
    request = create_form_request(
        message="Please provide your contact information",
        properties={
            "name": {"type": "string", "description": "Your name"},
            "email": {"type": "string", "format": "email"},
            "age": {"type": "integer", "default": 25},
        },
        required=["name", "email"],
        title="Contact Form",
    )
    
    # Process elicitation
    result = await handler.elicit(request)
    
    if result.action.value == "accept":
        print(f"Data: {result.content}")
    elif result.action.value == "decline":
        print(f"Declined: {result.validation_error}")
    else:
        print("Cancelled")

asyncio.run(main())
```

### URL Mode Elicitation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.mcp_server.elicitation import create_url_request

# Create URL elicitation for OAuth
request = create_url_request(
    message="Please authorize access to your GitHub account",
    url="https://github.com/login/oauth/authorize?client_id=xxx",
    elicitation_id="oauth-github-123",
)

print(request.to_dict())
# {
#     "message": "Please authorize access to your GitHub account",
#     "mode": "url",
#     "url": "https://github.com/login/oauth/authorize?client_id=xxx",
#     "elicitationId": "oauth-github-123"
# }
```

### Using Factory Methods

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.mcp_server.elicitation import ElicitationResult

# Accept with data
result = ElicitationResult.accept({"confirmed": True, "value": 42})
print(result.to_dict())
# {"action": "accept", "content": {"confirmed": True, "value": 42}}

# Decline with error
result = ElicitationResult.decline("Invalid input provided")
print(result.to_dict())
# {"action": "decline", "validationError": "Invalid input provided"}

# Cancel
result = ElicitationResult.cancel()
print(result.to_dict())
# {"action": "cancel"}
```

### Custom Handler

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
async def custom_handler(request):
    """Custom handler for elicitation requests."""
    # Implement your own logic
    if request.mode.value == "form":
        return ElicitationResult.accept({"auto_approved": True})
    return ElicitationResult.decline("URL mode not supported")

handler = ElicitationHandler()
handler.set_custom_handler(custom_handler)
```

## MCP Protocol Messages

### Form Mode Request

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "elicitation/create",
  "params": {
    "message": "Please provide your preferences",
    "requestedSchema": {
      "type": "object",
      "properties": {
        "checkAlternative": {
          "type": "boolean",
          "description": "Check another date?"
        },
        "alternativeDate": {
          "type": "string",
          "default": "2024-12-26"
        }
      },
      "required": ["checkAlternative"]
    }
  }
}
```

### URL Mode Request

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "elicitation/create",
  "params": {
    "message": "Please confirm payment",
    "mode": "url",
    "url": "https://payments.example.com/confirm?id=123",
    "elicitationId": "payment-123"
  }
}
```

### Response

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "action": "accept",
    "content": {
      "checkAlternative": true,
      "alternativeDate": "2024-12-26"
    }
  }
}
```

## Security Considerations

### Form Mode

* Use for **non-sensitive** structured data
* Schema validation ensures data integrity
* Default values are supported

### URL Mode

* Use for **sensitive** operations (OAuth, payments)
* Data never passes through the MCP server
* Requires `elicitationId` for tracking

## CI/Non-Interactive Mode

For automated environments:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
handler = ElicitationHandler(
    ci_mode=True,
    ci_defaults={
        "name": "CI User",
        "confirm": True,
    }
)
```

In CI mode:

* Form mode uses provided defaults
* URL mode returns `decline` (cannot be automated)

## Related

* [MCP Tasks API](/docs/mcp/mcp-tasks-api) - Long-running operations
* [MCP Sampling](/docs/mcp/mcp-sampling) - LLM completions
* [MCP Auth](/docs/mcp/mcp-auth) - OAuth 2.1 authentication
