Multi-transport MCP chaining and hosted MCP package#17
Merged
Conversation
Introduces `@umbraco-cms/mcp-hosted` — building blocks for deploying Umbraco MCP servers to Cloudflare Workers with OAuth authentication and Streamable HTTP transport. Key components: - OAuth Third-Party Authorization Flow (MCP spec compliant) - /authorize route with per-client consent screen - /callback completing authorization via OAUTH_PROVIDER.completeAuthorization() - Full OAuthAuthRequest stored in KV for round-trip integrity - Per-request McpServer factory (MCP SDK 1.26.0+ requirement) - fetch-based API client replacing Axios for Workers runtime - Worker config loader for env bindings - UMBRACO_SERVER_URL env var for self-signed cert workaround in local dev - OAuthAuthRequest/OAuthProviderHelpers type interfaces (avoids Wrangler virtual module dependency) Template updates: - Worker entry using McpAgent.serve() for Streamable HTTP - wrangler.toml with new_sqlite_classes for agents library - client-fetch adapter for hosted fetch client Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t support Enable Orval-generated API clients in Cloudflare Workers by adding setCustomTransport() to UmbracoManagementClient, which replaces Axios with a fetch-based transport at runtime. Add fetchCurrentUser() to load the authenticated user's permissions for per-user tool filtering. Switch OAuth client from confidential to public (PKCE provides sufficient security), making client_secret optional throughout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…iltering SDK: Add `readOnly` field to CollectionConfiguration that filters tools by their `annotations.readOnlyHint` or deprecated `isReadOnly` property, replacing the previous approach of expanding readOnly into excludeSlices. This runs as step 0 in shouldIncludeTool (before all other checks). Hosted MCP: Add slice checkboxes to the consent screen so users can toggle individual operation types (read, create, update, etc.). Slice selections narrow the admin config via includeSlices intersection. Move hosted-mcp README from docs/ to package root. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Includes token-storage KV helpers, multi-site type definitions, fetch client token refresh, updated exports, jest config for hosted-mcp project, and comprehensive documentation covering architecture, auth internals, deployment, security, customization, multi-site, troubleshooting, and future roadmap items. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… get-server-info tool - Add /info diagnostic endpoint to hosted-mcp (gated behind ENABLE_INFO_ENDPOINT env var) - Add 19 integration tests using Jest + unstable_dev (landing page, OAuth discovery, consent screen, MCP protocol, info endpoint) - Add 5 E2E acceptance tests using Playwright against real Umbraco (OAuth flow, authenticated MCP calls including real API tool execution, MCP Inspector visual test) - Add get-server-info tool that calls Umbraco Management API to prove full auth chain - Add minimal Umbraco 17 test instance (SQLite, unattended install, OAuth client registration) - Add wrangler.integration.toml and .dev.vars.integration for test Worker config Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These tests validate the hosted-mcp platform (OAuth flow, consent screen, MCP protocol), not the user's project, so they don't belong in the starter kit. Test scripts moved to root package.json; template gets a .dev.vars.example for discoverability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Always set prompt=login on every Umbraco authorization redirect, removing the conditional showLoginToggle/reauth machinery. This forces the login form on every connection, allowing users to switch accounts between MCP sessions without manual logout. E2E tests rewritten with consent tool selection coverage: - Mode filtering (single mode, exclude modes) - Slice filtering (single slice, multiple slices) - ReadOnly toggle - Cross-filter combinations (mode+slice, mode+readOnly, triple) - Deny consent flow - Tool call execution after filtering Also fixes E2E test performance (removed unnecessary 15s/10s waits) and suppresses wrangler 401 warnings via logLevel: "error". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…vements - Add scripts/tunnels.sh for Cloudflare tunnel testing with remote MCP clients - Add umbraco/McpOAuthComposer.cs and ProgramSnippet.cs for OAuth setup - Auto-copy McpOAuthComposer.cs and patch Program.cs during init - Add x-forwarded-proto rewriting in createWorkerExport for tunnel support - Add two-column grid layout for consent screen tool modes - Collapse collection lists under mode checkboxes (show/hide on toggle) - Add reauth/logout flow with PostLogoutRedirectUris and EndSession permission - Add local-dev-setup.md docs, update README with new template files - Update tests for new template files and patchProgramCs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restore blue header with Umbraco logo on consent screen, lay out info fields in a 2-column grid, and display operations in a 5-column grid. Add future planning doc for chained MCP consent scenarios. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
McpClientManager now supports two transport types via a discriminated union config. Stdio transport (default) spawns child processes as before. In-process transport calls tool handlers directly, enabling MCP chaining in environments without node:child_process (e.g. Cloudflare Workers). - Extract StdioConnection from manager.ts (dynamic import) - Add InProcessConnection with collection filtering and Zod→JSON Schema - Add McpConnection interface abstracting both transports - Make @modelcontextprotocol/sdk external in tsup to avoid bundling stdio - Update mcp-chaining docs for both transports - Add SDK docs (api-helpers, configuration, constants, testing, etc.) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t-mcp-chaining # Conflicts: # .gitignore
New skills for incrementally adding tools, integration tests, and eval tests to existing collections. Each skill delegates template ownership to its respective agent rather than duplicating inline. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace $(npm root) with node_modules/ in jest paths — shell command substitution doesn't work on Windows cmd.exe or PowerShell. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract registerChainedTools() to reduce ~60 lines of chaining boilerplate per worker. Add agents-mcp.d.ts ambient types to hosted-mcp package. Replace Axios with fetch-based client in SDK. Update template to delegate to SDK's UmbracoManagementClient. Add chained MCP e2e test suite. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move inspector lifecycle, OAuth flow, tool listing, and tool execution helpers from three duplicate inspector-setup files into a shared /testing export. Lazy-load yargs in the SDK config module to prevent it from crashing in Cloudflare Worker builds where import.meta.url is undefined. Add example E2E test suite to the template. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Delete SDK and hosted-mcp docs that are now in the official Umbraco documentation site. Move remaining planning docs into docs/plans/ grouped by package (hosted-mcp, create-mcp-server, monorepo). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Split SDK tests so stdio-based MCP client tests run sequentially (--runInBand) to avoid timeout under parallel Jest workers - Document testing gotchas in CLAUDE.md: integration tests, evals, self-signed certs, stale workerd processes - Auto-set npm latest tag for prerelease versions when no stable release exists, fixing beta.1 stuck as default 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
The template uses file: references to sibling monorepo packages which break when the template is copied as a starter kit for new projects. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The template package.json correctly uses file: references for the monorepo workspace. The create-mcp-server scaffold tool rewrites these to published versions when creating new projects, but was missing the rewrite for @umbraco-cms/mcp-hosted. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Playwright's test-results/ directory is a local artifact that shouldn't be included when copying or scaffolding the template. Without this exclusion, CI fails because the snapshot includes the file but clean checkouts don't have it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
packages/hosted-mcp/): New package for building Cloudflare Worker-hosted MCP servers with OAuth authorization, consent screens, multi-site support, and token storageregisterChainedToolshelper supporting stdio and in-process transports to proxy tools from other MCP serversreadOnlyHintannotation filtering, in-process MCP connections, and stdio connection supportget-server-infotool, and hosted E2E test infrastructureadd-tool,add-test, andadd-evalClaude Code skills for scaffoldingTest plan
npm run build && npm run testto verify everything builds and passes🤖 Generated with Claude Code