diff --git a/README.md b/README.md index 3412d91..bc250a3 100644 --- a/README.md +++ b/README.md @@ -96,47 +96,47 @@ most clients don't use versions anyway. This might change in the future. ### Clients supported -| Display name | [Resources](#resources) | [Prompts](#prompts) | [Tools](#tools) | [Discovery](#discovery) | [Sampling](#sampling) | [Tasks](#tasks) | [Roots](#roots) | [Elicitation](#elicitation) | +| Display name | [Resources](#resources) | [Prompts](#prompts) | [Tools](#tools) | [Discovery](#discovery) | [Sampling](#sampling) | [Tasks](#tasks) | [Roots](#roots) | [Elicitation](#elicitation) (form, url) | | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| [Alpic Playground](https://alpic.ai/blog/launch-week-2-introducing-the-alpic-playground) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | -| [Amazon Q Developer CLI](https://github.com/aws/amazon-q-developer-cli) | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [AmpCode](https://ampcode.com) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | -| [Apify MCP Client](https://apify.com/jiri.spilka/tester-mcp-client) | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | -| [Arcade](https://arcade.dev) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | -| [ChatGPT](https://chatgpt.com) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Cherry Studio](https://www.cherry-ai.com) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Claude Code](https://claude.com/product/claude-code) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | -| [Claude.ai](https://claude.ai) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Cline](https://cline.bot/) | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | -| [Continue CLI Client](https://www.continue.dev/) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Crush](https://github.com/charmbracelet/crush) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | -| [Cursor](https://cursor.com) | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | -| [Dust](https://dust.tt) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Factory CLI](https://github.com/factory-ai/factory-cli) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Gemini CLI](https://geminicli.com/) | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [GitGuardian](https://www.gitguardian.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | -| [GitHub Copilot CLI](https://github.com/features/copilot/cli) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [GitHub Copilot for Xcode](https://github.com/github/CopilotForXcode) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | -| [Glama](https://glama.ai/chat) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | -| [Google Antigravity](https://antigravity.google) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | -| [Goose](https://block.github.io/goose) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Jan AI](https://jan.ai) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [JetBrains AI Assistant](https://plugins.jetbrains.com/plugin/22282-jetbrains-ai-assistant) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | -| [JetBrains AI Assistant with GitHub Copilot](https://plugins.jetbrains.com/plugin/22282-jetbrains-ai-assistant) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | -| [Kilo Code](https://github.com/Kilo-Org/kilocode) | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | -| [LibreChat](https://www.librechat.ai) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [LobeHub](https://lobehub.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Make MCP Client](https://www.make.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Mistral AI: Le Chat](https://chat.mistral.ai) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | -| [N8N MCP Client](https://n8n.io) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [OpenAI Codex](https://openai.com/codex) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | -| [Opencode](https://opencode.ai) | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | -| [Postman](https://postman.com/downloads) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | -| [Raycast](https://www.raycast.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | -| [Roo Code](https://roocode.com) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Visual Studio Code](https://code.visualstudio.com) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Windsurf Editor](https://codeium.com/windsurf) | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | -| [Zed Editor](https://zed.dev) | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | +| [Alpic Playground](https://alpic.ai/blog/launch-week-2-introducing-the-alpic-playground) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅, ❌ | +| [Amazon Q Developer CLI](https://github.com/aws/amazon-q-developer-cli) | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [AmpCode](https://ampcode.com) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌, ❌ | +| [Apify MCP Client](https://apify.com/jiri.spilka/tester-mcp-client) | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Arcade](https://arcade.dev) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅, ❌ | +| [ChatGPT](https://chatgpt.com) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Cherry Studio](https://www.cherry-ai.com) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Claude Code](https://claude.com/product/claude-code) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌, ❌ | +| [Claude.ai](https://claude.ai) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Cline](https://cline.bot/) | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Continue CLI Client](https://www.continue.dev/) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Crush](https://github.com/charmbracelet/crush) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌, ❌ | +| [Cursor](https://cursor.com) | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅, ❌ | +| [Dust](https://dust.tt) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Factory CLI](https://github.com/factory-ai/factory-cli) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Gemini CLI](https://geminicli.com/) | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [GitGuardian](https://www.gitguardian.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅, ❌ | +| [GitHub Copilot CLI](https://github.com/features/copilot/cli) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [GitHub Copilot for Xcode](https://github.com/github/CopilotForXcode) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌, ❌ | +| [Glama](https://glama.ai/chat) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅, ✅ | +| [Google Antigravity](https://antigravity.google) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌, ❌ | +| [Goose](https://block.github.io/goose) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Jan AI](https://jan.ai) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [JetBrains AI Assistant](https://plugins.jetbrains.com/plugin/22282-jetbrains-ai-assistant) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ✅, ❌ | +| [JetBrains AI Assistant with GitHub Copilot](https://plugins.jetbrains.com/plugin/22282-jetbrains-ai-assistant) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ✅, ❌ | +| [Kilo Code](https://github.com/Kilo-Org/kilocode) | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌, ❌ | +| [LibreChat](https://www.librechat.ai) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [LobeHub](https://lobehub.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Make MCP Client](https://www.make.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Mistral AI: Le Chat](https://chat.mistral.ai) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ✅, ❌ | +| [N8N MCP Client](https://n8n.io) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [OpenAI Codex](https://openai.com/codex) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅, ❌ | +| [Opencode](https://opencode.ai) | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Postman](https://postman.com/downloads) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅, ❌ | +| [Raycast](https://www.raycast.com) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌, ❌ | +| [Roo Code](https://roocode.com) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Visual Studio Code](https://code.visualstudio.com) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅, ✅ | +| [Windsurf Editor](https://codeium.com/windsurf) | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌, ❌ | +| [Zed Editor](https://zed.dev) | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌, ❌ | ### Column explanations @@ -148,7 +148,7 @@ most clients don't use versions anyway. This might change in the future. - **Sampling**: Whether the client supports sampling from an LLM. This allows the server to request the client to generate text using its language model. - **Tasks**: Whether the client supports task-augmented tool calls. This enables asynchronous execution where the server can poll task status and retrieve results after completion, useful for expensive or long-running operations. - **Roots**: Whether the client supports managing root directories. Roots define the workspace or directories that the client wants the server to have access to. -- **Elicitation**: Whether the client supports elicitation from the server. This allows the server to request additional information or clarification from the client during interactions. +- **Elicitation**: Whether the client supports elicitation from the server. This allows the server to request additional information or clarification from the client during interactions. Clients may support **form**-based elicitation (structured input fields), **url**-based elicitation (opening a URL for the user), or both. ## Usage diff --git a/scripts/generate-table.js b/scripts/generate-table.js index c588e27..ad2e75e 100644 --- a/scripts/generate-table.js +++ b/scripts/generate-table.js @@ -7,7 +7,7 @@ const readmePath = path.join(__dirname, '../README.md'); const clients = JSON.parse(fs.readFileSync(jsonPath, 'utf8')); // Generate table content (header + rows) -const tableHeader = `| Display name | [Resources](#resources) | [Prompts](#prompts) | [Tools](#tools) | [Discovery](#discovery) | [Sampling](#sampling) | [Tasks](#tasks) | [Roots](#roots) | [Elicitation](#elicitation) | +const tableHeader = `| Display name | [Resources](#resources) | [Prompts](#prompts) | [Tools](#tools) | [Discovery](#discovery) | [Sampling](#sampling) | [Tasks](#tasks) | [Roots](#roots) | [Elicitation](#elicitation) (form, url) | | --- | --- | --- | --- | --- | --- | --- | --- | --- |`; // Track seen display names to skip duplicates @@ -31,7 +31,10 @@ const tableRows = Object.entries(clients) const sampling = clientData.sampling ? '✅' : '❌'; const tasks = clientData.tasks?.requests?.tools?.call ? '✅' : '❌'; const roots = clientData.roots ? '✅' : '❌'; - const elicitation = clientData.elicitation ? '✅' : '❌'; + const hasElicitation = !!clientData.elicitation; + const elicitationForm = hasElicitation && (!clientData.elicitation.url || clientData.elicitation.form) ? '✅' : '❌'; + const elicitationUrl = clientData.elicitation?.url ? '✅' : '❌'; + const elicitation = `${elicitationForm}, ${elicitationUrl}`; return `| ${displayName} | ${resources} | ${prompts} | ${tools} | ${discovery} | ${sampling} | ${tasks} | ${roots} | ${elicitation} |`; }) diff --git a/src/mcp_client_capabilities/mcp_types.py b/src/mcp_client_capabilities/mcp_types.py index b2f0228..eb1e1a1 100644 --- a/src/mcp_client_capabilities/mcp_types.py +++ b/src/mcp_client_capabilities/mcp_types.py @@ -35,7 +35,8 @@ class Experimental(TypedDict, total=False): class Elicitation(TypedDict, total=False): - pass + form: Optional[dict] + url: Optional[dict] class Sampling(TypedDict, total=False): diff --git a/src/types.ts b/src/types.ts index ead6a79..05c31b0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,7 +14,7 @@ export interface McpClientRecord { prompts?: { listChanged?: boolean }; tools?: { listChanged?: boolean }; tasks?: { requests?: { tools?: { call?: {} } } }; - elicitation?: {}; + elicitation?: { form?: {}; url?: {} }; sampling?: {}, roots?: { listChanged?: boolean }, completions?: {}; diff --git a/src/validate.ts b/src/validate.ts index 1480dfc..93fc5ae 100644 --- a/src/validate.ts +++ b/src/validate.ts @@ -159,10 +159,24 @@ function validateClientCapabilities(clientName: string, record: any): record is } } - // Validate elicitation capability (empty object) + // Validate elicitation capability if (record.elicitation !== undefined) { if (typeof record.elicitation !== 'object' || record.elicitation === null) { errors.push(`${clientName}.elicitation: must be an object`); + } else { + for (const key of Object.keys(record.elicitation)) { + if (key === 'form' || key === 'url') { + if (typeof record.elicitation[key] !== 'object' || record.elicitation[key] === null) { + errors.push(`${clientName}.elicitation.${key}: must be an object`); + } else { + for (const subKey of Object.keys(record.elicitation[key])) { + errors.push(`${clientName}.elicitation.${key}: unknown property '${subKey}'`); + } + } + } else { + errors.push(`${clientName}.elicitation: unknown property '${key}'`); + } + } } }