Roots — communicating scope
A Root is a directory or URI prefix the client puts in-scope for the current session. Servers ask roots/list and only expose resources that fall inside.
{
"roots": [
{ "uri": "file:///Users/alice/projects/myapp", "name": "myapp" },
{ "uri": "file:///Users/alice/projects/docs", "name": "docs" }
]
}
Reminder: roots are advisory. Filesystem boundaries belong in the host process — never trust a remote server to honour them.
Elicitation — two modes
Form mode
Server provides a JSON Schema. The client renders a form (primitive fields only). User fills it in and the client returns the data.
Use for: confirmations, missing parameters, structured input.
URL mode
Server provides a URL. The client opens it in a browser tab. When the user finishes, the client sends a completion notification.
Use for: OAuth, sensitive data, payment flows.
Form elicitation example
{
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "Confirm your Barcelona booking.",
"requestedSchema": {
"type": "object",
"properties": {
"confirm": { "type": "boolean", "title": "I accept the $3,000 total" },
"seat": { "type": "string", "enum": ["aisle", "window", "no preference"] }
},
"required": ["confirm"]
}
}
}
The three-action model
accept
User submitted. content matches your schema.
decline
Explicit refusal. Offer alternatives.
cancel
Dismissed without an answer. Maybe prompt again later.
Never ask for secrets in form mode — clients log forms. Use url mode for anything sensitive.
Quick summary
- Roots scope server access — but they're advisory, not security
- Elicitation has two modes: form (JSON-Schema-driven UI) and url (out-of-band)
- Three response actions: accept, decline, cancel — handle each
- Sensitive data goes in url mode, never form mode