Skip to content
Development
Skill

/mcp-best-practices

Claude Code client-side cap on MCP tool result size, referenced in the result-size budget guidance

From plugin
tenequm-skills
3630 skills
Install
$ npx -y skills add tenequm/skills --skill mcp-best-practices --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/mcp-best-practices

Context preview

The summary Claude sees to decide when to auto-load this skill.

Claude Code client-side cap on MCP tool result size, referenced in the result-size budget guidance

SKILL.md

mcp-best-practices.SKILL.md
name: mcp-best-practices
description: Build, harden, and debug production MCP servers with the TypeScript SDK. Use when writing or reviewing an MCP server - transports, tool schemas, errors, OAuth, token bloat, SDK migrations, MCP Apps, Registry. Assumes a server already exists.
metadata:
  version: "1.2.1"
  categories: "development, integrations"
  topics: "mcp, typescript-sdk, tool-design, transports, server-hardening"
  upstream: "@modelcontextprotocol/sdk@1.30.0, @modelcontextprotocol/server@2.0.0, @modelcontextprotocol/ext-apps@2.0.0, modelcontextprotocol-spec@2026-07-28"
  openclaw:
    homepage: https://github.com/tenequm/skills/tree/main/skills/mcp-best-practices
    emoji: "🔌"
    envVars:
      - name: MAX_MCP_OUTPUT_TOKENS
        required: false
        description: Claude Code client-side cap on MCP tool result size, referenced in the result-size budget guidance

MCP Best Practices

Decision reference for building production MCP servers with the TypeScript SDK. Not a tutorial - assumes you already have a working server and need to make it correct, fast, and secure.

Quick Reference

| Component | Current | Notes | |-----------|---------|-------| | Spec (released) | **2026-07-28** ([specification](https://modelcontextprotocol.io/specification/latest)) | Stateless/sessionless overhaul - see "Spec 2026-07-28" below and `references/spec-2026-07-28.md` | | Spec (still deployed) | **2025-11-25** | What most shipped clients and servers actually speak today; the v2 SDK's default | | TS SDK (current) | **v2.0.0** (2026-07-27), nine packages in lockstep: `/server`, `/client`, `/core`, `/hono`, `/express`, `/node`, `/fastify`, `/codemod`, `/server-legacy` | Speaks 2025-era by default; 2026-07-28 is opt-in | | TS SDK (legacy) | **v1.30.0** (`@modelcontextprotocol/sdk`) | Bug + security fixes for >=6 months after v2 GA; source on the [`v1.x` branch](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x) | | JSON Schema | **2020-12** default (2019-09 / draft-07 accepted since v2.0.0) | - | | Transport | **Streamable HTTP** (remote), **stdio** (local) | SSE + WebSocket removed in v2 | | Extensions | **MCP Apps** (Stable, SEP-1865), **Auth Extensions** (official), **Tasks** ([ext-tasks](https://github.com/modelcontextprotocol/ext-tasks)) | Domain-specific WGs | | Registry | **Preview** with v0.1 API freeze since 2025-10-24 ([registry](https://modelcontextprotocol.io/registry/about)) | GA pending |

**v2 imports** (current):

import { McpServer } from "@modelcontextprotocol/server";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/server";
import { ProtocolError, ProtocolErrorCode } from "@modelcontextprotocol/core";

**v1 imports** (legacy line, still widely deployed):

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

The Two Eras

The most decision-relevant fact after the 2026-07-28 release: **upgrading to SDK v2.0.0 does not move you to the new spec.** A hand-constructed `Client`/`Server`/`McpServer` keeps speaking the 2025-era protocol it was written for.

Every revision from `2024-10-07` through `2025-11-25` opens with `initialize` and shares one wire behavior - the SDK calls that family **legacy**. `2026-07-28` starts the **modern** era: no `initialize`, a `server/discover` advertisement instead, a `_meta` envelope on every request. Selection is explicit:

| `versionNegotiation.mode` | Behavior | |---|---| | absent / `'legacy'` | The 2025 `initialize` handshake, byte for byte. No probe. **This is the default.** | | `'auto'` | Probe with `server/discover`; fall back to `initialize` against a 2025-only server | | `{ pin: '2026-07-28' }` | That revision or nothing - a pin never falls back |

Build new servers on the 2025-era wire unless you control both ends. The stateless design guidance throughout this skill is what makes the eventual era switch cheap.

Tooling: [SDK docs](https://ts.sdk.modelcontextprotocol.io) ([v2](https://ts.sdk.modelcontextprotocol.io/v2/)); [MCP Inspector](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector), which **connects as `legacy` by default** (see "Testing Against Each Era" in `references/spec-2026-07-28.md`); the [conformance suite](https://github.com/modelcontextprotocol/conformance); and the [`mcp-server-dev` plugin](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-server-dev) for scaffolding.

Server Setup

Transport Decision

| Scenario | Transport | Key Config | |----------|-----------|------------| | Remote, stateless (K8s, CF Workers) | `WebStandardStreamableHTTPServerTransport` | `sessionIdGenerator: undefined`, `enableJsonResponse: true` | | Remote, stateful (long tasks, SSE) | `WebStandardStreamableHTTPServerTransport` | `sessionIdGenerator: () => randomUUID()` | | Local CLI / Claude Desktop | `StdioServerTransport` | Default | | Legacy SSE clients | SSE removed in v2 - migrate to Streamable HTTP | - |

Stateless Pattern (recommended for remote deployment)

Per-request server+transport creation is the canonical pattern. Maintainer @ihrpr confirms: "each transport should have an instance of MCPServer" ([#343](https://github.com/modelcontextprotocol/typescript-sdk/issues/343)). Sharing instances leaks cross-client data (GHSA-345p-7cg4-v4c7).

app.post("/mcp", async (c) => {
  const server = new McpServer({ name: "my-server", version: "1.0.0" });
  // Register tools, resources, prompts...
  registerTools(server);

  const transport = new WebStandardStreamableHTTPServerTransport({
    sessionIdGenerator: undefined,   // stateless - no session tracking
    enableJsonResponse: true,        // JSON responses, no SSE streaming
    // Origin/Host checking is OFF unless you turn
Read more
Ships withtenequm-skills

Claude Code skills for founders, developers, and web3 builders. This repository publishes reusable skill folders under skills//, ships stable bundle downloads through GitHub Releases, and publishes changed skills to ClawHub.

Get the whole plugin
Stats
36
Stars
1
Forks
Active
Maintenance
Python
Language
MIT
License
3d ago
Last commit
10mo ago
Created

Repo: tenequm/skills

Other skills on tenequm-skills.