Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(typescript): scaffold @mcp-use/server v2 package (MCP-2601)#1832

Draft
khandrew1 wants to merge 5 commits into
v2from
v2-server-scaffold
Draft

feat(typescript): scaffold @mcp-use/server v2 package (MCP-2601)#1832
khandrew1 wants to merge 5 commits into
v2from
v2-server-scaffold

Conversation

@khandrew1

@khandrew1 khandrew1 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Greenfield rebuild of the server SDK as @mcp-use/server, built directly on the official @modelcontextprotocol/[email protected] (stateless 2026-07-28 protocol only — legacy clients are rejected) and Hono. packages/server/SPEC.md is the working contract — API-shape decisions, deltas vs. the old package, and phase scoping live there.

Package

  • MCPServer with tool() / resource() / resourceTemplate() / prompt() registration, replayed per request; registration is frozen at listen()/getHandler()
  • Raw SDK result shapes (CallToolResult, ReadResourceResult, GetPromptResult) — no framework response helpers
  • Compile-time enforcement: tools with an outputSchema must return matching structuredContent or isError: true (pinned in tests/type-level.test.ts, incl. non-object schema roots per the 2026 wire)
  • Input schemas via Standard Schema (StandardSchemaWithJSON): zod v4, ArkType, Valibot — zod is a devDep only
  • RFC 6570 template-variable inference for resource templates
  • Secure-by-default serving: listen() binds 127.0.0.1 with Host/Origin validation; public binds are an explicit opt-in
  • Examples: Vercel (serverless getHandler()) and Railway (long-lived listen()), each verified end-to-end; vercel example carries the smoke test

Workspace

  • pnpm workspace + root tsconfig registration for the new package
  • Scoped lint gates in eslint.config.js: tsdoc/syntax + jsdoc/require-jsdoc so every export in the package carries strict TSDoc (feeds the generated API reference)
  • ⚠️ Also deletes the old repo-level CLAUDE.md files (root, docs/, python, typescript, cli) in favor of per-package docs — flagging since it touches paths outside the new package

Private during development; the changeset ships no releases.

Test plan

  • pnpm typecheck (tsc over src + tests; type-level contract tests enforced here)
  • pnpm vitest run — 3 files, 29 tests passing (server behavior, mounting, type-level)
  • eslint clean on the package (TSDoc gates active)
  • Vercel example smoke test exercises initialize → tools/call → resources/read → prompts/get over the wire

Greenfield v2 server SDK built on @modelcontextprotocol/[email protected]
(stateless 2026-07-28 protocol) and Hono. SPEC.md in the package is the
working contract: constructor-only config, raw SDK result shapes (no response
helpers), compile-time structuredContent enforcement, Standard Schema inputs
(zod v4 / ArkType / Valibot), secure-by-default listen(). Ships with
type-level contract tests, an end-to-end smoke test, and Vercel/Railway
example deployments. Private during development — no releases.

Workspace changes: pnpm workspace + root tsconfig registration, scoped
TSDoc/jsdoc lint gates in eslint.config.js, and removal of the old
repo-level CLAUDE.md files in favor of per-package docs.

Claude-Session: https://claude.ai/code/session_01B59sx2QJ6bBBwMevCCqkr4
@socket-security

socket-security Bot commented Jul 2, 2026

Copy link
Copy Markdown

@socket-security

socket-security Bot commented Jul 2, 2026

Copy link
Copy Markdown

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

const data = { rolls, total };
// Tools with an outputSchema return the payload twice: machine-readable
// structuredContent plus a text serialization for content-only clients.
return {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we said this is done by the sdk no?

description: "Static metadata about this example server",
},
async (uri) => ({
contents: [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we sure the agent has an easier time to return this than json(obj) ?

);

const port = Number(process.env.PORT ?? 3000);
const started = await server.listen(port);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's just model is as await server.listen() => default 3000, checks internally for --port or PORT env

// Origin validation uses the same port-agnostic hostname allowlist
// convention as Host validation; reusing the derived list covers browser-
// based clients hitting the deployed domain directly.
allowedHosts,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how are we managing the DNS rebinding of the spec?

* package that belong to later phases (favicon, icons, websiteUrl, OAuth, …)
* are added together with the features that read them.
*/
export interface ServerConfig {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are missing the v1 icon and other options, where did they go? also the /mcp landing

/**
* Per-request context passed to tool/resource/prompt callbacks.
*
* Grows with later phases (auth, elicitation via input_required, progress);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very important, we should identify v1 context and extend / change as needed for v2 => e.g. the instrumentation adapters, or the auth adapters

khandrew1 and others added 4 commits July 2, 2026 13:36
… SDK to beta.2, move specs into specs/ (MCP-2601)

Bumps @modelcontextprotocol/{server,hono,client} to 2.0.0-beta.2. Reworks
Host/Origin validation docs and behavior so allowedHosts/allowedOrigins are
additive to the localhost allowlist instead of replacing it, and clarifies
getHandler() never binds/validates Host by default. Moves SPEC.md and the
new AUTH_SPEC.md into a specs/ folder for the package.

Claude-Session: https://claude.ai/code/session_01XdhVvFiym8nAVDWow1mcp6
…r CDN shell (MCP-2601) (#1834)

* feat(typescript): mcp-use build/dev/start CLI + inspector CDN shell (MCP-2601)

Implements specs/CLI_SPEC.md — the v2 build/dev/start contract:

- Single-package toolchain: bin dispatches dev/build through a dynamic
  import of the src/cli/ chunk; `start` and the library export never
  load it. vite is an optional peerDependency, absent from prod installs.
- Entry contract: entry modules `export default server` and never call
  listen() — dev/start own the socket; serverless wraps getHandler().
- build: Vite SSR build to .mcp-use/build + manifest. dev: Environment
  API module runner with atomic handler swap behind a single listener
  (reload, not HMR). start: serves the built entry.
- Inspector CDN shell (FastAPI /docs model): dependency-free HTML page
  at ${basePath}/inspector loads the @mcp-use/inspector bundle from
  jsDelivr pinned to major v11; `inspector?: boolean | { assetsUrl }`
  config, default enabled, assetsUrl for air-gapped self-hosting.
- MCPServer gains a readonly `basePath` accessor for tooling; legacy
  wire mode relaxed from "reject" to "stateless".
- examples/railway migrated to the entry contract.

Claude-Session: https://claude.ai/code/session_012wzYppyk7JtFePEjweiWFm

* docs(typescript): document the self-referencing devDependency in CLI_SPEC.md

Claude-Session: https://claude.ai/code/session_012wzYppyk7JtFePEjweiWFm
…p-use/server v2 (MCP-2601) (#1849)

Inspector shell (v2 server):
- Point the default assets URL at the mcp-use R2 bucket serving this
  branch's CDN build, pinned to an exact version (published inspector
  bundles through 12.x hardcode the /inspector router basename and cannot
  run under ${basePath}/inspector; swap to jsDelivr once a release ships
  the basePath-aware client).
- Load the bundle's companion stylesheet (the CDN build is a .js/.css
  pair) and inject the window.process polyfill the bundle needs, matching
  the v1 shell.

Inspector client:
- Auto-connect from the shell-injected window.__MCP_USE_INSPECTOR__
  global (no inspector backend in the v2 shell), and report the real
  bundle version via a compile-time fallback instead of a hardcoded
  1.0.0 (also released separately to canary as inspector 12.0.2).

Dev tunneling (v2 CLI, CLI_SPEC updated):
- mcp-use dev --tunnel spawns npx @mcp-use/tunnel against the bound
  port; the dev listener also answers the inspector's dev-only API
  routes (dev/info, dev/start-tunnel, dev/stop-tunnel) in-process, so
  the UI tunnel toggle works without a server restart. Subdomains are
  persisted and released v1-style via .mcp-use/state/tunnel.json.
- Auto-open the inspector on dev startup; disabled by --no-open and
  skipped when stdout is not a TTY (agents/CI).
@khandrew1 khandrew1 marked this pull request as ready for review July 7, 2026 16:13
@khandrew1 khandrew1 marked this pull request as draft July 7, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants