diff --git a/README.md b/README.md index 4c7a4ba5..415c841d 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ Official integrations are maintained by companies building production ready MCP - DevHub Logo **[DevHub](https://github.com/devhub/devhub-cms-mcp)** - Manage and utilize website content within the [DevHub](https://www.devhub.com) CMS platform - DevRev Logo **[DevRev](https://github.com/devrev/mcp-server)** - An MCP server to integrate with DevRev APIs to search through your DevRev Knowledge Graph where objects can be imported from diff. Sources listed [here](https://devrev.ai/docs/import#available-sources). - DexPaprika Logo **[DexPaprika (CoinPaprika)](https://github.com/coinpaprika/dexpaprika-mcp)** - Access real-time DEX data, liquidity pools, token information, and trading analytics across multiple blockchain networks with [DexPaprika](https://dexpaprika.com) by CoinPaprika. -- Drata Logo **[Drata](https://drata.com/mcp)** - Get hands-on with our experimental MCP server—bringing real-time compliance intelligence into your AI workflows. +- Drata Logo **[Drata](https://drata.com/mcp)** - Get hands-on with our experimental MCP server—bringing real-time compliance intelligence into your AI workflows. - Dumpling AI Logo **[Dumpling AI](https://github.com/Dumpling-AI/mcp-server-dumplingai)** - Access data, web scraping, and document conversion APIs by [Dumpling AI](https://www.dumplingai.com/) - Dynatrace Logo **[Dynatrace](https://github.com/dynatrace-oss/dynatrace-mcp)** - Manage and interact with the [Dynatrace Platform ](https://www.dynatrace.com/platform) for real-time observability and monitoring. - E2B Logo **[E2B](https://github.com/e2b-dev/mcp-server)** - Run code in secure sandboxes hosted by [E2B](https://e2b.dev) diff --git a/src/everything/README.md b/src/everything/README.md index 261ce033..3ab3299a 100644 --- a/src/everything/README.md +++ b/src/everything/README.md @@ -72,6 +72,14 @@ This MCP server attempts to exercise all the features of the MCP protocol. It is - Embedded resource with `type: "resource"` - Text instruction for using the resource URI +9. `startElicitation` + - Initiates an elicitation (interaction) within the MCP client. + - Inputs: + - `color` (string): Favorite color + - `number` (number, 1-100): Favorite number + - `pets` (enum): Favorite pet + - Returns: Confirmation of the elicitation demo with selection summary. + ### Resources The server provides 100 test resources in two formats: diff --git a/src/everything/everything.ts b/src/everything/everything.ts index 541b8382..b1f6950b 100644 --- a/src/everything/everything.ts +++ b/src/everything/everything.ts @@ -86,6 +86,8 @@ const GetResourceReferenceSchema = z.object({ .describe("ID of the resource to reference (1-100)"), }); +const ElicitationSchema = z.object({}); + const GetResourceLinksSchema = z.object({ count: z .number() @@ -104,6 +106,7 @@ enum ToolName { GET_TINY_IMAGE = "getTinyImage", ANNOTATED_MESSAGE = "annotatedMessage", GET_RESOURCE_REFERENCE = "getResourceReference", + ELICITATION = "startElicitation", GET_RESOURCE_LINKS = "getResourceLinks", } @@ -126,6 +129,7 @@ export const createServer = () => { tools: {}, logging: {}, completions: {}, + elicitation: {}, }, instructions } @@ -216,6 +220,21 @@ export const createServer = () => { return await server.request(request, CreateMessageResultSchema); }; + const requestElicitation = async ( + message: string, + requestedSchema: any + ) => { + const request = { + method: 'elicitation/create', + params: { + message, + requestedSchema + } + }; + + return await server.request(request, z.any()); + }; + const ALL_RESOURCES: Resource[] = Array.from({ length: 100 }, (_, i) => { const uri = `test://static/resource/${i + 1}`; if (i % 2 === 0) { @@ -469,6 +488,11 @@ export const createServer = () => { "Returns a resource reference that can be used by MCP clients", inputSchema: zodToJsonSchema(GetResourceReferenceSchema) as ToolInput, }, + { + name: ToolName.ELICITATION, + description: "Demonstrates the Elicitation feature by asking the user to provide information about their favorite color, number, and pets.", + inputSchema: zodToJsonSchema(ElicitationSchema) as ToolInput, + }, { name: ToolName.GET_RESOURCE_LINKS, description: @@ -664,6 +688,61 @@ export const createServer = () => { return { content }; } + if (name === ToolName.ELICITATION) { + ElicitationSchema.parse(args); + + const elicitationResult = await requestElicitation( + 'What are your favorite things?', + { + type: 'object', + properties: { + color: { type: 'string', description: 'Favorite color' }, + number: { type: 'integer', description: 'Favorite number', minimum: 1, maximum: 100 }, + pets: { + type: 'string', + enum: ['cats', 'dogs', 'birds', 'fish', 'reptiles'], + description: 'Favorite pets' + }, + } + } + ); + + // Handle different response actions + const content = []; + + if (elicitationResult.action === 'accept' && elicitationResult.content) { + content.push({ + type: "text", + text: `✅ User provided their favorite things!`, + }); + + // Only access elicitationResult.content when action is accept + const { color, number, pets } = elicitationResult.content; + content.push({ + type: "text", + text: `Their favorites are:\n- Color: ${color || 'not specified'}\n- Number: ${number || 'not specified'}\n- Pets: ${pets || 'not specified'}`, + }); + } else if (elicitationResult.action === 'decline') { + content.push({ + type: "text", + text: `❌ User declined to provide their favorite things.`, + }); + } else if (elicitationResult.action === 'cancel') { + content.push({ + type: "text", + text: `⚠️ User cancelled the elicitation dialog.`, + }); + } + + // Include raw result for debugging + content.push({ + type: "text", + text: `\nRaw result: ${JSON.stringify(elicitationResult, null, 2)}`, + }); + + return { content }; + } + if (name === ToolName.GET_RESOURCE_LINKS) { const { count } = GetResourceLinksSchema.parse(args); const content = [];