By the Octri team · Updated
MCP vs SDK: what each is for, and why you may want both
A well-designed SDK is full of decisions that help an application developer: retry behavior, typed models, pagination helpers and exceptions with recognizable names. An MCP server has a different audience. It has to tell a model which actions exist, when to choose them, and what to do when one fails.
That is why MCP vs SDK is a question about the caller rather than the underlying capability. An SDK and an MCP server can share the same API client; they should not necessarily expose the same surface.
What is the difference between MCP and an SDK?
A developer imports an SDK package and decides which method to call in code. A model receives the MCP tool list through its host and chooses at run time. SDK methods have types and conventional exceptions. MCP tools have JSON Schema arguments, descriptions and tool results that an agent must interpret.
The same cancel_order action might be a Python method that raises OrderAlreadyShipped and an MCP tool that returns an error explaining that shipped orders cannot be cancelled. Both describe the same business rule, but the consumer needs a different presentation.
| Question | SDK | MCP server |
|---|---|---|
| Who chooses the action? | Developer's code | Model, via an AI host |
| How is it installed? | Package pinned in a project | Local server command or remote URL |
| How are inputs described? | Language types and docs | JSON Schema and tool descriptions |
| What represents a failure? | Typed exception or error value | Tool error result, or transport error |
| When does the interface change? | On package upgrades | As the published tool catalog changes |

An MCP server built on an SDK
There is no reason to reimplement pagination, authentication headers and retries in the MCP wrapper when a reliable SDK already provides them. Write the tool against that client and translate the domain-specific result.
I tested this translation with a small local Python SDK-style class. It raised a NotCancellable exception for a shipped order. A thin wrapper converted that into a result with isError: true and the message “shipped order cannot be cancelled.” The test did not run an MCP SDK; it verified the boundary between an application exception and the explanation a model needs.
A simplified pattern looks like this:
class NotCancellable(Exception):
pass
class OrdersClient:
def cancel(self, order_id: str):
order = self.fetch(order_id)
if order["status"] != "pending":
raise NotCancellable("Order already shipped")
return self.post(f"/orders/{order_id}/cancel")
def cancel_order_tool(client: OrdersClient, order_id: str):
try:
return client.cancel(order_id)
except NotCancellable as error:
return {"isError": True, "message": str(error)}An actual MCP server should use its SDK's error-result mechanism rather than returning this illustrative dictionary verbatim. Keep the SDK exception type available to ordinary application code; the tool wrapper exists to make it intelligible to an agent.
How SDKs and MCP meet in coding agents
A coding agent sometimes needs to write a durable integration, not just perform one action. In that situation an SDK is the better output. The agent can use MCP to search API documentation or retrieve an idiomatic SDK example, then incorporate the SDK call into the application's codebase.
Other systems offer a constrained code-execution tool backed by an SDK, which lets an agent perform several operations in a small script without exposing hundreds of individual methods as tools. That can reduce tool-list size, but it raises sandboxing and authorization questions. Limit which SDK capabilities the runtime exposes and keep execution isolated.
This is the place to be careful with the phrase “agents can do anything the SDK can do.” Capability is not permission. If the SDK can delete a whole account, that does not mean the MCP server should present the deletion operation to every assistant.

Versions work differently
SDK versions are dependencies. A project might keep acme-sdk==2.3.1 until it is ready to upgrade. A remote MCP server can update the tool list for every client using that URL, so changes to names and argument schemas need release discipline even if no package changes hands.
Maintain a reviewed change record of renamed, added and removed tools. For a compatibility-breaking change, consider a new tool name or a transitional period rather than silently replacing a field. Clients that cached an older tool definition should fail understandably and have a route to recovery.
When an API needs an SDK, an MCP server or both
If your customers are writing production software, provide an SDK for the languages they use. If they expect assistants to perform tasks across their account, provide a curated MCP server. If they want AI coding agents to build applications against the API, SDKs and API documentation remain important even when you ship MCP.
Use the API as the shared source of truth. Avoid having separate interpretations of a field, an enum or a permission in three places. Automation is valuable here, but differences in audience still justify hand-edited descriptions and examples.
Checklist for an API with an SDK and an MCP server
Verify that both interfaces use the same API contract, that authentication is correct for each caller, and that errors carry enough information for their consumers. Keep SDK package versions discoverable, record changes to MCP tool definitions, and measure the agent-facing context cost. Test language-specific SDK code separately from model tool-selection behavior.
The right test for an SDK is often “Does this compile and behave predictably?” The right test for a tool is often “Does the model choose it for the right task, and can it recover when it fails?”
SDKs and MCP servers with Octri
Octri's SDK generation and MCP Studio are built around the same API description. That helps you make an API available through idiomatic client libraries and agent tools without maintaining duplicate endpoint catalogs.

Keep the final judgment with the interface's user. An SDK method that reads naturally in Go may not make a sensible standalone MCP tool, and a tool description optimized for an agent may not be the documentation a developer needs while debugging an SDK.