An agent that can read your repository is a demo. An agent that can deploy to production is infrastructure — and infrastructure has to answer questions a demo never faces. Which agent triggered this deploy? What credentials did it hold, and for how long? Where is the log that proves it? When a rollout goes sideways at 2 a.m., "the model called a tool" is not an incident report.
Here is the uncomfortable arithmetic of a deploy-authority MCP server: the deploy tool itself is fifty lines of code wrapped around an API call. Everything around it — authentication, per-agent credential scoping, audit logging, telemetry, safe handling of long-running rollouts — is the other ninety-five percent. That ratio is exactly what Golf, a production-oriented MCP server framework built on FastMCP 4.0, is trying to invert. Its pitch is a clean split: you write the agent logic, the framework owns the server infrastructure.
This post takes that pitch seriously and tests it against the hardest realistic case — an MCP server whose tools can deploy and roll back production services. What concretely stops being your code, what the MCP 2026-07-28 protocol changes about the answer, and what no framework can build for you.
What Golf actually is
Golf is a Python framework for building MCP servers with minimal boilerplate, published as golf-mcp on PyPI. The core idea is convention over configuration: you define a server's capabilities — tools, prompts, and resources — as plain Python files in a conventional directory layout, and Golf discovers, parses, and compiles them into a runnable MCP server. A minimal project looks like this:
my-deploy-server/
├── golf.json # server name, port, transport, telemetry
├── auth.py # JWT, OAuth server, API key, or dev-token config
└── tools/
├── deploy.py # the deploy tool
└── rollback.py # the rollback toolTwo facts about Golf's foundations matter more than anything else in its feature list. First, it targets FastMCP 4.0 and the MCP 2026-07-28 protocol, with FastMCP's compatibility mode negotiating down to legacy clients. Second, since v0.2.0, authentication lives in a dedicated auth.py using explicit config objects — JWTAuthConfig, OAuthServerConfig, StaticTokenConfig — where Golf can act as a full OAuth 2.0 authorization server, validate JWTs with issuer and audience binding, or mint development tokens for local iteration. That auth.py file is the single biggest thing that separates a framework-built server from a hand-rolled one: auth stops being middleware you wrote and becomes configuration you declare.
The framework ships with the rest of the production checklist too: automatic OpenTelemetry integration, a debugger, a runtime, and built-in utilities for LLM interactions. golf run starts the compiled server with telemetry on; golf telemetry disable turns the framework's own usage reporting off. The point is not that any one of these is exotic — it is that none of them is code you write.
The split: what stops being your code
For a deploy-authority server, the framework-vs-platform boundary lands roughly like this:
| Requirement | Owner | How |
|---|---|---|
| Tool/resource/prompt plumbing | Golf + FastMCP | Auto-discovery compile from tools/ files |
| Transport and session handling | FastMCP 4.0 | Stateless-core Streamable HTTP per MCP 2026-07-28, legacy compat mode |
| Caller authentication | Golf auth.py | JWT with issuer/audience binding, OAuth server mode, dev tokens |
| Distributed tracing and metrics | Golf + FastMCP | Native OpenTelemetry spans per tool call, with auth context attributes |
| Local debugging and run loop | Golf runtime | golf run, debugger, golf.json build settings |
| Tool semantics (what "deploy" means) | You | Your code against your platform API |
| Per-agent credential scoping | You | Short-lived, least-privilege tokens per agent identity |
| Deploy API surface | You | Services, deploys, env vars, rollback endpoints |
| Audit log ("which agent changed what") | You | Append-only record of every mutating call |
| Approval policy for destructive tools | You | Human-in-the-loop gates on rollback/prod deploy |
The top half of that table is the framework's value proposition, and it is genuinely large: transport negotiation, auth verification, and telemetry are each a week of careful work to build and an ongoing liability to maintain. FastMCP 4's native OpenTelemetry instrumentation — spans for every tool call, resource read, and prompt render, carrying component, session, and auth-context attributes — means a deploy server gets request-level tracing without importing a single observability library. Telemetry modes (native, propagation_only, off via FASTMCP_TELEMETRY_MODE) let the same server run fully instrumented in production and silent in tests.
But notice what the bottom half has in common: every item is a policy decision about authority, not a mechanism. Frameworks ship mechanisms. Authority — who may do what, with whose credentials, recorded where — is always yours. The rest of this post is about the two halves: first why the protocol itself just made the top half more valuable, then what the bottom half concretely requires.
Why the 2026-07-28 spec matters for a deploy server
Golf targets the MCP 2026-07-28 protocol deliberately, and three of that spec's changes land directly on a server whose tools mutate production.
Stateless core: any instance can take the deploy call. The spec removes protocol-level sessions and the Mcp-Session-Id header from the Streamable HTTP transport, along with the initialize handshake — every request now carries its protocol version and client capabilities in its own _meta field, and servers that need cross-call state mint explicit handles passed as ordinary tool arguments. The official rationale is that any server instance behind a load balancer can handle a request without shared storage. For a deploy server, that is not an abstract scaling story: deploy and rollback calls become horizontally scalable and serverless-deployable by construction, instead of requiring sticky sessions to the instance that "knows" the agent. If your deploy tool needs multi-step state, the spec's answer is a server-minted handle, not a connection — which is also exactly how a deploy ID already works.
Stricter OAuth/OIDC: enterprise identity stops being optional. Authorization now mandates iss parameter validation against the recorded issuer (per RFC 9207, blocking authorization-server mix-up attacks), requires explicit application_type in client registration so desktop-CLI localhost redirects can't collide with web flows, binds client credentials to the authorization server that issued them, and deprecates Dynamic Client Registration in favor of Client ID Metadata Documents. The direction is unmistakable: the protocol is hardening toward enterprise identity providers like Entra and Okta. A deploy server that only ever faces one developer's laptop can ignore this. A deploy server that faces a team's agents — each with its own identity — cannot, because "which agent" starts at "which issuer vouches for this token."
Tasks becomes a versioned extension: long work gets a pollable handle. Long-running operations moved out of the core spec into the io.modelcontextprotocol/tasks extension, rebuilt around polling (tasks/get) plus tasks/update for clients to feed in extra input. A production deploy is the canonical long-running tool call: it takes minutes, it streams progress, and the caller may disconnect. Under the new model, deploy returns a task handle and the agent polls — a far better fit than holding a single tool call open for nine minutes, and a cleaner contract for "the deploy is still running; here is how to check on it." The catch is that extension support is now opt-in on both ends, so a deploy server must declare and negotiate it rather than assuming every client speaks Tasks.
What no framework gives you
The bottom half of the table is where deploy servers are won or lost. Three items deserve more than a row.
Short-lived, per-agent credential scoping. Golf's own documentation states a rule every deploy server must internalize: JWT authentication requires an audience so tokens are bound to the MCP resource, and an inbound MCP bearer token must never be forwarded to an upstream API — use a separate upstream credential or a standards-based token exchange/delegation flow. The reason is blast radius. If the token that authenticates "agent X called tool Y" is the same token that can push to production, then every tool call carries production authority, and any confused-deputy or token-leak path becomes a deploy path. The correct shape is two tokens: a short-lived, audience-bound token identifying the agent to the MCP server, exchanged server-side (OAuth Token Exchange, RFC 8693, is the standard mechanism the MCP authorization spec points at) for a least-privilege, short-lived upstream credential scoped to exactly the operation — deploy service A to staging, not "administer the platform." No framework can define that scope for you, because only you know what your deploy API can do.
A Render-compatible deploy API surface. The MCP tools are a thin skin over a real platform API, and that API needs at minimum: services (create, inspect, configure), deploys (trigger from a git SHA, stream status), environment variables (scoped per service and environment), and rollback (to a previous known-good deploy, as a first-class operation, not "deploy the old SHA and hope"). Modeling it on the Render API's shape is a deliberate choice: agents — and the humans supervising them — benefit when the operations vocabulary matches a service model they already understand, and a Render-compatible surface keeps migration paths open in both directions. The framework owns how the tool is invoked; you own what it invokes, including idempotency (replayed deploy calls must not double-deploy) and safe defaults (production deploys gated, preview deploys open).
An append-only audit log that answers "which agent changed what." Telemetry tells you a tool was called and how long it took; an audit log tells you who authorized a production change and lets you prove it later. Every mutating tool call should append an immutable record: agent identity, issuer, tool name and arguments, upstream credential scope, approval decision and approver, result, and timestamp. Production agent checklists already recommend pinning MCP servers to a known-good tool-definition hash with re-approval required on change, plus OAuth issuer validation on every client — the audit log is what makes those controls verifiable after the fact instead of aspirational. When the postmortem asks "who rolled back payments at 2 a.m.," the answer should be one query, not a reconstruction from scattered spans.
These three are also where the "human approval console" belongs: destructive tools (production deploy, rollback, env-var changes touching secrets) should route through an explicit approval step with a policy engine in front and the audit log behind. Frameworks give you the tool call; the decision to let it through is platform policy.
The framework era of agent infrastructure
A year ago, shipping an MCP server meant owning the whole stack: transport quirks, session state, hand-rolled auth, and whatever logging you remembered to add. Golf on FastMCP 4.0 marks the moment that stack became a framework concern — declare your tools, configure auth, get telemetry and a debugger for free, speak the current protocol with legacy fallback handled. That is real progress, and for read-heavy servers (docs, search, repo context) it may be nearly the whole job.
But a deploy-authority server is where the framework's boundary becomes visible, and the visibility is useful: everything Golf takes off your plate is mechanism, and everything left on it is authority. Credential scoping, the deploy API, the audit log, the approval gate — those are not gaps in the framework. They are the platform, and they always were. The win is that you now get to spend your engineering time on them instead of on session headers.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with a Render-compatible API surface that agents can operate. Star the repo on GitHub or deploy your first app today.
Sources
- golf-mcp/golf — Production-Ready MCP Server Framework (FastMCP 4.0, MCP 2026-07-28, auth/telemetry/debugger/runtime)
- golf-mcp on PyPI — auto-discovery compile of tools, prompts, and resources
- FastMCP v4.0.0 "Four Real" release and native OpenTelemetry telemetry docs — per-tool spans with auth context, telemetry modes
- MCP 2026-07-28 changelog and announcement via Katsuya Ds' spec analysis — stateless core, stricter OAuth/OIDC, versioned Tasks/Apps extensions
- Arcade: multi-user AI agent auth in 2026 — OAuth 2.1/OIDC, RFC 8707 resource indicators, RFC 8693 token exchange
- Agentic AI production deployment checklist — tool-definition hash pinning, OAuth issuer validation, audit logs



