- The AI Stack for devs
- Posts
- Your API to MCP conversion is broken
Your API to MCP conversion is broken
5 step process to fix it

Before you jump in, here’s something you’ll love.
I’ve put together a curated list of MCP servers and MCP registries to support your development workflows. When you subscribe to the newsletter, you’ll get instant access to this resource in your welcome email.
Bonus: I’m also working on a collection of free educational resources for building AI agents at every skill level. Coming soon for subscribers. Stay tuned!

Guide to convert API endpoints to MCP tools
Most teams start MCP development by directly mapping existing REST endpoints to tools. This approach creates decision paralysis for agents when they encounter dozens of similar looking tools. Systems with 20+ granular tools often see agents spending more time selecting tools than executing tasks.
Here’s the 5-step agent first pattern to convert your team’s APIs to MCP tools.
Step 1: Consolidate by intent, not endpoints
What: Collapse CRUD endpoints into a single task oriented tool.
How:
- ReplacecreateUser
,updateUser
,deleteUser
withmanageUserProfile(action: create|update|delete, safety: safe|risky, outputFormat: summary|full)
.
- Split risky actions into dedicated tools only when needed (e.g.,updateUserStatus
).Why: Agents decide faster with fewer, more expressive tools.
// Intent-based consolidated tools
tools = [
"manageUserProfile", // handles create/update/delete via 'action'
"searchUsers", // consolidated user lookup
"updateUserStatus" // specific state changes
]
// Sample tool parameter schema (for manageUserProfile)
manageUserProfile.params = {
action: "create | update | delete", // operation type
user: "<user-id>", // target user identifier
fields: { ... }, // key-value profile data
safety: "<optional safety flags>", // e.g., admin_approval
outputFormat: "json | xml" // desired response format
}
Step 2: Make responses agent guiding, not human friendly
What: Every tool response should suggest next best actions.
How:
- Include next_actions:[verify_email, setup_profile]
- Include suggestion: "User created. Next: call verify_email with user_id"
- Standardize error surfaces with correction hints.Why: Agents recover faster and chain correctly.
//Example success response shape
success_response = {
success: true,
data: { user_id: "U12345" },
next_actions: ["verify_email", "setup_profile"], // machine-usable next steps
suggestion: "User created. Next: call verify_email with user_id" // agent hint
}
// Example error response shape
error_response = {
error_code: "EMAIL_INVALID",
message: "Provided email address is not valid",
suggestion: "Use a valid RFC5321-compliant email and retry", // correction hint
retry_after: 1
}
Step 3: Optimize tokens and latency
What: Reduce cognitive and token overhead.
How:
- Batch: accept arrays where safe (ids[], operations[]
).
- Filtered fields: fields: ["id","email"] vs "All response fields".
- Cache: versioned reference data
- Trim tool catalog: target 15–20 max.Why: Faster loops, lower costs, fewer agent retries.
// Batch support (where safe)
getUsers(params) = {
ids: ["U123", "U456"],
fields: ["id", "email"] // request only needed fields
}
// Filtered fields (partial responses instead of full objects)
readUser(params) = {
id: "U123",
fields: ["id", "email", "status"] // avoid sending entire payload
}
// Tool catalog trimming
tool_catalog = [
// maintain <20 tools (merge or retire low-use ones)
"manageUserProfile",
"searchUsers",
"updateUserStatus",
...
]
Step 4: Permissions and risk bands
What: Encode risk into the interface; make “dangerous” explicit.
How:
- Separate safe vs risky flows (e.g.,write
/delete
in their own tools).
- Require confirmations:confirm_token
or reason for risky ops.
- Scope by agent role:read_only
vsoperator
vsadmin
.Why: Prevent runaway retries and unintended writes.
// Separate safe and risky flows
// - read-users // safe: no write, just data
// - update-user-profile // risky: writes/changes
// - delete-user // risky: deletes, always requires confirmation
// Risk annotation in tool schema
deleteUser.params = {
user_id: "U123",
// Risky operation: requires extra confirmation fields
risky: true, // marks operation as high risk
reason: "Cleanup inactive account",// mandatory audit log hint
ticket_id: "JIRA-7891" // (optional) incident/change tracking
}
// Scope by agent role
agent.permissions = {
role: "operator", // e.g., read_only, operator, admin
allowed_tools: ["read-users", "create-user", "update-user-profile"]
}
Step 5: Test and monitor with MCP Inspector
What: Validate schemas and real agent loops.
How:
Run:
npx @modelcontextprotocol/inspector
against your serverLog per agent: tool selection counts, error cause, avg hops/task
// Log and monitor key metrics per agent/session
metrics = {
tool_selection_frequency: { // How often each tool is selected
"manageUserProfile": 124,
"searchUsers": 87,
"updateUserStatus": 39
},
error_rate_by_tool: { // Error counts and rates per tool
"manageUserProfile": 0.07,
"searchUsers": 0.02,
"updateUserStatus": 0.15
},
avg_response_time: { // Average response time in ms per tool
"manageUserProfile": 450,
"searchUsers": 120,
"updateUserStatus": 300
},
average_tools_per_task: 3.5, // Average number of tools called per agent task
abandon_rate: 0.05 // % of tasks abandoned/failing unrecoverably
}
// Use these metrics to:
// - Identify bottlenecks causing latency or failures
// - Spot tools that are under or over-used and adjust tool catalog accordingly
// - Optimize agent workflows to reduce hops and cost
// - Improve success rates and decrease abandon rate by refining tool design

If you’re not a subscriber, here’s what you missed this month
Subscribe to get access to such posts every week in your email.
I’ve compiled a list of useful MCP servers and MCP registries to support your development work. Check it out here. Feel free to share it with your teammates/colleagues and if you find it helpful, I’d really appreciate you spreading the word about this newsletter.

👀 Whats shipping (shipped) this week?
POML (Prompt Orchestration Markup Language) is Microsoft's new markup language for structured prompt engineering with Large Language Models
Claude Code adds the ability to clear old tool calls for longer sessions, plus PDF support and automatic security reviews.
📖 Worth the scroll

🤓 Case Studies
Perplexity enabled day-0 support for OpenAI’s GPT-OSS-20B and 120B on its ROSE inference stack, running on H200s with FP8 and targeted kernel updates.

📰 Recommended newsletters
Techpresso gives you a daily rundown of what's happening in tech and read by 300,000+ professionals.
The Deep View The go to daily newsletter for 250k+ founders and knowledge workers who want to stay up to date with artificial intelligence..

💬 Quick question: What's the most time consuming part of your development workflow? Reply and I’ll build a tutorial to automate it.
Thanks for reading
- Sanket