add-mcp-tool
Add a new tool to an existing FastMCP server with guided configuration
What this skill does
# Add MCP Tool
Add a new tool to an existing FastMCP server with interactive configuration.
## Usage
```bash
/add-mcp-tool [tool-name]
```
## Arguments
- `[tool-name]`: Optional - Name for the new tool (will prompt if not provided)
## Execution Instructions for Claude Code
When this command is run:
1. **Locate the FastMCP server** in the current project
2. **Gather tool requirements** through interactive questions
3. **Generate tool code** based on configuration
4. **Add tool to server** by modifying existing files or creating new ones
## Interactive Session Flow
### 1. Locate Server
First, find the FastMCP server in the project:
```
Looking for FastMCP server...
Found: src/server.ts
Is this the correct server file? (yes/no):
```
If not found:
```
I couldn't find a FastMCP server. Please provide the path to your server file:
```
### 2. Tool Basics
```
Let's add a new tool to your MCP server.
Tool name (lowercase, use hyphens):
Example: "fetch-data", "create-file", "query-database"
Tool name:
```
```
Tool description (shown to LLM clients):
Example: "Fetches data from the specified API endpoint"
Description:
```
### 3. Parameters
```
Does this tool require parameters?
1. No parameters
2. Simple parameters (strings, numbers, booleans)
3. Complex parameters (objects, arrays, enums)
Select (1-3):
```
If parameters needed:
```
Let's define the parameters one by one.
Parameter 1:
Name:
Type (string/number/boolean/array/object):
Required? (yes/no):
Description:
Add another parameter? (yes/no):
```
For enum types:
```
Enum values (comma-separated):
Example: "json,xml,csv"
Values:
```
### 4. Return Type
```
What does this tool return?
1. Simple text response
2. Multiple content items
3. Image content
4. Audio content
5. Resource reference
6. Custom structure
Select (1-6):
```
### 5. Tool Features
```
Which features do you need?
[ ] Logging (log.info, log.error, etc.)
[ ] Progress reporting (for long operations)
[ ] Streaming output (for text generation)
[ ] Authorization check (canAccess)
[ ] Error handling with UserError
Select features (comma-separated numbers, or 'none'):
```
### 6. Tool Annotations
```
Optional annotations for LLM clients:
Read-only hint (tool doesn't modify state)? (yes/no) [default: no]:
Open-world hint (tool accesses external systems)? (yes/no) [default: no]:
Streaming hint (tool produces streaming output)? (yes/no) [default: no]:
```
## Generated Code Examples
### Simple Tool (no parameters)
```typescript
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
execute: async () => {
return "Result here";
},
});
```
### Tool with Parameters
```typescript
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
{{#each parameters}}
{{name}}: z.{{type}}(){{#if description}}.describe("{{description}}"){{/if}}{{#unless required}}.optional(){{/unless}},
{{/each}}
}),
execute: async (args) => {
const { {{parameterNames}} } = args;
// TODO: Implement tool logic
return "Processed: " + JSON.stringify(args);
},
});
```
### Tool with Logging
```typescript
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
url: z.string().describe("URL to fetch"),
}),
execute: async (args, { log }) => {
log.info("Starting operation", { url: args.url });
try {
// TODO: Implement logic
const result = await fetchData(args.url);
log.info("Operation completed successfully");
return result;
} catch (error) {
log.error("Operation failed", { error: String(error) });
throw error;
}
},
});
```
### Tool with Progress Reporting
```typescript
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
items: z.array(z.string()).describe("Items to process"),
}),
execute: async (args, { reportProgress }) => {
const total = args.items.length;
const results: string[] = [];
for (let i = 0; i < total; i++) {
await reportProgress({ progress: i, total });
// TODO: Process each item
results.push("Processed: " + args.items[i]);
}
await reportProgress({ progress: total, total });
return results.join("\n");
},
});
```
### Tool with Streaming Output
```typescript
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
prompt: z.string().describe("Input prompt"),
}),
annotations: {
streamingHint: true,
},
execute: async (args, { streamContent }) => {
// Stream content progressively
await streamContent({ type: "text", text: "Processing...\n" });
// TODO: Generate content
const chunks = ["First ", "part, ", "second ", "part."];
for (const chunk of chunks) {
await streamContent({ type: "text", text: chunk });
await new Promise(r => setTimeout(r, 100));
}
return; // Return undefined when using streaming
},
});
```
### Tool with Authorization
```typescript
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
canAccess: (auth) => {
// Return true if user is authorized
return auth?.role === "admin";
},
execute: async (args, { session }) => {
// Tool is only executed if canAccess returns true
return "Welcome, " + session.id;
},
});
```
### Tool with UserError
```typescript
import { UserError } from "fastmcp";
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
id: z.string().describe("Resource ID"),
}),
execute: async (args) => {
// Validate input
if (!args.id.match(/^[a-z0-9-]+$/)) {
throw new UserError("Invalid ID format. Use lowercase letters, numbers, and hyphens only.");
}
// Check resource exists
const resource = await findResource(args.id);
if (!resource) {
throw new UserError(`Resource not found: ${args.id}`);
}
return JSON.stringify(resource);
},
});
```
### Tool with Image Content
```typescript
import { imageContent } from "fastmcp";
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
imageId: z.string().describe("Image identifier"),
}),
execute: async (args) => {
// Return image from URL
return imageContent({
url: `https://example.com/images/${args.imageId}.png`,
});
// Or from file path:
// return imageContent({ path: `/path/to/${args.imageId}.png` });
// Or from buffer:
// return imageContent({ buffer: imageBuffer });
},
});
```
### Tool with Multiple Content Types
```typescript
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
execute: async () => {
return {
content: [
{ type: "text", text: "Here's the analysis:" },
{ type: "text", text: "Line 1: Found 5 issues" },
{ type: "text", text: "Line 2: 3 warnings" },
],
};
},
});
```
## File Placement Options
```
Where should the tool code be added?
1. Inline in server.ts (simple projects)
2. New file in tools/ directory (recommended for organization)
3. Existing tools file (specify which)
Select (1-3):
```
## Implementation Notes
1. **Find existing server**: Use Glob/Grep to locate FastMCP server files
2. **Parse existing structure**: Understand current tool organization
3. **Generate imports**: Add necessary imports (z, UserError, imageContent, etc.)
4. **Insert code**: Add tool at appropriate location
5. **Preserve formatting**: Match existing code style
6. **Summary**: Show the generated tool and file location
Related in AI Agents
skill-development
IncludedComprehensive meta-skill for creating, managing, validating, auditing, and distributing Claude Code skills and slash commands (unified in v2.1.3+). Provides skill templates, creation workflows, validation patterns, audit checklists, naming conventions, YAML frontmatter guidance, progressive disclosure examples, and best practices lookup. Use when creating new skills, validating existing skills, auditing skill quality, understanding skill architecture, needing skill templates, learning about YAML frontmatter requirements, progressive disclosure patterns, tool restrictions (allowed-tools), skill composition, skill naming conventions, troubleshooting skill activation issues, creating custom slash commands, configuring command frontmatter, using command arguments ($ARGUMENTS, $1, $2), bash execution in commands, file references in commands, command namespacing, plugin commands, MCP slash commands, Skill tool configuration, or deciding between skills vs slash commands. Delegates to docs-management skill for official documentation.
reprompter
IncludedTransform messy prompts into well-structured, effective prompts — single or multi-agent. Use when: "reprompt", "reprompt this", "clean up this prompt", "structure my prompt", rough text needing XML tags and best practices, "reprompter teams", "repromptception", "run with quality", "smart run", "smart agents", multi-agent tasks, audits, parallel work, anything going to agent teams. Don't use when: simple Q&A, pure chat, immediate execution-only tasks. See "Don't Use When" section for details. Outputs: Structured XML/Markdown prompt, quality score (before/after), optional team brief + per-agent sub-prompts, agent team output files. Success criteria: Single mode quality score ≥ 7/10; Repromptception per-agent prompt quality score 8+/10; all required sections present, actionable and specific.
adaptive-compaction
IncludedAdaptive add-on policy and recovery layer that decides WHEN to compact, prune, snapshot, or fork -- replacing fixed-percent auto-compaction across Claude Code, Codex, and MCP-capable hosts. Trigger on auto-compact timing or damage: "when should I compact", "is it safe to compact now or start a fresh session", "auto-compact fires too early/mid-task", "switching to an unrelated task but the window still has space", "context rot", "answers get worse the longer the session runs", "the agent forgot the plan or my decisions after it summarized", "add a layer on top that manages context without changing the agent", raising autoCompactWindow to give the policy room, or installing/tuning a cross-tool compaction policy or PreCompact hook -- even when "compaction" is never said but the problem is context-window pressure or post-summarization memory loss. Do NOT use to summarize a conversation, build RAG, write a summarization prompt (decides WHEN not HOW), or answer max-context-length trivia.
agent-skill-creator
IncludedCreate cross-platform agent skills from workflow descriptions. Activates when users ask to create an agent, automate a repetitive workflow, create a custom skill, or need advanced agent creation. Triggers on phrases like create agent for, automate workflow, create skill for, every day I have to, daily I need to, turn process into agent, need to automate, create a cross-platform skill, validate this skill, export this skill, migrate this skill. Supports single skills, multi-agent suites, transcript processing, template-based creation, interactive configuration, cross-platform export, and spec validation.
llm-wiki
IncludedUse when building or maintaining a persistent personal knowledge base (second brain) in Obsidian where an LLM incrementally ingests sources, updates entity/concept pages, maintains cross-references, and keeps a synthesis current. Triggers include "second brain", "Obsidian wiki", "personal knowledge management", "ingest this paper/article/book", "build a research wiki", "compound knowledge", "Memex", or whenever the user wants knowledge to accumulate across sessions instead of being re-derived by RAG on every query.
skill-master
IncludedAgent Skills authoring, evaluation, and optimization. Create, edit, validate, benchmark, and improve skills following the agentskills.io specification. Use when designing SKILL.md files, structuring skill folders (references, scripts, assets), ingesting external documentation into skills, running trigger evals, benchmarking skill quality, optimizing descriptions, or performing blind A/B comparisons. Keywords: agentskills.io, SKILL.md, skill authoring, eval, benchmark, trigger optimization.