Skip to content

fix(basic-host): serve sandbox.html when the checkout is under a dotted directory - #812

Open
kristian-presso wants to merge 1 commit into
modelcontextprotocol:mainfrom
kristian-presso:fix/basic-host-sandbox-dotted-path
Open

kristian-presso wants to merge 1 commit into
modelcontextprotocol:mainfrom
kristian-presso:fix/basic-host-sandbox-dotted-path

Conversation

@kristian-presso

Copy link
Copy Markdown

basic-host answers 404 for sandbox.html when the checkout sits anywhere under a directory whose name starts with a dot. The host page still loads, so the View silently never renders. This passes root to res.sendFile so only the file name is checked.

Motivation and Context

I test MCP App Views against basic-host from automated evaluation runs, which keep their working copies under a .runs/ directory. There the host page loaded, but every View stayed blank and the browser showed a 404 for the sandbox iframe, which pointed at my app rather than at the host.

The cause is in examples/basic-host/serve.ts:

res.sendFile(join(DIRECTORY, "sandbox.html"));

Express passes this to send, whose dotfiles option defaults to "ignore". With an absolute path and no root, send checks every segment of the full path, so any dotted directory above the example (.runs/, .cache/, a .worktrees/ checkout) makes it return 404. The host page is not affected because express.static(DIRECTORY) passes a root, and then only the path below the root is checked. The fix does the same for the sandbox:

res.sendFile("sandbox.html", { root: DIRECTORY });

The /sandbox.html-only routing and the CSP and cache headers are unchanged.

How Has This Been Tested?

  • Built basic-host, copied it under <tmp>/.runs/basic-host/ and ran bun serve.ts there with HOST_PORT=18080 SANDBOX_PORT=18081:
    • before: GET :18080/index.html 200, GET :18081/sandbox.html 404;
    • after: both 200, and the sandbox response still carries the Content-Security-Policy header.
  • A minimal Express 5.3.0 script comparing the two calls: sendFile(join(dir, f)) returns 404 under .runs/dist and 200 under plain/dist; sendFile(f, { root: dir }) returns 200 in both.
  • tsc --noEmit in examples/basic-host and npx prettier --check on the file pass.

There is no test harness for serve.ts (it starts both servers on import), so I have not added one. Happy to add one if you would like serve.ts to export its apps for testing.

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

The open basic-host PRs (#718, #632) leave this line as it is, so this should not conflict with them.

AI disclosure: traced, prototyped and drafted with Claude Code, which I use as my coding agent.

…ed directory

`res.sendFile` with an absolute path and no `root` makes `send` check every
segment of the path for dotfiles, and it ignores dotfiles by default. So
when any directory above examples/basic-host starts with a dot (`.cache/`,
`.runs/`, a `.worktrees/` checkout), the sandbox server answers 404 for
sandbox.html while the host page, served through `express.static` with a
root, loads fine. The View then never renders.

Pass the file name with `root: DIRECTORY` so only the relative path is
checked, as `express.static` already does for the host page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyfRBGJuWRersRLswfqPwd

This branch has not been deployed

No deployments
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