Skip to content

Commit cdce732

Browse files
committed
good progress
1 parent bc6cb6a commit cdce732

8 files changed

Lines changed: 138 additions & 28 deletions

File tree

exercises/01.sampling/01.problem.simple/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
"name": "exercises_01.sampling_01.problem.simple",
33
"private": true,
44
"type": "module",
5-
"epicshop": {
6-
"testTab": {
7-
"enabled": true
8-
}
9-
},
105
"scripts": {
116
"dev": "mcp-dev",
127
"dev:mcp": "tsx src/index.ts",

exercises/01.sampling/01.solution.simple/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
"name": "exercises_01.sampling_01.solution.simple",
33
"private": true,
44
"type": "module",
5-
"epicshop": {
6-
"testTab": {
7-
"enabled": true
8-
}
9-
},
105
"scripts": {
116
"dev": "mcp-dev",
127
"dev:mcp": "tsx src/index.ts",

exercises/01.sampling/02.problem.advanced/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
"name": "exercises_01.sampling_02.problem.advanced",
33
"private": true,
44
"type": "module",
5-
"epicshop": {
6-
"testTab": {
7-
"enabled": true
8-
}
9-
},
105
"scripts": {
116
"dev": "mcp-dev",
127
"dev:mcp": "tsx src/index.ts",

exercises/01.sampling/02.solution.advanced/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
"name": "exercises_01.sampling_02.solution.advanced",
33
"private": true,
44
"type": "module",
5-
"epicshop": {
6-
"testTab": {
7-
"enabled": true
8-
}
9-
},
105
"scripts": {
116
"dev": "mcp-dev",
127
"dev:mcp": "tsx src/index.ts",

exercises/99.finished/01.solution.finished/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
"name": "exercises_05.sampling_02.solution.advanced",
33
"private": true,
44
"type": "module",
5-
"epicshop": {
6-
"testTab": {
7-
"enabled": true
8-
}
9-
},
105
"scripts": {
116
"dev": "mcp-dev",
127
"dev:mcp": "tsx src/index.ts",

exercises/99.finished/01.solution.finished/src/index.test.ts

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
77
import {
88
CreateMessageRequestSchema,
99
type CreateMessageResult,
10+
ElicitRequestSchema,
1011
ResourceUpdatedNotificationSchema,
1112
} from '@modelcontextprotocol/sdk/types.js'
1213
import { test, expect } from 'vitest'
@@ -352,3 +353,135 @@ test('Resource subscriptions: entry and tag', async () => {
352353
await new Promise((r) => setTimeout(r, 200))
353354
expect(notifications).toHaveLength(0)
354355
})
356+
357+
test('Elicitation: delete_entry confirmation', async () => {
358+
await using setup = await setupClient({ capabilities: { elicitation: {} } })
359+
const { client } = setup
360+
361+
// Set up a handler for elicitation requests
362+
let elicitationRequest: any
363+
client.setRequestHandler(ElicitRequestSchema, (req) => {
364+
elicitationRequest = req
365+
// Simulate user accepting the confirmation
366+
return {
367+
action: 'accept',
368+
content: { confirmed: true },
369+
}
370+
})
371+
372+
// Create an entry to delete
373+
const entryResult = await client.callTool({
374+
name: 'create_entry',
375+
arguments: {
376+
title: 'Elicit Test Entry',
377+
content: 'Testing elicitation on delete.',
378+
},
379+
})
380+
const entry = (entryResult.structuredContent as any).entry
381+
invariant(entry, '🚨 No entry resource found')
382+
invariant(entry.id, '🚨 No entry ID found')
383+
384+
// Delete the entry, which should trigger elicitation
385+
const deleteResult = await client.callTool({
386+
name: 'delete_entry',
387+
arguments: { id: entry.id },
388+
})
389+
const structuredContent = deleteResult.structuredContent as any
390+
invariant(
391+
structuredContent,
392+
'🚨 No structuredContent returned from delete_entry',
393+
)
394+
invariant(
395+
'success' in structuredContent,
396+
'🚨 structuredContent missing success field',
397+
)
398+
expect(structuredContent.success).toBe(true)
399+
400+
invariant(elicitationRequest, '🚨 No elicitation request was sent')
401+
const params = elicitationRequest.params
402+
invariant(params, '🚨 elicitationRequest missing params')
403+
invariant(
404+
typeof params.message === 'string',
405+
'🚨 elicitationRequest.params.message must be a string',
406+
)
407+
invariant(
408+
params.message.match(/Are you sure you want to delete entry/i),
409+
'🚨 elicitationRequest.params.message does not match expected confirmation prompt',
410+
)
411+
expect(params.message).toMatch(/Are you sure you want to delete entry/i)
412+
413+
invariant(
414+
params.requestedSchema,
415+
'🚨 elicitationRequest.params.requestedSchema is missing',
416+
)
417+
invariant(
418+
params.requestedSchema.type === 'object',
419+
'🚨 elicitationRequest.params.requestedSchema.type must be "object"',
420+
)
421+
invariant(
422+
params.requestedSchema.properties &&
423+
typeof params.requestedSchema.properties === 'object',
424+
'🚨 elicitationRequest.params.requestedSchema.properties must be an object',
425+
)
426+
invariant(
427+
'confirmed' in params.requestedSchema.properties,
428+
'🚨 elicitationRequest.params.requestedSchema.properties must include confirmed',
429+
)
430+
invariant(
431+
params.requestedSchema.properties.confirmed.type === 'boolean',
432+
'🚨 elicitationRequest.params.requestedSchema.properties.confirmed.type must be boolean',
433+
)
434+
expect(params.requestedSchema).toEqual(
435+
expect.objectContaining({
436+
type: 'object',
437+
properties: expect.objectContaining({
438+
confirmed: expect.objectContaining({ type: 'boolean' }),
439+
}),
440+
}),
441+
)
442+
})
443+
444+
test('Elicitation: delete_tag decline', async () => {
445+
await using setup = await setupClient({ capabilities: { elicitation: {} } })
446+
const { client } = setup
447+
448+
// Set up a handler for elicitation requests
449+
client.setRequestHandler(ElicitRequestSchema, () => {
450+
return {
451+
action: 'decline',
452+
}
453+
})
454+
455+
// Create a tag to delete
456+
const tagResult = await client.callTool({
457+
name: 'create_tag',
458+
arguments: {
459+
name: 'Elicit Test Tag',
460+
description: 'Testing elicitation decline.',
461+
},
462+
})
463+
const tag = (tagResult.structuredContent as any).tag
464+
invariant(tag, '🚨 No tag resource found')
465+
invariant(tag.id, '🚨 No tag ID found')
466+
467+
// Delete the tag, which should trigger elicitation and be declined
468+
const deleteResult = await client.callTool({
469+
name: 'delete_tag',
470+
arguments: { id: tag.id },
471+
})
472+
const structuredContent = deleteResult.structuredContent as any
473+
invariant(
474+
structuredContent,
475+
'🚨 No structuredContent returned from delete_tag',
476+
)
477+
invariant(
478+
'success' in structuredContent,
479+
'🚨 structuredContent missing success field',
480+
)
481+
expect(structuredContent.success).toBe(false)
482+
invariant(
483+
'message' in structuredContent,
484+
'🚨 structuredContent missing message field',
485+
)
486+
expect(structuredContent.message).toMatch(/cancelled/i)
487+
})

exercises/99.finished/01.solution.finished/src/tools.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,11 @@ function createTagResourceContent(tag: { id: number }): ResourceContent {
437437
}
438438

439439
async function elicitConfirmation(agent: EpicMeMCP, message: string) {
440+
const capabilities = agent.server.server.getClientCapabilities()
441+
if (!capabilities?.elicitation) {
442+
return true
443+
}
444+
440445
const result = await agent.server.server.elicitInput({
441446
message,
442447
requestedSchema: {

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
"host": "www.epicai.pro",
1515
"displayName": "EpicAI.pro",
1616
"displayNameShort": "Epic AI"
17-
},
18-
"testTab": {
19-
"enabled": false
2017
}
2118
},
2219
"type": "module",

0 commit comments

Comments
 (0)