/mcp-for-agents
Designs or reviews MCP servers so AI agents can use them reliably: outcome-oriented tools, flat constrained parameters, actionable errors via isError, token-efficient responses, composable outputs, and disciplined tool surfaces. Use when building an MCP server, adding tools to
$ npx -y skills add ReinaMacCredy/maestro --skill mcp-for-agents --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/mcp-for-agents
Context preview
The summary Claude sees to decide when to auto-load this skill.
Designs or reviews MCP servers so AI agents can use them reliably: outcome-oriented tools, flat constrained parameters, actionable errors via isError, token-efficient responses, composable outputs, and disciplined tool surfaces. Use when building an MCP server, adding tools to
SKILL.md
mcp-for-agents.SKILL.mdname: mcp-for-agents
description: >-
Designs or reviews MCP servers so AI agents can use them reliably: outcome-oriented
tools, flat constrained parameters, actionable errors via isError, token-efficient
responses, composable outputs, and disciplined tool surfaces. Use when building an
MCP server, adding tools to one, reviewing MCP tool design, or when the user mentions
MCP optimization, tool descriptions, MCP best practices, or agent-friendly MCP design.
Also use when the user has too many tools causing agent confusion, bloated responses
wasting tokens, or agents picking the wrong tool.
MCP for agents
Developer-oriented MCP servers often fail agents: 1:1 REST-to-tool mappings that force multi-step orchestration, vague descriptions that cause wrong tool selection, nested parameter objects that invite hallucination, and raw API passthrough that exhausts the context window. Design for the agent's constraints, not the developer's convenience.
Outcomes over operations
The agent decides *when* to call; the server decides *how*. Combine backend operations server-side so the agent makes one call, not three.
**Bad:** Expose `get_user_by_email`, `list_orders`, `get_order_status` separately -- agent chains three calls. **Good:** Expose `track_latest_order(email)` -- server handles the lookup internally, returns what the agent needs.
A tool that maps 1:1 to a REST endpoint is almost always wrong. Ask: "What outcome does the agent want?" and build the tool around that.
Flat, constrained parameters
Agents hallucinate missing keys in nested objects. Flatten parameters to top-level primitives, constrain with enums, and add sensible defaults so the agent makes fewer decisions.
**Bad:**
{
"filters": {
"status": "string",
"date_range": { "start": "string", "end": "string" },
"sort": { "field": "string", "order": "string" }
}
}**Good:**
{
"status": { "type": "string", "enum": ["pending", "shipped", "delivered"], "default": "pending" },
"since_date": { "type": "string", "description": "ISO 8601 date. Defaults to 30 days ago." },
"sort_by": { "type": "string", "enum": ["date", "total"], "default": "date" },
"limit": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 }
}Mark `required` fields explicitly in the schema. Add `description` to every property -- the agent reads these, not your README. Use consistent parameter names across all tools: pick `user_id` or `userId`, never both.
Descriptions that trigger correctly
The description is the *only* signal the agent uses to pick your tool. A study of 856 tools across 103 servers found 97% of descriptions have quality deficiencies, and 56% have unclear purpose.
Write the description as an answer to: "When should the agent reach for this?"
**Bad:** `"Sends a message"` **Good:** `"Send a Slack message to a channel or user. Use when the user asks to notify someone, post an update, or communicate via Slack. Requires channel_id or user_id. Messages must be under 4000 characters."`
Cover six components: 1. **Purpose** -- what the tool does, in one sentence 2. **When to use** -- trigger conditions in natural language matching user queries 3. **Limitations** -- what it cannot do, known constraints 4. **Parameters** -- key arguments summarized (detailed descriptions go in the schema) 5. **Completeness** -- detail proportional to complexity 6. **Examples** -- concrete usage demonstrations where helpful
Actionable errors via isError
MCP has two error mechanisms. Use the right one:
- **Protocol errors** (JSON-RPC `error` object): malformed requests, unknown tool names. The agent cannot self-correct from these.
- **Tool execution errors** (`isError: true` in result content): validation failures, API errors, business logic issues. The agent *can* self-correct from these.
Always return tool execution failures as result content with `isError: true`, not as protocol errors. The error text is an observation the agent uses to retry -- write it as an instruction.
**Bad:** `"Error: 400 Bad Request"` **Good:** `"User not found for email 'foo@bar.com'. Verify the email is lowercase, or search by user_id with find_user(user_id: '...')"`
Never expose stack traces, SQL errors, or infrastructure details. Distinguish user errors (wrong input -- explain what's valid) from server errors (backend down -- say whether to retry and when).
Token-efficient responses
Tool schemas are injected into the agent's context on every request. Input schemas alone account for 60-80% of total MCP token usage. Every description, enum value, and property competes for context window space.
**In responses:**
- Return only what the agent needs to complete the task. Do not pass through raw API responses.
- Paginate by default: add `limit` (default 20-50), return `has_more` and `total_count`.
- Prefer plain text over JSON when structure is not needed -- plain text uses ~80% fewer tokens.
- For structured data the agent must parse, use `structuredContent` with `outputSchema`.
**In schemas:**
- Keep tool count low. 5-15 tools per server is the practical ceiling for reliable selection. 30+ tools cause the agent to confuse overlapping descriptions.
- For very large surfaces (40+ tools), consider dynamic toolsets: a `search_tools(query)` discovery tool, a `describe_tool(name)` loader, and an `execute_tool(name, args)` runner. This can reduce input tokens by 90%+.
Composable outputs
Tool outputs should be directly usable as inputs to other tools without the agent needing to parse prose or guess at field names.
**Bad:** `"Successfully created user John Smith (ID: usr_abc123) in the system."` **Good:**
{ "user_id": "usr_abc123", "name": "John Smith", "created": true }Use consistent field names across tools. If `create_user` returns `user_id`, then `get_user` and `update_user` accept `user_id` -- not `id`, `userId`, or `user`.
Return IDs, URIs, and status fields the agent can f
Read more
name: mcp-for-agents description: >- Designs or reviews MCP servers so AI agents can use them reliably: outcome-oriented tools, flat constrained parameters, actionable errors via isError, token-efficient responses, composable outputs, and disciplined tool surfaces. Use when building an MCP server, adding tools to one, reviewing MCP tool design, or when the user mentions MCP optimization, tool descriptions, MCP best practices, or agent-friendly MCP design. Also use when the user has too many tools causing agent confusion, bloated responses wasting tokens, or agents picking the wrong tool.
MCP for agents
Developer-oriented MCP servers often fail agents: 1:1 REST-to-tool mappings that force multi-step orchestration, vague descriptions that cause wrong tool selection, nested parameter objects that invite hallucination, and raw API passthrough that exhausts the context window. Design for the agent's constraints, not the developer's convenience.
Outcomes over operations
The agent decides *when* to call; the server decides *how*. Combine backend operations server-side so the agent makes one call, not three.
**Bad:** Expose `get_user_by_email`, `list_orders`, `get_order_status` separately -- agent chains three calls. **Good:** Expose `track_latest_order(email)` -- server handles the lookup internally, returns what the agent needs.
A tool that maps 1:1 to a REST endpoint is almost always wrong. Ask: "What outcome does the agent want?" and build the tool around that.
Flat, constrained parameters
Agents hallucinate missing keys in nested objects. Flatten parameters to top-level primitives, constrain with enums, and add sensible defaults so the agent makes fewer decisions.
**Bad:**
{
"filters": {
"status": "string",
"date_range": { "start": "string", "end": "string" },
"sort": { "field": "string", "order": "string" }
}
}**Good:**
{
"status": { "type": "string", "enum": ["pending", "shipped", "delivered"], "default": "pending" },
"since_date": { "type": "string", "description": "ISO 8601 date. Defaults to 30 days ago." },
"sort_by": { "type": "string", "enum": ["date", "total"], "default": "date" },
"limit": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 }
}Mark `required` fields explicitly in the schema. Add `description` to every property -- the agent reads these, not your README. Use consistent parameter names across all tools: pick `user_id` or `userId`, never both.
Descriptions that trigger correctly
The description is the *only* signal the agent uses to pick your tool. A study of 856 tools across 103 servers found 97% of descriptions have quality deficiencies, and 56% have unclear purpose.
Write the description as an answer to: "When should the agent reach for this?"
**Bad:** `"Sends a message"` **Good:** `"Send a Slack message to a channel or user. Use when the user asks to notify someone, post an update, or communicate via Slack. Requires channel_id or user_id. Messages must be under 4000 characters."`
Cover six components: 1. **Purpose** -- what the tool does, in one sentence 2. **When to use** -- trigger conditions in natural language matching user queries 3. **Limitations** -- what it cannot do, known constraints 4. **Parameters** -- key arguments summarized (detailed descriptions go in the schema) 5. **Completeness** -- detail proportional to complexity 6. **Examples** -- concrete usage demonstrations where helpful
Actionable errors via isError
MCP has two error mechanisms. Use the right one:
- **Protocol errors** (JSON-RPC `error` object): malformed requests, unknown tool names. The agent cannot self-correct from these.
- **Tool execution errors** (`isError: true` in result content): validation failures, API errors, business logic issues. The agent *can* self-correct from these.
Always return tool execution failures as result content with `isError: true`, not as protocol errors. The error text is an observation the agent uses to retry -- write it as an instruction.
**Bad:** `"Error: 400 Bad Request"` **Good:** `"User not found for email 'foo@bar.com'. Verify the email is lowercase, or search by user_id with find_user(user_id: '...')"`
Never expose stack traces, SQL errors, or infrastructure details. Distinguish user errors (wrong input -- explain what's valid) from server errors (backend down -- say whether to retry and when).
Token-efficient responses
Tool schemas are injected into the agent's context on every request. Input schemas alone account for 60-80% of total MCP token usage. Every description, enum value, and property competes for context window space.
**In responses:**
- Return only what the agent needs to complete the task. Do not pass through raw API responses.
- Paginate by default: add `limit` (default 20-50), return `has_more` and `total_count`.
- Prefer plain text over JSON when structure is not needed -- plain text uses ~80% fewer tokens.
- For structured data the agent must parse, use `structuredContent` with `outputSchema`.
**In schemas:**
- Keep tool count low. 5-15 tools per server is the practical ceiling for reliable selection. 30+ tools cause the agent to confuse overlapping descriptions.
- For very large surfaces (40+ tools), consider dynamic toolsets: a `search_tools(query)` discovery tool, a `describe_tool(name)` loader, and an `execute_tool(name, args)` runner. This can reduce input tokens by 90%+.
Composable outputs
Tool outputs should be directly usable as inputs to other tools without the agent needing to parse prose or guess at field names.
**Bad:** `"Successfully created user John Smith (ID: usr_abc123) in the system."` **Good:**
{ "user_id": "usr_abc123", "name": "John Smith", "created": true }Use consistent field names across tools. If `create_user` returns `user_id`, then `get_user` and `update_user` accept `user_id` -- not `id`, `userId`, or `user`.
Return IDs, URIs, and status fields the agent can f
Local-first harness for agent-built codebases. Humans steer, agents execute, maestro is the substrate. maestro is a single Rust binary that gives a coding agent a durable place to work.
Repo: ReinaMacCredy/maestro
Other skills on maestro.
- /cli-for-agent
Designs or reviews CLIs so coding agents can run them reliably: non-interactive flags, layered --help with examples, stdin/pipelines, fast actionable errors, idempotency, dry-run, and predictable structure. Use when building a CLI, adding commands, writing --help, or when the
Open skill - /docs
Update repository documentation to match the current state of the codebase. Local replacement for the remote /docs command (which needs the Claude GitHub app). Use when the user says /docs, "update the docs", "sync the README", "document this feature", or asks you to refresh
Open skill - /gitnexus-cli
Use when the user needs to run GitNexus CLI commands like analyze/index a repo, check status, clean the index, generate a wiki, or list indexed repos. Examples: \"Index this repo\", \"Reanalyze the codebase\", \"Generate a wiki\"
Open skill - /gitnexus-debugging
Use when the user is debugging a bug, tracing an error, or asking why something fails. Examples: \"Why is X failing?\", \"Where does this error come from?\", \"Trace this bug\"
Open skill - /gitnexus-exploring
Use when the user asks how code works, wants to understand architecture, trace execution flows, or explore unfamiliar parts of the codebase. Examples: \"How does X work?\", \"What calls this function?\", \"Show me the auth flow\"
Open skill - /gitnexus-guide
Use when the user asks about GitNexus itself — available tools, how to query the knowledge graph, MCP resources, graph schema, or workflow reference. Examples: \"What GitNexus tools are available?\", \"How do I use GitNexus?\"
Open skill

