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

Skip to content

v2#1827

Draft
khandrew1 wants to merge 7 commits into
mainfrom
v2
Draft

v2#1827
khandrew1 wants to merge 7 commits into
mainfrom
v2

Conversation

@khandrew1

@khandrew1 khandrew1 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Splits the monolithic mcp-use TypeScript package into three focused packages for v2.

Packages

  • mcp-use — server only (MCPServer, OAuth providers, session stores, stream managers, widget adapters, middleware, response/elicitation/completion helpers). An island — depends on nothing else in the repo at runtime. The MCP Apps view runtime stays behind the mcp-use/react subpath.
  • @mcp-use/client — MCP client, connectors, sessions, config, browser OAuth (@mcp-use/client/auth, /auth/node), and the useMcp connection console (@mcp-use/client/react).
  • @mcp-use/agent — LangChain agent, adapters, observability. Depends only on @mcp-use/client.

The only internal dependency edge is agent → client. The server reaches the client solely through an optional lazy import() in MCPServer.proxy(), so client code is never bundled into the server.

Breaking changes (intended for v2)

  • Removed the mcp-use/server subpath — those exports are now the main entry.
  • Removed mcp-use/browser — the browser client is @mcp-use/client's BrowserMCPClient.
  • Client/agent symbols no longer re-export from mcp-use; import them from @mcp-use/client / @mcp-use/agent.
  • mcp-use/auth* moved to @mcp-use/client/auth*.

Verification

Build + idempotent rebuild, per-package unit tests, lint, and cross-package import-boundary checks all pass. A basic and an mcp-apps server example both boot and respond to a real MCP handshake; the mcp-apps widgets resolve mcp-use/react in both dev and production builds; the inspector UI loads and connects to the server.

Landed as 6 reviewed commits: distribute utils → scaffold shells → extract @mcp-use/client → extract @mcp-use/agent → split React + move auth to client → server-only island.

No changeset yet — to be added before release.

Relocate top-level src/utils/ helpers next to their future package owners
ahead of the v2 package split:
- json-schema-to-zod/ -> client/
- url-sanitize.ts -> auth/
- assert, favicon-detector, proxy-config -> react/

Delete the dead utils barrel and drop the ./utils subpath export (also
removes favicon-detector/proxy-config from the main entry). No logic
changes. Part of MCP-2601.
…se 2)

Add empty package shells ahead of the v2 split:
- @mcp-use/client (base) and @mcp-use/agent (depends on @mcp-use/client)
- mirror @mcp-use/cli conventions: composite tsconfig, tsup + tsc
  declaration build, dual ESM/CJS exports
- wire both into the root tsconfig references; the packages/* glob
  auto-includes them in the workspace + build graph

Both build to dist (js/cjs/d.ts); the agent->client workspace link
resolves. No source moved yet. Part of MCP-2601.
…e 3)

Carve the MCP client out of mcp-use into its own leaf package, the third
phase of the v2 package split.

Moved into @mcp-use/client:
- client core (client.ts, client/base, browser), connectors (base/http/stdio),
  session, task_managers, config + config-file, code executors (vm/e2b),
  code-mode connector, elicitation helpers, json-schema-to-zod.
- Duplicated dependency-free leaves (logging, version, runtime, the telemetry
  set) per the agreed no-core-package strategy; the Day-9 telemetry split will
  collapse the duplicates.

Cutover:
- Repoint mcp-use src/index/tests and the CLI from the old in-package paths to
  @mcp-use/client; add a temporary mcp-use -> @mcp-use/client dependency to
  carry agent code still living in mcp-use until Phase 4.
- Remove the mcp-use "./client" subpath export and its tsup entries.
- Export config-file (loadConfigFile) and client/executors/base (tool-search
  types) from the client public surface.

Tests:
- Move the client-owned white-box unit tests (connectors, session,
  task_managers, config, code executor, client/connector telemetry) into the
  client package and stand up vitest there.
- Keep mcp-use-level tests in place, repointing their MCPClient/BrowserMCPClient
  imports and partial vi.mocks to @mcp-use/client so the mocks stay effective.

Build:
- Build client before mcp-use and exclude it from build:other so the foundation
  package is always built first.
- Add `rimraf dist` to the client build: tsup's clean leaves dist/.tsbuildinfo,
  which made composite tsc skip the .d.ts emit on no-change rebuilds.

Gate: build (incl. idempotent rebuild), client + mcp-use unit tests, and lint
all green.
Move the agent cluster out of the mcp-use server package into the
scaffolded @mcp-use/agent package and sever all agent re-exports from
the server. @mcp-use/agent depends on @mcp-use/client (the one legal
internal edge); the server no longer references the agent at all.

Moved into packages/agent/src: agents/, adapters/, managers/,
observability/, browser-agent.ts, and telemetry/utils.ts
(extractModelInfo). Agent code now imports logger/Telemetry from the
@mcp-use/client public surface; version.ts is duplicated as a
dependency-free leaf.

mcp-use (server):
- index.ts: drop MCPAgent/RemoteAgent, adapters, AI-SDK utils,
  ServerManager, manager tools, observability, and PROMPTS exports
- package.json: remove ./adapters, ./agent, ./browser/agent export
  blocks; drop now-unused langchain/langfuse peer deps and the
  @langchain/openai + ai devDeps (server has zero langchain/ai imports);
  remove dead agent integration/simple test scripts
- telemetry-node/telemetry-browser: getPackageVersion now resolves from
  ../version.js (telemetry/utils.ts moved to the agent)
- tsup.config.ts: drop adapters/agents node entries and browser-agent

agent:
- index.ts, tsup (browser-agent entry), tsconfig (tsBuildInfoFile),
  build script (rimraf dist prefix), vitest.config.ts
- package.json: workspace client dep, langchain peers, ai devDep (for
  the AI SDK interop test), and ported integration test scripts
- agent-telemetry.test.ts: stub Telemetry at the @mcp-use/client
  boundary and assert on trackAgentExecution input rather than reaching
  through the client's compiled dist to PostHog

Build (incl. idempotent rebuild), client/agent/mcp-use unit tests, lint,
and cross-package import boundaries all green.
…ase 5)

Split the React surface across its two homes and move all client-
connection OAuth into @mcp-use/client, keeping the server an island.

React:
- The useMcp connection console cluster (useMcp, McpClientProvider,
  storage providers, rpc-logger, useMcp-helpers, types, assert,
  favicon-detector, proxy-config) moves to @mcp-use/client/react.
- The view runtime (useWidget, useCallTool, useFiles, generateHelpers,
  widget providers/types) stays as mcp-use/react. No file is shared
  across the two clusters.

Auth (whole dir → client, deviating from the written "node stays in
server" plan):
- src/auth/ is entirely client-connection OAuth — node-provider/
  FileKVStore are consumed by the CLI acting as an MCP client, and the
  server's own OAuth is the separate src/server/oauth/. Moving the whole
  dir keeps mcp-use a true island instead of forcing a permanent
  mcp-use → @mcp-use/client dependency.
- Client exposes @mcp-use/client/auth (browser barrel) and
  @mcp-use/client/auth/node (node barrel).

client:
- New ./auth, ./auth/node, ./react export subpaths (tsup object entries
  + tsc rootDir:src layout, no src/ prefix); React as optional peer dep;
  react/jsdom/@types/react/react-test-renderer devDeps; tsconfig gains
  jsx:react + DOM.Iterable. Moved useMcp/auth white-box + jsdom tests in.
- Repointed the moved files' BrowserMCPClient self-import to the relative
  ../client/browser.js, and the moved tests' vi.mock target accordingly.

mcp-use (server):
- Dropped the ./auth + ./auth/node subpaths and the main-entry browser
  OAuth re-exports (breaking, expected in v2); react barrel now exports
  only the view runtime; browser.ts re-exports OAuth from
  @mcp-use/client/auth. Updated the browser/commonjs export-surface tests.

consumers:
- CLI: mcp-use/auth/node → @mcp-use/client/auth/node.
- inspector: console symbols → @mcp-use/client/react (added @mcp-use/client
  dep); MessageContentBlock stays on mcp-use/react; OAuth callback →
  @mcp-use/client/auth.

Build (incl. idempotent rebuild), client/agent/mcp-use unit tests
(170/86/358), lint, and cross-package boundaries all green. The react and
auth runtime seams to the server are resolved; the remaining
mcp-use → @mcp-use/client edges (index re-exports, browser.ts,
mcp-server dynamic import, proxy-client type) are the Phase 6 cleanup.
…ase 6)

`mcp-use`'s main entry is now the server surface only (MCPServer, OAuth
providers, session stores, stream managers, widget adapters, middleware,
helpers, telemetry, elicitation errors). The MCP client lives in
`@mcp-use/client`, the agent in `@mcp-use/agent`, and the MCP-UI view runtime
behind the `mcp-use/react` subpath.

Breaking (expected for v2):
- Removed the `mcp-use/server` subpath — its exports are now the main entry.
- Removed the `mcp-use/browser` subpath (zero external consumers); the browser
  client is `@mcp-use/client`'s `BrowserMCPClient`.
- Dropped all client/agent re-exports from the main entry.

Package boundary:
- `@mcp-use/client` is now an optional peer dep, reached only via a lazy
  `await import("@mcp-use/client")` in `MCPServer.proxy()` and marked external
  in tsup, so client code is never bundled into the server. The server depends
  on nothing else in the repo at runtime.
- Removed the dead `@e2b/code-interpreter` peer dep.

Consumers repointed: CLI, inspector, create-mcp-use-app templates, e2e
fixtures, deno import map, integration tests, JSDoc, and examples now import
server symbols from `mcp-use` and client symbols from `@mcp-use/client`.

Also resolves a pre-existing `window.openai` global collision (unrelated to the
split, previously masked by the incremental .tsbuildinfo cache): `@mcp-ui/server`
augments `Window.openai` with an incompatible `AppsSdkBridge` shape in the same
TypeScript project as the view runtime. The view runtime now reads the bridge
through a locally-typed `getWindowOpenAi()` accessor and exports the
`AppsSdkWindowOpenAi` type instead of re-declaring the global; the inspector uses
that exported type for its iframe host simulation.

Claude-Session: https://claude.ai/code/session_012RQjGLNsXpsxzN9uzkNUkF
@pkg-pr-new

pkg-pr-new Bot commented Jun 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

@mcp-use/agent

npm i https://pkg.pr.new/mcp-use/mcp-use/@mcp-use/agent@1827

@mcp-use/cli

npm i https://pkg.pr.new/mcp-use/mcp-use/@mcp-use/cli@1827

@mcp-use/client

npm i https://pkg.pr.new/mcp-use/mcp-use/@mcp-use/client@1827

create-mcp-use-app

npm i https://pkg.pr.new/mcp-use/mcp-use/create-mcp-use-app@1827

@mcp-use/inspector

npm i https://pkg.pr.new/mcp-use/mcp-use/@mcp-use/inspector@1827

mcp-use

npm i https://pkg.pr.new/mcp-use/mcp-use@1827

commit: 6a3a12c

try {
switch (this._storageCapability) {
case "filesystem":
this._currUserId = this._getUserIdFromFilesystem();
try {
newUserId = generateUUID();
} catch (uuidError) {
newUserId = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

MCP MCP Conformance Test Results

Commit: 6a3a12c

Server Conformance

SDK Score vs main vs canary
typescript 26/30 (87%) 🔴 -4 🔴 -4
4 failure(s) — click to expand
Scenario typescript
completion-complete
dns-rebinding-protection
elicitation-sep1034-defaults ❌ -1
elicitation-sep1330-enums ❌ -1
logging-set-level
ping
prompts-get-embedded-resource
prompts-get-simple
prompts-get-with-args
prompts-get-with-image
prompts-list
resources-list
resources-read-binary
resources-read-text
resources-subscribe
resources-templates-read
resources-unsubscribe
server-initialize
server-sse-multiple-streams
tools-call-audio
tools-call-elicitation ❌ -1
tools-call-embedded-resource
tools-call-error
tools-call-image
tools-call-mixed-content
tools-call-sampling ❌ -1
tools-call-simple-text
tools-call-with-logging
tools-call-with-progress
tools-list

Client Conformance

SDK Score vs main vs canary
typescript-browser-client 0/20 (0%) 🔴 -20 🔴 -20
typescript-node-client 0/20 (0%) 🔴 -20 🔴 -20
typescript-react-client 0/20 (0%) 🔴 -20 🔴 -20
60 failure(s) — click to expand
Scenario typescript-browser-client typescript-node-client typescript-react-client
auth/2025-03-26-oauth-endpoint-fallback ❌ -1 ❌ -1 ❌ -1
auth/2025-03-26-oauth-metadata-backcompat ❌ -1 ❌ -1 ❌ -1
auth/basic-cimd ❌ -1 ❌ -1 ❌ -1
auth/metadata-default ❌ -1 ❌ -1 ❌ -1
auth/metadata-var1 ❌ -1 ❌ -1 ❌ -1
auth/metadata-var2 ❌ -1 ❌ -1 ❌ -1
auth/metadata-var3 ❌ -1 ❌ -1 ❌ -1
auth/pre-registration ❌ -1 ❌ -1 ❌ -1
auth/scope-from-scopes-supported ❌ -1 ❌ -1 ❌ -1
auth/scope-from-www-authenticate ❌ -1 ❌ -1 ❌ -1
auth/scope-omitted-when-undefined ❌ -1 ❌ -1 ❌ -1
auth/scope-retry-limit ❌ -1 ❌ -1 ❌ -1
auth/scope-step-up ❌ -1 ❌ -1 ❌ -1
auth/token-endpoint-auth-basic ❌ -1 ❌ -1 ❌ -1
auth/token-endpoint-auth-none ❌ -1 ❌ -1 ❌ -1
auth/token-endpoint-auth-post ❌ -1 ❌ -1 ❌ -1
elicitation-sep1034-client-defaults ❌ -1 ❌ -1 ❌ -1
initialize ❌ -1 ❌ -1 ❌ -1
sse-retry ❌ -1 ❌ -1 ❌ -1
tools_call ❌ -1 ❌ -1 ❌ -1

View full run details

…urable basePath, env consolidation (#1831)

* feat(typescript): mcp-use.json config schema + loader (MCP-2601, MCP-2613 P1)

Add the mcp-use.json project config: Zod schema + McpUseConfig/ResolvedConfig
types, a generated JSON Schema, and a zero-execution loader (walk-up discovery,
JSON.parse only, missing-file -> defaults) exposed via the new mcp-use/config
subpath. No CLI/server consumer wired yet -- non-breaking foundation for the
.mcp-use/ workspace + config-driven build (P2+).

* feat(typescript): .mcp-use/ workspace replaces dist/ (MCP-2601, MCP-2613 P2)

Move all per-project build output and runtime scratch out of dist/ into a
single gitignored .mcp-use/ workspace (the Next.js .next analog), derived from
one paths module (mcp-use/config resolveWorkspacePaths/resolveWorkspace):

  .mcp-use/build/      compiled server + views + public + manifest.json (outDir)
  .mcp-use/generated/  tool-registry.d.ts
  .mcp-use/cache/      dev/build scratch (vite entries, metadata extraction)
  .mcp-use/state/      sessions.json, tunnel.json
  .mcp-use/cloud/      link.json (deploy linkage)

mcp-use (server):
- new mcp-use/config paths API; the server resolves outDir from config at boot
  and serves built widgets/public from <outDir> instead of a hardcoded dist/
  (buildDir threaded through the widget ServerConfig carrier).
- session store default -> state/sessions.json; type generator -> generated/.
- dev widget cleanup scoped to cache/ so it no longer deletes sibling workspace
  dirs (build/generated/state/cloud).

cli:
- build writes to config.outDir (default .mcp-use/build); manifest renamed to
  build/manifest.json; entry detection + start fallbacks resolve under the
  build dir.
- tunnel subdomain split out of the manifest into state/tunnel.json (build
  output carries no mutable runtime state).
- project.json -> cloud/link.json; single .gitignore writer (utils/gitignore.ts)
  shared by deploy + link; dist dropped from ignores + tarball excludes.

Verified end-to-end: build + start of the mcp-apps example serves widgets from
.mcp-use/build (HTTP 200), dev scratch lands in cache/ and the workspace
survives cleanup, sessions resolve to state/. 330 mcp-use unit tests pass;
tsc + eslint clean on both packages.

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

* refactor(typescript): rename mcp-use.json → mcp-use.config.json (MCP-2613)

The project config filename collided with the `mcp-use` package import: with
`baseUrl: "."` in tsconfig (very common — the example uses it), a bare
`import … from "mcp-use"` resolves to the sibling `mcp-use.json` FILE, which
breaks `mcp-use build` (esbuild bundle: "No matching export in mcp-use.json for
import MCPServer") and direct tsx execution. Renaming to `mcp-use.config.json`
avoids the collision (the extension probe never matches it) and matches the
`next.config.*` / `vitest.config.*` convention.

Changes the CONFIG_FILE_NAME constant (single source of truth; the loader reads
it), the two config tests that write the file, and doc comments.

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

* feat(typescript): configurable basePath (MCP-2074, Phase 3)

Relocate the entire framework HTTP surface under a single configurable
basePath (default /mcp): MCP transport, widget/public assets, OAuth endpoints,
and the inspector all move under ${basePath}. Only /.well-known/* and
/favicon.ico stay at the server root. basePath is read solely from
mcp-use.config.json (NOT a runtime constructor field — it is build-time-baked
into widget HTML by the CLI, so a runtime-only override would mount routes
where no assets were baked; mirrors Next.js basePath).

- New config/base-path.ts: normalizeBasePath + widgetAssetBase/publicAssetBase
  route builders centralizing the ~18 hardcoded /mcp-use literals.
- Security: narrow the OAuth bearer guard from app.use("/mcp/*") to the EXACT
  transport paths, so public assets under ${basePath}/mcp-use/* and OAuth under
  ${basePath}/oauth/* are no longer trapped behind the bearer token.
- React: server injects window.__mcpServerUrl + __MCP_BASE_PATH__; drop the
  useWidget.ts suffix-strip that reverse-engineered the origin.
- Inspector fully basePath-aware: client reads __MCP_BASE_PATH__ via a new
  helper, serve-time asset-path rewrite, CLI dev auto-open/health/transport URLs
  prefixed; the inspector now serves only at ${basePath}/inspector.
- Startup [MCP] connect-hint logs print the resolved basePath, not a hardcoded
  /mcp.

Verified: all packages build clean; oauth guard-invariant + base-path unit
tests pass; live curl at default /mcp, custom /app, and root-mount.

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

* chore(examples): enable the inspector in the mcp-apps example (MCP-2074)

Add `@mcp-use/inspector` as a devDependency so the example can run the
inspector (via `mcp-use dev` or `build --with-inspector`) under the new
configurable basePath. devDependency, not a runtime dep — the inspector is a
dev-only tool the SDK loads via optional dynamic import.

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

* fix(typescript): correct P2 build-dir drift (MCP-2601)

Two spots still referenced the pre-P2 `dist/` build layout:

- cli/utils/tarball.ts: `dist` had fallen out of EXCLUDE_DIRS, so cloud
  upload tarballs re-shipped build output (tarball test asserted it was
  excluded and was failing). Re-added `dist`.
- inspector/server/tunnel.ts: read the tunnel subdomain from the stale
  `dist/mcp-use.json` manifest (nested `.tunnel.subdomain`). Now reads
  `.mcp-use/state/tunnel.json` via `resolveWorkspacePaths().tunnel`
  (top-level `subdomain`), matching where the CLI writes tunnel state.

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

* feat(typescript): constructor-only config, MCP_USE_LOG_LEVEL, canonical URL resolution (MCP-2601 P4)

Removes mcp-use.config.json (loader, Zod schema, generated JSON schema)
in favor of MCPServer constructor options introspected off the imported
entry by the CLI. Consolidates DEBUG/MCP_DEBUG_LEVEL/VERBOSE into a
single MCP_USE_LOG_LEVEL (info|debug|trace) and adds the resolve-url
canonical-origin helpers (MCP_URL -> proxy headers -> host:port).

Includes review fixes: getHandler() now resolves the base URL from
MCP_URL like listen() (fixes localhost widget URLs and
localhost:undefined OAuth issuers on serverless), the serve-time widget
rewrite no longer pulls absolute assetPrefix/CDN URLs back to the
server origin, mcp-use build bakes the introspected serverBasePath into
widget HTML (favicon hrefs, __MCP_BASE_PATH__), and the vacuous
display-package-versions test suite is deleted. Adds the branch
changeset.

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

* chore: drop the branch changeset for now

Claude-Session: https://claude.ai/code/session_016mTqhvE92xGhVy9nV7sT7G
*/
function normalizeInspectorBasePath(raw: string | undefined): string {
if (raw === undefined) return "/mcp";
let value = raw.trim().replace(/\/{2,}/g, "/").replace(/\/+$/, "");
let value = raw.trim().replace(/\/{2,}/g, "/");

// Strip every trailing slash.
value = value.replace(/\/+$/, "");
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