Skip to content
LaravelBlog

laravel/mcp: Sync 0.x changes and update phpunit.xml.dist

LaravelBlogBot
LaravelBlogBot

Contributed by pushpak1300

Part of the mcp v1.0.1 release

] Pull request #346 is a housekeeping release for laravel/mcp: it folds the work that accumulated on the 0.x line back into main, backfills the changelog for v0.9.3 through v0.9.5, and tightens the package's PHPUnit configuration. It also carries one genuine functional fix — a rewritten size-measurement routine in the bundled MCP Apps SDK bridge. If you are upgrading from v0.9.6, there are no breaking changes and no public PHP API changes; much of this may already be in your install if v0.9.6 was cut from the 0.x line. The value of this PR is that main now reflects all of it, guaranteeing it ships in the next tagged release from main, plus a small test-suite improvement worth knowing about.

What changed at a glance

The diff touches four files, and they tell the story:

  • resources/js/mcp-sdk.js and mcp-sdk.min.js — the internal currentSize() helper, which feeds the ui/notifications/size-changed notification that hosts use to resize MCP App iframes, now measures the document's intrinsic height instead of scrollHeight, and reports window.innerWidth instead of scrollWidth.
  • phpunit.xml.dist — the test suite now pins SESSION_DRIVER to array.
  • CHANGELOG.md — release notes for v0.9.3, v0.9.4, and v0.9.5 were added, and the "Unreleased" comparison link now points from v0.9.5 to main.

The sizing fix: measuring intrinsic height, not scroll size

The old implementation:

function currentSize() {
    return {
        width: document.documentElement.scrollWidth,
        height: document.documentElement.scrollHeight,
    };
}

The new one:

function currentSize() {
    const html = document.documentElement;
    const originalHeight = html.style.height;

    html.style.height = "max-content";
    const height = Math.ceil(html.getBoundingClientRect().height);
    html.style.height = originalHeight;

    return { width: Math.ceil(window.innerWidth), height };
}

Why does this matter? In an iframe-based MCP App, the host sizes the frame to the last reported dimensions. Once that happens, documentElement.scrollHeight can never report anything smaller than the frame's current height — so when your content shrinks, the reported height stays stuck at the tallest it has ever been, and the iframe only ever grows. The new code sidesteps that by temporarily setting the root element's height to max-content, reading the natural content height via getBoundingClientRect(), and restoring the inline style. Rounding up with Math.ceil() avoids a one-pixel overflow that could ping-pong between resize notifications, and using window.innerWidth matches the viewport width the host actually controls.

The public surface of the bridge — createMcpApp() and the API object it hands back — is unchanged; only the measurement behavior differs:

const api = await window.createMcpApp(() => {
    // render your app UI...
});

api.autoResize(); // resize notifications now report true intrinsic height

The test suite now uses the array session driver

phpunit.xml.dist gains one environment variable:

<php>
    <env name="DB_CONNECTION" value="sqlite"/>
    <env name="DB_DATABASE" value=":memory:"/>
    <env name="SESSION_DRIVER" value="array"/>
</php>

With the suite already running on an in-memory SQLite database, leaving the session driver unpinned meant tests touching sessions could depend on the ambient environment — writing session files or reaching for a real session store. The array driver makes every run self-contained and side-effect free. This only affects people running the package's own test suite (contributors and fork maintainers); the dist file isn't part of what Composer installs into your app.

Changelog backfill: context, not new behavior

The changelog now documents three releases you likely already have:

  • v0.9.3 — the MCP Inspector is pinned to v1-latest, and mcp:inspector prompts for route parameter values (#307, #294).
  • v0.9.4 — .gitattributes updates and searchable tool catalogs (#309, #317).
  • v0.9.5 — OAuth client logo and URI support (#337).

If you jumped to v0.9.6 from an earlier version, it's a handy recap of what shipped along the way. The corrected "Unreleased" link also means future release diffs will compare against the right base instead of v0.9.2.

Upgrade impact

  • Standard installs: run composer update laravel/mcp and you're done. No config, code, or environment changes are required.
  • Self-served bridge script: if you copy mcp-sdk.js (or the minified build) into your own pages or a CDN, grab the updated copy and cache-bust it so your MCP Apps pick up the resizing fix.
  • Fork maintainers: mirror the SESSION_DRIVER=array line in your own phpunit.xml if you run the package's tests.
  • MCP App authors: no API changes, but re-testing against a host after updating should show the iframe shrinking correctly when content collapses.

Takeaways

  • PR #346 is a 0.x-to-main sync: changelog backfill, a PHPUnit tweak, and one real fix to the SDK bridge.
  • The bridge now reports intrinsic content height, fixing iframes that never shrink.
  • The package's test suite runs with SESSION_DRIVER=array, making it hermetic.
  • Nothing breaks for v0.9.6 users; only self-hosted bridge scripts and forks need attention.

Sources

More from this release

Related Articles