Skip to content

Commit d54d1af

Browse files
ArthurDEV44claude
andcommitted
feat(mcp): add MCP 2025-06-18 compliance with output schemas and annotations
- Add outputSchema to core tools for structured validation - Add tool annotations (readOnlyHint, idempotentHint, longRunningHint, title) - Add semantic property descriptions for better LLM tool selection - Extend ToolRegistry to support outputSchema and annotations - Update token budgets for MCP 2025-06-18 requirements - Update release notes with MCP compliance section Tools updated: auto_optimize, smart_file_read, discover_tools, code_execute, session_stats, summarize_logs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1b1d07d commit d54d1af

File tree

9 files changed

+445
-117
lines changed

9 files changed

+445
-117
lines changed

RELEASE_NOTES_v0.8.0.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,46 @@ Nouveau mode de résumé pour les fichiers volumineux :
108108

109109
---
110110

111+
## Conformité MCP 2025-06-18
112+
113+
### Output Schemas
114+
115+
Tous les outils principaux incluent maintenant des schémas de sortie conformes à la spécification MCP 2025-06-18 :
116+
117+
- **Validation structurée** : Les résultats sont validés contre un schéma défini
118+
- **Documentation automatique** : Chaque champ de sortie est documenté avec sa description et son type
119+
- **Interopérabilité** : Meilleure intégration avec les clients MCP conformes
120+
121+
Outils mis à jour : `auto_optimize`, `smart_file_read`, `discover_tools`, `code_execute`, `session_stats`, `summarize_logs`.
122+
123+
### Annotations d'outils
124+
125+
Nouveau système d'annotations pour guider les LLMs dans l'utilisation des outils :
126+
127+
- **readOnlyHint** : Indique que l'outil ne modifie pas l'état du système
128+
- **destructiveHint** : Avertit des opérations potentiellement destructives
129+
- **idempotentHint** : Signale que le même input produit toujours le même résultat
130+
- **longRunningHint** : Prévient que l'exécution peut être longue
131+
- **title** : Titre lisible pour l'affichage dans les interfaces
132+
133+
### Descriptions sémantiques
134+
135+
Les schémas d'entrée incluent maintenant des descriptions détaillées pour chaque propriété :
136+
137+
- Amélioration de la sélection automatique d'outils par les LLMs
138+
- Documentation inline des paramètres avec valeurs par défaut
139+
- Contraintes de validation (`minLength`, `minimum`, `maximum`)
140+
141+
### Registre d'outils étendu
142+
143+
Le `ToolRegistry` supporte maintenant :
144+
145+
- `outputSchema` optionnel pour chaque outil
146+
- `annotations` pour les métadonnées comportementales
147+
- Sérialisation complète dans la réponse `ListTools`
148+
149+
---
150+
111151
## Pipeline Builder fluide
112152

113153
Nouvelle API chaînable pour les opérations multi-étapes :

packages/mcp-server/src/tools/auto-optimize.ts

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,66 @@ import { countTokens } from "../utils/token-counter.js";
1717

1818
type OutputFormat = "plain" | "markdown";
1919

20-
// Minimal schema - format rarely used, keep only essential properties
20+
// Input schema with semantic descriptions for better LLM understanding
2121
const autoOptimizeSchema = {
2222
type: "object" as const,
2323
properties: {
24-
content: { type: "string" },
25-
hint: { enum: ["build", "logs", "errors", "code", "auto"] },
26-
aggressive: { type: "boolean" },
27-
format: { enum: ["plain", "markdown"] },
24+
content: {
25+
type: "string",
26+
description: "The content to optimize (build output, logs, errors, or any text)",
27+
minLength: 100,
28+
},
29+
hint: {
30+
enum: ["build", "logs", "errors", "code", "auto"],
31+
description: "Content type hint: build (compiler errors), logs (server/test logs), errors (stack traces), code (source code), auto (detect)",
32+
default: "auto",
33+
},
34+
aggressive: {
35+
type: "boolean",
36+
description: "Enable aggressive compression for maximum token savings",
37+
default: false,
38+
},
39+
format: {
40+
enum: ["plain", "markdown"],
41+
description: "Output format",
42+
default: "plain",
43+
},
2844
},
2945
required: ["content"],
3046
};
3147

48+
// Output schema per MCP 2025-06-18 spec for structured validation
49+
const autoOptimizeOutputSchema = {
50+
type: "object" as const,
51+
properties: {
52+
detectedType: {
53+
type: "string",
54+
description: "Detected or specified content type",
55+
},
56+
originalTokens: {
57+
type: "number",
58+
description: "Token count before optimization",
59+
},
60+
optimizedTokens: {
61+
type: "number",
62+
description: "Token count after optimization",
63+
},
64+
savingsPercent: {
65+
type: "number",
66+
description: "Percentage of tokens saved (0-100)",
67+
},
68+
method: {
69+
type: "string",
70+
description: "Compression method used",
71+
},
72+
optimizedContent: {
73+
type: "string",
74+
description: "The optimized content",
75+
},
76+
},
77+
required: ["detectedType", "originalTokens", "optimizedTokens", "savingsPercent", "optimizedContent"],
78+
};
79+
3280
interface AutoOptimizeArgs {
3381
content: string;
3482
hint?: "build" | "logs" | "errors" | "code" | "auto";
@@ -229,7 +277,16 @@ async function autoOptimize(
229277

230278
export const autoOptimizeTool: ToolDefinition = {
231279
name: "auto_optimize",
232-
description: "Auto-compress verbose output (build errors, logs). 80-95% token reduction.",
280+
description:
281+
"Auto-compress verbose output (build errors, logs, stack traces). " +
282+
"Detects content type and applies optimal compression. " +
283+
"Typical savings: build errors 95%, logs 80-90%, generic 40-60%.",
233284
inputSchema: autoOptimizeSchema,
285+
outputSchema: autoOptimizeOutputSchema,
286+
annotations: {
287+
title: "Auto Optimize Content",
288+
readOnlyHint: true,
289+
idempotentHint: true,
290+
},
234291
execute: async (args) => autoOptimize(args as AutoOptimizeArgs),
235292
};

packages/mcp-server/src/tools/code-execute.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,42 @@ import type { ToolDefinition } from "./registry.js";
99
import { executeSandbox, DEFAULT_LIMITS } from "../sandbox/index.js";
1010

1111
/**
12-
* Minimal schema for token efficiency
12+
* Input schema with semantic descriptions
1313
*/
1414
const codeExecuteSchema = {
1515
type: "object" as const,
1616
properties: {
17-
code: { type: "string" },
18-
timeout: { type: "number" },
17+
code: {
18+
type: "string",
19+
description:
20+
"TypeScript code to execute. Use 'return' to output results. " +
21+
"Access SDK via 'ctx' object (ctx.files, ctx.compress, ctx.code, etc.)",
22+
},
23+
timeout: {
24+
type: "number",
25+
description: "Execution timeout in ms (1000-30000)",
26+
minimum: 1000,
27+
maximum: 30000,
28+
default: 5000,
29+
},
1930
},
2031
required: ["code"],
2132
};
2233

34+
/**
35+
* Output schema per MCP 2025-06-18 spec
36+
*/
37+
const codeExecuteOutputSchema = {
38+
type: "object" as const,
39+
properties: {
40+
success: { type: "boolean", description: "Whether execution succeeded" },
41+
output: { type: "string", description: "Execution result or error message" },
42+
executionTimeMs: { type: "number", description: "Time taken in milliseconds" },
43+
tokensUsed: { type: "number", description: "Tokens in output" },
44+
},
45+
required: ["success", "output"],
46+
};
47+
2348
interface CodeExecuteArgs {
2449
code: string;
2550
timeout?: number;
@@ -98,5 +123,12 @@ export const codeExecuteTool: ToolDefinition = {
98123
name: "code_execute",
99124
description: DESCRIPTION,
100125
inputSchema: codeExecuteSchema,
126+
outputSchema: codeExecuteOutputSchema,
127+
annotations: {
128+
title: "Execute TypeScript Code",
129+
readOnlyHint: false, // Can modify files via ctx.files
130+
idempotentHint: false, // Results depend on filesystem state
131+
longRunningHint: true, // May take up to 30s
132+
},
101133
execute: executeCodeExecute,
102134
};

packages/mcp-server/src/tools/discover-tools.ts

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,57 @@ import {
1818
type ToolMetadataLite,
1919
} from "../utils/toon-serializer.js";
2020

21-
// Minimal schema - descriptions in tool description, not properties
21+
// Input schema with semantic descriptions per MCP best practices
2222
const discoverToolsSchema = {
2323
type: "object" as const,
2424
properties: {
25-
query: { type: "string" },
26-
category: { enum: ["compress", "analyze", "logs", "code", "pipeline"] },
27-
load: { type: "boolean" },
28-
format: { enum: ["list", "toon", "toon-tabular"] },
25+
query: {
26+
type: "string",
27+
description: "Search query to find tools by name or description",
28+
},
29+
category: {
30+
enum: ["compress", "analyze", "logs", "code", "pipeline"],
31+
description: "Filter tools by category",
32+
},
33+
load: {
34+
type: "boolean",
35+
description: "Activate matched tools for immediate use",
36+
default: false,
37+
},
38+
format: {
39+
enum: ["list", "toon", "toon-tabular"],
40+
description: "Output format: list (readable), toon/toon-tabular (token-efficient ~55% savings)",
41+
default: "list",
42+
},
2943
},
3044
};
3145

46+
/**
47+
* Output schema per MCP 2025-06-18 spec
48+
*/
49+
const discoverToolsOutputSchema = {
50+
type: "object" as const,
51+
properties: {
52+
matchedTools: {
53+
type: "array",
54+
description: "List of matching tools",
55+
items: {
56+
type: "object",
57+
properties: {
58+
name: { type: "string" },
59+
category: { type: "string" },
60+
description: { type: "string" },
61+
},
62+
},
63+
},
64+
loadedCount: {
65+
type: "number",
66+
description: "Number of tools activated (if load=true)",
67+
},
68+
},
69+
required: ["matchedTools"],
70+
};
71+
3272
type OutputFormat = "list" | "toon" | "toon-tabular";
3373

3474
interface DiscoverToolsArgs {
@@ -205,7 +245,17 @@ function formatListOutput(
205245

206246
export const discoverToolsTool: ToolDefinition = {
207247
name: "discover_tools",
208-
description: "Find and load optimization tools. Categories: compress, analyze, logs, code, pipeline.",
248+
description:
249+
"Find and load optimization tools on-demand. " +
250+
"Categories: compress (token reduction), analyze (parsing), logs (summarization), " +
251+
"code (AST extraction), pipeline (chained operations). " +
252+
"Use TOON format for 55% additional token savings.",
209253
inputSchema: discoverToolsSchema,
254+
outputSchema: discoverToolsOutputSchema,
255+
annotations: {
256+
title: "Discover Tools",
257+
readOnlyHint: true,
258+
idempotentHint: true,
259+
},
210260
execute: executeDiscoverTools,
211261
};

packages/mcp-server/src/tools/registry.ts

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,31 @@ import type { ToolContext, ToolResult } from "../middleware/types.js";
88
import type { MiddlewareChain } from "../middleware/chain.js";
99
import { countTokens } from "../utils/token-counter.js";
1010

11+
/**
12+
* Tool annotations per MCP 2025-06-18 specification
13+
* @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools
14+
*/
15+
export interface ToolAnnotations {
16+
/** Tool only reads data, doesn't modify state */
17+
readOnlyHint?: boolean;
18+
/** Tool may perform destructive operations */
19+
destructiveHint?: boolean;
20+
/** Tool is idempotent (same input = same result) */
21+
idempotentHint?: boolean;
22+
/** Tool may take a long time to execute */
23+
longRunningHint?: boolean;
24+
/** Human-readable title for the tool */
25+
title?: string;
26+
}
27+
1128
export interface ToolDefinition {
1229
name: string;
1330
description: string;
1431
inputSchema: Record<string, unknown>;
32+
/** Output schema for structured result validation (MCP 2025-06-18) */
33+
outputSchema?: Record<string, unknown>;
34+
/** Tool behavior annotations for LLM guidance */
35+
annotations?: ToolAnnotations;
1536
execute: (args: unknown) => Promise<ToolExecuteResult>;
1637
}
1738

@@ -88,17 +109,40 @@ export class ToolRegistry {
88109

89110
/**
90111
* Get tool definitions for MCP ListTools response
112+
* Includes outputSchema and annotations per MCP 2025-06-18 spec
91113
*/
92114
getToolDefinitions(): Array<{
93115
name: string;
94116
description: string;
95117
inputSchema: Record<string, unknown>;
118+
outputSchema?: Record<string, unknown>;
119+
annotations?: ToolAnnotations;
96120
}> {
97-
return this.list().map((tool) => ({
98-
name: tool.name,
99-
description: tool.description,
100-
inputSchema: tool.inputSchema,
101-
}));
121+
return this.list().map((tool) => {
122+
const def: {
123+
name: string;
124+
description: string;
125+
inputSchema: Record<string, unknown>;
126+
outputSchema?: Record<string, unknown>;
127+
annotations?: ToolAnnotations;
128+
} = {
129+
name: tool.name,
130+
description: tool.description,
131+
inputSchema: tool.inputSchema,
132+
};
133+
134+
// Include outputSchema if defined (MCP 2025-06-18)
135+
if (tool.outputSchema) {
136+
def.outputSchema = tool.outputSchema;
137+
}
138+
139+
// Include annotations if defined
140+
if (tool.annotations) {
141+
def.annotations = tool.annotations;
142+
}
143+
144+
return def;
145+
});
102146
}
103147

104148
/**

0 commit comments

Comments
 (0)