Skip to content

fix: normalize trailing slashes in UMBRACO_BASE_URL (#63)#64

Merged
hifi-phil merged 2 commits intodevfrom
fix/base-url-trailing-slash
Apr 25, 2026
Merged

fix: normalize trailing slashes in UMBRACO_BASE_URL (#63)#64
hifi-phil merged 2 commits intodevfrom
fix/base-url-trailing-slash

Conversation

@hifi-phil
Copy link
Copy Markdown
Contributor

Summary

Closes #63.

When UMBRACO_BASE_URL was configured with or without a trailing slash, the URL concatenation in the SDK and hosted-mcp fetch clients could produce malformed request URLs (double slashes or edge-case path joining), causing token exchange and API calls to fail without a clear error message.

Normalize baseUrl at the HTTP client entry points so both forms behave identically:

  • SDK initializeUmbracoFetch and createUmbracoFetchClient().initialize strip trailing slashes before storing the auth config
  • Hosted-mcp createUmbracoFetchClient normalizes once at setup

Paths produced by the Orval-generated clients already start with a leading /, so stripping trailing slashes on baseUrl yields correct URLs for every combination.

Tests

  • New packages/mcp-server-sdk/src/http/__tests__/base-url-normalization.test.ts — 6 tests covering no / one / multiple trailing slashes against both the singleton and factory clients
  • Extended packages/hosted-mcp/src/http/__tests__/umbraco-fetch-client.test.ts — 3 additional parameterized cases against createUmbracoFetchClient

Local verification

Command Result
npm test (SDK unit + stdio) ✅ 485 tests (was 479)
npm test -w packages/hosted-mcp ✅ 194 tests (was 191)

Test plan

  • CI green
  • Merge into dev, include in next beta release

🤖 Generated with Claude Code

hifi-phil and others added 2 commits April 23, 2026 15:57
When UMBRACO_BASE_URL was configured with (or without) a trailing slash,
the URL concatenation in the SDK and hosted-mcp fetch clients produced
malformed request URLs ("//" or edge-case path joining), which caused
token exchange and API calls to fail without a clear error.

Normalize baseUrl at the HTTP client entry points so both forms behave
identically:

- SDK `initializeUmbracoFetch` and `createUmbracoFetchClient().initialize`
  strip trailing slashes before storing the auth config
- Hosted-mcp `createUmbracoFetchClient` normalizes once at setup

Adds focused unit tests covering no / one / multiple trailing slashes in
both packages.

Closes #63

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code-review follow-ups on the trailing-slash fix:

- Extract `normalizeBaseUrl(url)` to `@umbraco-cms/mcp-server-sdk`
  (`helpers/url.ts`, exported from main + helpers entry points) and
  use it from the SDK and hosted-mcp fetch clients
- Replace `getBackofficeEndpoints` inline `/\/$/` (single-slash only —
  latent bug for inputs like `https://x//`) with the same helper
- `initializeUmbracoFetch` now clears the cached access token, so a
  re-init with a different base URL can't reuse a stale token
- Drop redundant `mockFetch.mockReset()` calls inside `it.each` bodies
  (already covered by the suite's `beforeEach`)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hifi-phil hifi-phil merged commit 47eebc2 into dev Apr 25, 2026
7 checks passed
@hifi-phil hifi-phil mentioned this pull request Apr 26, 2026
4 tasks
hifi-phil added a commit that referenced this pull request Apr 26, 2026
  Changes since 17.0.0-beta.14:                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                           
  - feat(sdk): ship per-tool TypeScript types codegen (#65, #66)                                                                                                                                                                                                           
    Adds a `umbraco-mcp-generate-types` postbuild step that walks       
    `dist/collections.js`, runs each tool's input/output Zod schema                                                                                                                                                                                                        
    through codegen, and writes a typed registry to                                                                                                                                                                                                                        
    `dist/tool-types.d.ts`. Exposed via the `./tool-types` subpath                                                                                                                                                                                                         
    so downstream MCPs can chain to a built server with full type                                                                                                                                                                                                          
    safety (`import type { McpTemplateTools } from "@umbraco-cms/mcp-template/tool-types"`).                                                                                                                                                                               
                                                                                                                                                                                                                                                                           
  - fix: normalize trailing slashes in UMBRACO_BASE_URL (#63, #64)                                                                                                                                                                                                         
    Strips a trailing `/` from `UMBRACO_BASE_URL` before joining                                                                                                                                                                                                           
    paths, so values like `https://example.com/` no longer produce                                                                                                                                                                                                         
    `//umbraco/management/api/...` request URLs.
@hifi-phil hifi-phil deleted the fix/base-url-trailing-slash branch April 27, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant