Workspace IndexDev Notes › MCP from three sides — build one, consume one, wrap an agent as one

#54PoC

MCP from three sides — build one, consume one, wrap an agent as one

The 2026-07-28 revision drops the session handshake, so an MCP server becomes an ordinary stateless HTTP service — deployable to serverless and edge, and authorized like any enterprise API. That protocol change is underneath the other two positions, which is why it should be done first.

Build one narrow tool server against 2026-07-28 from the start rather than porting a 2025-11-25 one, deploy it to Cloud Run, and connect it to Claude. Then the client side: hold a Zapier MCP connection in a server-side route (URL plus auth token, never exposed to the browser) and forward tool calls through the Anthropic API's native MCP connector or a generic client via @modelcontextprotocol/sdk — scoped to an explicit allowlist of safe actions rather than handing an agent unrestricted access to real accounts. The framework question is a 30-minute skim afterwards: whether an existing subagent can be wrapped in Google ADK and served over MCP. Spec: blog.modelcontextprotocol.io, release candidate 2026-07-28.

Why

The reason to build one now rather than a year ago is that the shape of the answer changed. Until this revision an MCP server was a stateful conversation: an initialize/initialized handshake, an Mcp-Session-Id header, and a server that had to remember which client it was talking to. The 2026-07-28 revision removes both — every request is self-contained, with protocol version, client identity and capabilities travelling in _meta, Streamable HTTP requests routed by Mcp-Method and Mcp-Name headers, and list and resource-read results cacheable.

What that changes practically is deployment. A stateless request/response service runs on serverless or edge without sticky sessions, which is the difference between an MCP server is a process I keep running and an MCP server is a function I deploy.

The second change carries more weight for real work. Authorization now aligns with deployed OAuth 2.0 and OIDC practice, so pointing a server at an enterprise identity provider like Entra or Okta stops being a workaround. That is the half that decides whether an MCP server may ever touch company data, and it is why building against the new spec is not the same exercise as building against the old one. The adoption figure is context rather than argument: SDK downloads passed 400 million a month, roughly 4× this year.

The three positions are the same protocol from different seats, and the ordering is the useful part. Building a server is the protocol question. Consuming Zapier's — 8,000+ app integrations exposed as tools — is the client question, and it is where the security decision lives rather than the interesting engineering. Serving an agent as an MCP server, which Google's ADK Python 2.5 release added alongside sandboxed code execution on Cloud Run and a fresh ADK Go, is the framework question. Doing the protocol one first turns the other two into wrapper exercises instead of two unknowns at once.

One caution before building: Roots, Sampling and Logging are deprecated with documented replacements and a minimum twelve-month removal window, and Tasks is an explicit breaking change — poll-based tasks/get, tasks/update, cooperative tasks/cancel. Porting an old server means learning the old model twice.

How it works

Three seats, one protocol

Seat The question What it decides Do it
Build a server Protocol — what does a request carry now that there is no session? Whether the thing can be deployed and authorized at all First
Consume a server (Zapier) Client — how do I hold a connection and constrain what it may do? Blast radius, not architecture Second
Serve an agent as a server (ADK) Framework — can an existing subagent be wrapped? Reuse A 30-minute skim, last

What actually changed on 2026-07-28

Before After
Session initialize/initialized handshake, Mcp-Session-Id None — every request self-contained
Identity and capabilities Negotiated once Carried in _meta per request
Routing Session-scoped Mcp-Method / Mcp-Name headers
list / resource-read Per-session Cacheable
Authorization Ad hoc OAuth 2.0 / OIDC — Entra, Okta
Deployment A process you keep running A function you deploy
Tasks Breaking change: tasks/get, tasks/update, tasks/cancel
Roots, Sampling, Logging Current Deprecated, 12-month minimum removal window

Three things worth verifying by doing rather than reading

  1. That a cold-started serverless instance can serve a request with no prior state at all. That is the whole claim of the stateless core, and it either holds on a real cold start or it does not.
  2. What _meta must actually carry for a client to work without the handshake — the part a spec summary never makes concrete enough to implement from.
  3. Whether cacheability of list and resource-read survives a real deployment, since that is where the stateless design either pays for its extra per-request payload or does not.

The authorization half deserves the most time: put the server behind an OAuth/OIDC provider and walk the token path end to end, because the approval path for company data is standardised now is a claim that is either true in an hour or false all week.

The client side, where the decision is a security decision

A server-side route holds the Zapier MCP connection — URL and auth token never reaching the browser — and either forwards tool calls through the Anthropic API's native MCP connector or acts as a generic client via @modelcontextprotocol/sdk, listing available tools and executing whichever the model selects. Scope it to an explicit allowlist (e.g. send email to self) rather than handing an agent unrestricted access to real accounts. That allowlist is the entire engineering decision; everything else is plumbing, and the-harness-not-the-model is where the general version of it lives.

The framework side, in one paragraph

Google's Agent Development Kit release adds sandboxed code execution isolation on Cloud Run, the ability to serve an agent as an MCP server, and an improved Live API; ADK Go shipped alongside. The 30-minute question is whether an existing subagent can be wrapped in ADK and called from Claude over MCP. Once the protocol question is answered that is a wrapper exercise, which is exactly why it is last.

The fourth seat — the gateway between the agent and the tool

This card has three seats: build a server, consume one, wrap an agent as one. A fourth has appeared, and it is where the attention moved once the protocol stopped being the open question. With the MCP npm SDK at roughly 196M downloads a month, whether to speak MCP is settled. What is contested is the layer above it: the gateway that sits between the agent and everything it calls.

Three things currently occupying that layer, and they are not the same product:

What it actually sells
LiteLLM One API surface over 100+ model providers, with per-call cost tracking — a routing and billing layer
TrueFoundry Per-agent identity and spending caps — an authorization layer
vLLM The default once the model is hosted rather than called — an inference layer

The shape is familiar: this is the reverse proxy, arriving for agents. Every line in that table is something you would otherwise write badly yourself — a retry policy, a key vault, a budget, an audit log — and the reason it wants to be a separate box is that an agent cannot be trusted to enforce a limit on itself. That is the same argument as the-harness-not-the-model, and agentic-intent-veto is the warning about which limit to pick: a spending cap is the wrong invariant if what you actually care about is what the agent is for.

This lands directly on the client seat above, where the conclusion was that consuming an MCP server is a security decision — hold the connection server-side, never let the URL and token reach the browser. A gateway is that answer, productised. So the question to ask before adopting one is which of the four it is actually giving you — routing, identity, cost, or observability — because they are sold as a single product and needed one at a time, and the cheapest version of three of them is a server-side route you already know how to write.

← All Dev Notes · Workspace Index · Top ↑

MCP 를 세 방향에서 — 만들고, 쓰고, 에이전트를 그것으로 감싸기

2026-07-28 개정판이 세션 핸드셰이크를 없앴습니다. MCP 서버가 평범한 무상태 HTTP 서비스가 되어 서버리스·엣지에 배포되고, 여느 엔터프라이즈 API처럼 인가됩니다. 그 프로토콜 변화가 나머지 두 위치 밑에 깔려 있고, 그래서 이것부터 해야 합니다.

2025-11-25 서버를 포팅하지 말고 처음부터 2026-07-28 위에 좁은 툴 서버 하나를 만들어 Cloud Run 에 배포하고 Claude 에 연결합니다. 그다음 클라이언트 쪽: Zapier MCP 연결(URL + 인증 토큰, 브라우저에 절대 노출 금지)을 서버 라우트가 들고, Anthropic API 의 네이티브 MCP 커넥터나 @modelcontextprotocol/sdk 범용 클라이언트로 툴 호출을 전달합니다 — 에이전트에게 실제 계정 무제한 접근을 주는 대신 안전한 액션만 명시적 허용 목록으로. 프레임워크 질문은 그 뒤 30분 훑기입니다 — 기존 서브에이전트를 Google ADK 로 감싸 MCP 로 서빙할 수 있는가. 스펙: blog.modelcontextprotocol.io, 릴리스 후보 2026-07-28.

1년 전이 아니라 지금 만들 이유는 답의 모양이 바뀌었기 때문입니다. 이번 개정 전까지 MCP 서버는 상태 있는 대화였습니다 — initialize/initialized 핸드셰이크, Mcp-Session-Id 헤더, 그리고 어느 클라이언트와 말하는 중인지 기억해야 하는 서버. 2026-07-28 개정판이 둘 다 없앱니다 — 모든 요청이 자기완결적이고, 프로토콜 버전·클라이언트 신원·능력이 _meta 로 실려 가며, Streamable HTTP 요청은 Mcp-Method·Mcp-Name 헤더로 라우팅되고, list 와 resource-read 결과는 캐시 가능합니다.

실무적으로 바뀌는 것은 배포입니다. 무상태 요청/응답 서비스는 스티키 세션 없이 서버리스나 엣지에서 돕니다. MCP 서버는 내가 계속 띄워 두는 프로세스MCP 서버는 내가 배포하는 함수 의 차이입니다.

두 번째 변화가 실제 업무에는 더 무겁습니다. 인가가 배포된 OAuth 2.0·OIDC 관행과 정렬되어, Entra 나 Okta 같은 엔터프라이즈 아이덴티티 공급자에 서버를 붙이는 것이 우회책이기를 그만둡니다. MCP 서버가 회사 데이터에 닿아도 되는지를 결정하는 절반이고, 그래서 새 스펙 위에서 만드는 것이 옛 스펙 위에서 만드는 것과 같은 연습이 아닙니다. 채택 수치는 논거가 아니라 맥락입니다 — SDK 다운로드가 월 4억 건을 넘었고, 올해 약 4배입니다.

세 위치는 같은 프로토콜을 다른 자리에서 본 것이고, 쓸모 있는 부분은 순서입니다. 서버를 만드는 것은 프로토콜 질문입니다. Zapier 의 것을 쓰는 것 — 8,000개 이상 앱 연동을 툴로 노출 — 은 클라이언트 질문이고, 흥미로운 엔지니어링보다 보안 결정이 사는 자리입니다. 에이전트를 MCP 서버로 서빙하는 것은 — Google ADK Python 2.5 릴리스가 Cloud Run 샌드박스 코드 실행 격리·ADK Go 신규 릴리스와 함께 추가한 것 — 프레임워크 질문입니다. 프로토콜 질문을 먼저 풀면 나머지 둘이 두 개의 미지수가 아니라 래퍼 작업이 됩니다.

만들기 전 주의 하나: Roots·Sampling·Logging 은 대체재가 문서화된 채 폐기 예정이고 최소 12개월 제거 유예가 있으며, Tasks 는 명시적 파괴적 변경입니다 — 폴링 기반 tasks/get, tasks/update, 협조적 tasks/cancel. 옛 서버를 포팅하면 옛 모델을 두 번 배우게 됩니다.

동작 방식

세 자리, 하나의 프로토콜

자리 질문 무엇을 결정하나 순서
서버를 만든다 프로토콜 — 세션이 없는데 요청은 무엇을 나르나? 애초에 배포·인가가 되는지 첫째
서버를 쓴다(Zapier) 클라이언트 — 연결을 어떻게 들고, 무엇까지 허용하나? 아키텍처가 아니라 폭발 반경 둘째
에이전트를 서버로 서빙(ADK) 프레임워크 — 기존 서브에이전트를 감쌀 수 있나? 재사용 30분 훑기, 마지막

2026-07-28 에 실제로 바뀐 것

이전 이후
세션 initialize/initialized 핸드셰이크, Mcp-Session-Id 없음 — 모든 요청이 자기완결
신원·능력 한 번 협상 요청마다 _meta 로 운반
라우팅 세션 범위 Mcp-Method / Mcp-Name 헤더
list / resource-read 세션별 캐시 가능
인가 임기응변 OAuth 2.0 / OIDC — Entra, Okta
배포 계속 띄워 두는 프로세스 배포하는 함수
Tasks 파괴적 변경: tasks/get, tasks/update, tasks/cancel
Roots·Sampling·Logging 현행 폐기 예정, 최소 12개월 유예

읽기보다 해서 확인할 값이 있는 셋

  1. 콜드 스타트된 서버리스 인스턴스가 사전 상태 0으로 요청을 처리하는가. 무상태 코어의 주장 전부이고, 실제 콜드 스타트에서 성립하거나 아니거나 둘 중 하나입니다.
  2. 핸드셰이크 없이 클라이언트가 동작하려면 _meta 가 실제로 무엇을 날라야 하는가 — 스펙 요약으로는 구현할 만큼 구체적이 되지 않는 부분입니다.
  3. list·resource-read 의 캐시 가능성이 실제 배포에서 살아남는가. 무상태 설계가 요청당 늘어난 페이로드 값을 하는지 못 하는지가 거기서 갈립니다.

인가 절반에 시간을 가장 많이 줄 값이 있습니다 — 서버를 OAuth/OIDC 공급자 뒤에 두고 토큰 경로를 끝까지 걸어 봅니다. 회사 데이터에 대한 승인 경로가 이제 표준화됐다 는 주장은 한 시간 안에 참이거나, 일주일 내내 거짓입니다.

클라이언트 쪽, 결정이 보안 결정인 자리

서버 라우트가 Zapier MCP 연결을 듭니다 — URL 과 인증 토큰은 브라우저에 절대 도달하지 않고 — 그리고 Anthropic API 네이티브 MCP 커넥터로 툴 호출을 전달하거나 @modelcontextprotocol/sdk 로 범용 클라이언트가 되어, 사용 가능한 툴을 나열하고 모델이 고른 것을 실행합니다. 명시적 허용 목록으로 범위를 좁힙니다(예: 내게 이메일 보내기) — 에이전트에게 실제 계정 무제한 접근을 주는 대신. 그 허용 목록이 엔지니어링 결정 전부이고, 나머지는 배관입니다. 그 일반형은 the-harness-not-the-model 에 있습니다.

프레임워크 쪽, 한 문단

Google Agent Development Kit 릴리스는 Cloud Run 샌드박스 코드 실행 격리, 에이전트를 MCP 서버로 서빙, Live API 개선을 추가했고 ADK Go 도 함께 나왔습니다. 30분 질문은 기존 서브에이전트를 ADK 로 감싸 Claude 에서 MCP 로 부를 수 있는가입니다. 프로토콜 질문에 답한 뒤라면 이건 래퍼 작업이고, 정확히 그래서 마지막입니다.

네 번째 자리 — 에이전트와 툴 사이에 앉는 게이트웨이

이 카드에는 자리가 셋입니다: 서버를 만든다, 서버를 쓴다, 에이전트를 서버로 감싼다. 네 번째가 생겼고, 프로토콜이 더 이상 열린 질문이 아니게 된 뒤 관심이 옮겨간 자리입니다. MCP npm SDK가 월 약 1억 9,600만 다운로드인 지금, MCP를 쓸지 말지는 끝난 얘기입니다. 다투는 곳은 그 층 — 에이전트와 그가 호출하는 모든 것 사이에 앉는 게이트웨이입니다.

지금 그 층을 차지한 셋, 그리고 이들은 같은 제품이 아닙니다:

실제로 파는 것
LiteLLM 100개 이상 LLM 제공자 위의 단일 API 표면 + 호출별 비용 추적 — 라우팅·과금 계층
TrueFoundry 에이전트별 신원과 지출 한도 — 인가(authorization) 계층
vLLM 모델을 호출하는 대신 직접 호스팅할 때의 기본값 — 추론 계층

모양은 낯익습니다: 에이전트용 리버스 프록시가 도착한 것입니다. 표의 각 줄은 안 그러면 자기가 어설프게 짜게 될 것들입니다 — 재시도 정책, 키 보관소, 예산, 감사 로그. 그리고 이게 별도 박스가 되려는 이유는 하나입니다: 에이전트에게 자기 한도를 스스로 지키라고 맡길 수 없기 때문. the-harness-not-the-model 과 같은 논지이고, 어떤 한도를 고를지에 대한 경고는 agentic-intent-veto 에 있습니다 — 정작 중요한 게 에이전트가 무엇을 위해 움직이는가라면, 지출 한도는 틀린 불변량입니다.

이건 위의 클라이언트 자리에 그대로 내려앉습니다. 거기 결론은 MCP 서버를 소비하는 일이 보안 결정이라는 것이었습니다 — 연결은 서버 사이드에 두고, URL과 토큰은 브라우저에 절대 내보내지 않는다. 게이트웨이는 그 답을 제품화한 것입니다. 그래서 도입 전에 물을 것은 넷 중 무엇을 실제로 주는가 — 라우팅인가, 신원인가, 비용인가, 관측가능성인가 — 입니다. 이들은 하나의 제품으로 팔리지만 필요해지는 시점은 하나씩이고, 셋 중 대부분의 가장 싼 버전은 이미 짤 줄 아는 서버 사이드 라우트 하나이기 때문입니다.

← 전체 개발 노트 · 워크스페이스 인덱스 · 맨 위 ↑