Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/tools/ask-gemini.tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export const askGeminiTool: UnifiedTool = {
description: "Execute 'gemini -p <prompt>' to get Gemini AI's response. Supports enhanced change mode for structured edit suggestions.",
},
category: 'gemini',
annotations: {
title: "Ask Gemini",
readOnlyHint: true,
openWorldHint: true,
},
execute: async (args, onProgress) => {
const { prompt, model, sandbox, changeMode, chunkIndex, chunkCacheKey } = args; if (!prompt?.trim()) { throw new Error(ERROR_MESSAGES.NO_PROMPT_PROVIDED); }

Expand Down
5 changes: 5 additions & 0 deletions src/tools/brainstorm.tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ export const brainstormTool: UnifiedTool = {
description: "Generate structured brainstorming prompt with methodology-driven ideation, domain context integration, and analytical evaluation framework",
},
category: 'gemini',
annotations: {
title: "Brainstorm",
readOnlyHint: true,
openWorldHint: true,
},
execute: async (args, onProgress) => {
const {
prompt,
Expand Down
11 changes: 8 additions & 3 deletions src/tools/fetch-chunk.tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const inputSchema = z.object({
export const fetchChunkTool: UnifiedTool = {
name: 'fetch-chunk',
description: 'Retrieves cached chunks from a changeMode response. Use this to get subsequent chunks after receiving a partial changeMode response.',

zodSchema: inputSchema,

prompt: {
description: 'Fetch the next chunk of a response',
arguments: [
Expand All @@ -25,8 +25,13 @@ export const fetchChunkTool: UnifiedTool = {
}
]
},

category: 'utility',
annotations: {
title: "Fetch Chunk",
readOnlyHint: true,
idempotentHint: true,
},

execute: async (args: any, onProgress?: (newOutput: string) => void): Promise<string> => {
const { cacheKey, chunkIndex } = args;
Expand Down
26 changes: 23 additions & 3 deletions src/tools/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,28 @@ import { ToolArguments } from "../constants.js";
import { ZodTypeAny, ZodError } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

/**
* MCP Tool annotations per specification.
* @see https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#annotations
*/
export interface ToolAnnotations {
/** Human-readable title for the tool */
title?: string;
/** If true, the tool does not modify its environment */
readOnlyHint?: boolean;
/** If true, the tool may perform destructive updates */
destructiveHint?: boolean;
/** If true, repeated calls with same args have no additional effect */
idempotentHint?: boolean;
/** If true, the tool interacts with external entities */
openWorldHint?: boolean;
}

export interface UnifiedTool {
name: string;
description: string;
zodSchema: ZodTypeAny;

prompt?: {
description: string;
arguments?: Array<{
Expand All @@ -17,9 +34,11 @@ export interface UnifiedTool {
required: boolean;
}>;
};

execute: (args: ToolArguments, onProgress?: (newOutput: string) => void) => Promise<string>;
category?: 'simple' | 'gemini' | 'utility';
/** MCP tool annotations for AI assistants */
annotations?: ToolAnnotations;
}

export const toolRegistry: UnifiedTool[] = [];
Expand All @@ -35,11 +54,12 @@ export function getToolDefinitions(): Tool[] { // get Tool definitions from regi
properties: def.properties || {},
required: def.required || [],
};

return {
name: tool.name,
description: tool.description,
inputSchema,
annotations: tool.annotations,
};
});
}
Expand Down
10 changes: 10 additions & 0 deletions src/tools/simple-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export const pingTool: UnifiedTool = {
description: "Echo test message with structured response.",
},
category: 'simple',
annotations: {
title: "Ping",
readOnlyHint: true,
idempotentHint: true,
},
execute: async (args, onProgress) => {
const message = args.prompt || args.message || "Pong!";
return executeCommand("echo", [message as string], onProgress);
Expand All @@ -30,6 +35,11 @@ export const helpTool: UnifiedTool = {
description: "receive help information",
},
category: 'simple',
annotations: {
title: "Help",
readOnlyHint: true,
openWorldHint: true,
},
execute: async (args, onProgress) => {
return executeCommand("gemini", ["-help"], onProgress);
}
Expand Down
4 changes: 4 additions & 0 deletions src/tools/timeout-test.tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export const timeoutTestTool: UnifiedTool = {
description: "Test the timeout prevention system by running a long operation",
},
category: 'simple',
annotations: {
title: "Timeout Test",
readOnlyHint: true,
},
execute: async (args, onProgress) => {
const duration = args.duration as number;
const steps = Math.ceil(duration / 5000); // Progress every 5 seconds
Expand Down