Key Takeaways
- MCP co-creator David Soria Parra's 6 design lessons: stop wrapping CRUD endpoints, use progressive discovery, and choose Skills vs MCP by the problem.
- Claude Code users must redesign tool granularity for agents.
What Changed — MCP's First Year Design Lessons from Anthropic's Co-Creator
David Soria Parra, the MCP co-creator at Anthropic, recently gave a talk distilling the protocol's first year into six hard-won design lessons. These aren't theoretical — they're the mistakes teams keep making, and the corrective patterns the ecosystem needs in year two.
If you're building MCP servers for Claude Code (or any agent), these six lessons will save you from rebuilding the wrong thing.
Lesson 1: Don't Wrap REST as MCP
This is the design mistake every team makes once.
A REST API is structured around resources and CRUD verbs: GET /users, POST /orders, PATCH /documents/:id. That granularity is correct for a frontend developer. It is wrong for an agent.
An agent wants to perform an action — a piece of work the user cares about. "Prepare a customer for onboarding." "Find the contract and check it for risk clauses." Each of those, in CRUD terms, is a sequence of dozens of REST calls the agent has to plan, sequence, and check — wasting context window on ORM work.
Bad version (don't do this):
@server.tool()
def get_user(user_id: str) -> dict: ...
@server.tool()
def create_order(user_id: str, items: list) -> dict: ...
@server.tool()
def patch_document(doc_id: str, fields: dict) -> dict: ...
@server.tool()
def list_permissions(user_id: str) -> list: ...
# ... seventeen more atomic CRUD wrappers
Good version (do this):
@server.tool()
def prepare_user_for_onboarding(user_id: str) -> OnboardingResult:
"""Run the full onboarding checklist: provision account, send welcome
email, set initial permissions, attach to default workspace, audit-log."""
...
@server.tool()
def find_and_review_contract(party: str, period: str) -> ContractReview:
"""Locate the contract, parse it, flag clauses by risk category,
summarize key terms, return a structured review."""
...
@server.tool()
def draft_customer_response(ticket_id: str) -> DraftResponse:
"""Pull the ticket history, the customer's account context, and the
current state of the issue; produce a draft response with citations."""
...
The two servers wrap the same backend. The agent's behavior is not comparable. The first produces a long chain of tool calls with high failure probability. The second is one call, returns a structured result, and the agent moves on.
Shift your thinking: You are no longer designing an interface for a developer to make CRUD calls. You are designing an interface for an agent to perform business operations.
Lesson 2: Progressive Discovery — Don't Dump Every Tool Into Context
An MCP server with thirty tools dumps thirty tool descriptions into context at session start. With multiple servers, that climbs to a hundred. The costs are real:

- The model chooses worse among many tools than few
- Input-token cost per request goes up
- Latency goes up
- Incorrect tool calls increase with confusable options
- Actual data gets squeezed out by tool descriptions never invoked
The fix: progressive discovery. The agent fetches tools as needed, not the full catalog at start. The server presents a small categorized index with two-line descriptions, plus an on-demand expansion mechanism.
For Claude Code users: When connecting multiple MCP servers, audit your tool counts. If any server exposes 20+ flat tools, consider redesigning it with progressive discovery or splitting into focused servers.
Lesson 3: Skills and MCP Are Not Competitors
Anthropic also ships a Skills system. The natural reaction is to ask which wins. The answer: neither. They answer different questions.
Skills are for local, procedural, CLI-utility-driven work: "Take this video file, run it through ffmpeg, put the result in this directory." Low cost to build and run. No auth or audit needed.
MCP is for actions requiring authorization, role-based access control, audit logs, observability, stable contracts with external systems, lifecycle management. Customer data, finances, enterprise systems → MCP.
Decision rule: Use the simplest mechanism that solves the problem. MCP servers are not free to build, run, or maintain. If a Skill works, ship the Skill.
Lesson 4: Enterprise Needs a Gateway
(Full lesson from source: enterprise deployments need an MCP gateway for auth, rate limiting, audit logging, and routing between internal MCP servers. This is the pattern emerging for production deployments.)
Lesson 5: Tools Should Be Discoverable, Not Just Callable
(Full lesson: design for how agents find tools, not just how they call them. Categorization, naming conventions, and descriptions matter more than in traditional APIs.)
Lesson 6: Version Your Tool Contracts
(Full lesson: tool signatures are contracts. Breaking changes break existing agents. Use semantic versioning for your MCP server.)
What It Means For Claude Code Users
If you're building MCP servers for your Claude Code workflow:
- Audit your tools: Are they action-shaped or CRUD-shaped? Refactor any that require the agent to sequence multiple calls to accomplish one business task.
- Check your tool count: If a single server has 15+ tools, implement progressive discovery or split into focused servers.
- Know when to use Skills: For deterministic local procedures (file processing, git operations, build scripts), use Anthropic's Skills system instead of building an MCP server.
Try It Now
- Pick one MCP server you maintain or use frequently.
- List every tool it exposes.
- For each tool, ask: "Is this a business action an agent would ask for, or is this a CRUD endpoint?"
- Refactor any CRUD-style tools into action-shaped tools that compose multiple backend operations.
Example: Instead of get_user, create_onboarding_ticket, assign_workspace, send_welcome_email, expose one tool: onboard_new_user(user_email: str, workspace_id: str) -> OnboardingResult.
Source: dev.to









