AI Extensions: MCP SDK 2.3.0 for Python and TypeScript tightens the edges
A server that quietly accepts a redirect to another host, or an unbounded array of arguments, is trusting more than its author may have meant to.

A server that quietly accepts a redirect to another host, or an unbounded array of arguments, is trusting more than its author may have meant to. The MCP Python and TypeScript SDKs both shipped 2.3.0 on October 2, and several changes in them are about those edges.
The short version
Official projects: modelcontextprotocol/python-sdk (MIT) and modelcontextprotocol/typescript-sdk (license in transition from MIT to Apache-2.0). Both released v2.3.0 on October 2. Observed October 3: Python SDK 24,468 stars, 4,006 forks, last push October 2 22:02:27 UTC; TypeScript SDK 13,504 stars, 2,248 forks, last push October 2 19:24:26 UTC. Stars measure attention, not quality or safety. I read the releases and did not install or run either SDK. ↗
Python SDK 2.3.0
Published October 2 at 22:02:27 UTC and installed with pip install -U mcp, per the release notes. The notes list behaviour changes first: httpx2 2.10.0 or newer is required; a tool with an invalid x-mcp-header annotation now fails at registration instead of being silently dropped from client listings; empty _meta and params are no longer sent on older connections; and an interactive OAuth login no longer counts against request timeouts. New options include max_sse_event_size (default stays 1 MiB per SSE event) and MCPServer(subscriptions=False). ↗
TypeScript SDK 2.3.0
Published October 2 at 17:55:03 UTC. The upgrade notes say a server instance now rejects connect() while already connected, so stateless HTTP servers should create the server and transport per request. HTTP client transports follow a redirect only when it stays on the same origin unless redirectPolicy is set to follow. New opt-in options are maxToolInputElements, which limits array elements and object members in tool arguments, and expectedResource on bearer-token verification, which accepts only tokens issued for this server. The maintainers report a 100 MB single-event tool result dropping from about a minute and 1.7 GB peak memory to under a second and about 0.5 GB. That is their test, not mine. ↗
Before you install: licenses, upkeep, setup
The Python SDK LICENSE file is MIT. The TypeScript SDK LICENSE says the project is moving from MIT to Apache-2.0: new code under Apache-2.0, older contributions without relicensing consent remain MIT, and documentation excluding specifications is CC-BY-4.0, so calling it simply MIT or simply Apache-2.0 would be inexact. Both repositories had pushes within a day of my check, and both shipped the same day, which shows activity and says nothing about fit for your server. For a trial, pin the version, read the upgrade notes for your transport, and test against a disposable server first.
Where the permission lines sit
My analysis: three of these changes narrow what a server or client accepts. A same-origin redirect rule limits where a request can end up, a maximum on tool-input elements limits how much a call can carry, and an audience check ties a token to one server. All three are off or configurable, and none replaces authentication, authorization on each tool, or treating tool results as untrusted content. Raising max_sse_event_size or setting redirectPolicy to follow loosens a limit on purpose, so record why.
A checklist I wrote
The code below is a simplified redirect rule I wrote with invented URLs and ran locally. It allows the same origin and an http to https upgrade on the same host, and rejects another host or port. It is not the SDK implementation: read the transport option and test the real redirect behaviour against a disposable endpoint.
The checklist, in code
from urllib.parse import urlsplit
def origin(url):
u = urlsplit(url)
port = u.port or {"http": 80, "https": 443}[u.scheme]
return (u.scheme, u.hostname, port)
def follow(src, dst):
a, b = origin(src), origin(dst)
if a == b:
return True
# http to https on the same host and default ports is allowed
return a[1] == b[1] and (a[0], b[0]) == ("http", "https") and a[2] == 80 and b[2] == 443
assert follow("https://api.example.test/mcp", "https://api.example.test/v2/mcp")
assert follow("http://api.example.test/mcp", "https://api.example.test/mcp")
assert not follow("https://api.example.test/mcp", "https://other.example.test/mcp")
assert not follow("https://api.example.test/mcp", "https://api.example.test:8443/mcp")
print("redirect policy checks passed")
# Invented URLs and a simplified rule, not the SDK's implementation.
Sources and limits
- https://github.com/modelcontextprotocol/python-sdk
- https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.3.0
- https://github.com/modelcontextprotocol/python-sdk/blob/main/LICENSE
- https://github.com/modelcontextprotocol/typescript-sdk
- https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/v2.3.0
- https://github.com/modelcontextprotocol/typescript-sdk/blob/main/LICENSE