fix: add CAMOFOX_MAX_BODY_SIZE env var to control body parser limit - #8398
Merged
Merged
Conversation
Both the global express.json() parser and the /evaluate endpoint now read from CAMOFOX_MAX_BODY_SIZE (default: 100kb) via CONFIG.maxBodySize. The setting is defined in lib/config.js alongside all other env vars. Closes jo-inc#8397
igitur
force-pushed
the
fix/evaluate-max-body-size-env
branch
from
July 26, 2026 09:08
797f936 to
bc7dbb3
Compare
Contributor
|
Thanks @igitur — merged, with your original commit retained in the history. The follow-up keeps the global JSON limit at |
timothybrush
pushed a commit
to timothybrush/camofox-browser
that referenced
this pull request
Aug 2, 2026
Fixes jo-inc#8397 Refs jo-inc#8398 Co-authored-by: Francois Botha <igitur@users.noreply.github.com>
jimconstable
pushed a commit
to jimconstable/camofox-browser
that referenced
this pull request
Aug 2, 2026
* feat(mcp): add stdio MCP server exposing all 11 tools
- mcp/server.mjs mirrors the OpenClaw plugin.ts tools 1:1 (same names,
schemas, REST routes) so any MCP host reaches camofox identically
- add @modelcontextprotocol/sdk dep, camofox-mcp bin, npm run mcp + test:mcp
- scripts/test-mcp.mjs: dependency-free smoke test (handshake, 11 tools,
schemas, unknown-tool isError) — no REST server required
* test(mcp): add manual tool-call helpers for ad-hoc verification
- mcp-call.mjs: invoke one tool, print parsed result
- mcp-run.mjs: run a JSON sequence of calls in one MCP process
(auto-substitutes ${tabId} from the prior create_tab result,
simulating Claude Code's long-lived single-process usage)
- complements scripts/test-mcp.mjs (schema smoke test, no REST server)
* docs(mcp): convert helper comments to English
Match the repo's English-only comment convention (jo-inc/camofox-browser
is a global OSS project). No code change — comments only.
* docs(mcp): move MCP guide out of main README into mcp/README.md
The MCP integration is additive; the main README should keep jo-inc's
original Quick Start flow (OpenClaw -> Standalone -> Docker) untouched.
Restore README to upstream-identical and house the full MCP guide,
tool table, env vars, and troubleshooting in mcp/README.md instead.
The PR body links to it for discovery.
* docs(mcp): make registration path-independent
The previous quick start used 'node ./mcp/server.mjs', which only works
when cwd is the checkout — so the MCP server was effectively locked to
the camofox-browser repo. Rewrite around the 'camofox-mcp' bin, which
resolves from anywhere once installed via npm link / npm i -g / npx.
Verified the bin loads all 11 tools from /tmp.
* docs(mcp): add per-host registration for codex/agy/cursor/opencode
The MCP server is standard stdio, so all five hosts run the same
camofox-mcp bin — only the config file differs. Restructure the register
section into per-host snippets:
- Claude Code (claude mcp add / .claude.json / .mcp.json)
- Codex CLI (~/.codex/config.toml, [mcp_servers.*] TOML)
- Antigravity/agy (~/.gemini/config/mcp_config.json)
- Cursor (~/.cursor/mcp.json / .cursor/mcp.json)
- opencode (opencode.json, 'mcp' key, type: local)
Plus a per-host verify table and a clear install-vs-register split.
* feat: add /tabs/:tabId/upload endpoint for file attachment
Attach a file to an upload control without going through the native OS
file dialog. Two strategies are tried in order:
1. If an <input type="file"> is already present, call Playwright
setInputFiles on it directly (works for hidden inputs).
2. Otherwise arm a filechooser listener, activate the trigger element
(ref or selector) via keyboard (focus + Enter) with a forced click
as fallback, and setFiles on the resulting chooser. Also polls for
an in-app panel <input type=file> that mounts after activation.
The panel-input path is preferred over the native chooser so a control
that surfaces both (e.g. LinkedIn's media picker) attaches the file
exactly once rather than producing a duplicate.
Paths must be visible inside the container (e.g. a bind-mounted dir);
the route guards with fs.existsSync and returns 400 file_not_found
otherwise. Runs under the same per-user and per-tab locks as the other
interaction routes.
Includes OpenAPI documentation and unit tests (request validation +
source-contract assertions).
* refactor(upload): extract timeout magic numbers into constants + `timeout` arg
The upload route had inline millisecond literals (4000, 12000, 3000,
10000, 500, 1500) scattered through its two attach strategies. Replace
them with named UPLOAD_*_MS constants declared next to the route, and
expose the overall wait budget as an optional `timeout` request field.
- UPLOAD_UI_TIMEOUT_MS (default 12000) backs the request's `timeout`:
the budget to wait for an upload UI (panel input or native chooser).
Non-numeric / <= 0 values fall back to the default.
- The panel-poll window derives from that budget minus
UPLOAD_PANEL_MARGIN_MS, preserving the original 10000/12000 split so a
late native chooser is still caught after polling stops.
- UPLOAD_INPUT/FOCUS/CLICK/REFS/POLL/SETTLE_MS name the per-call bounds.
Defaults reproduce the previous behavior exactly. OpenAPI documents the
new `timeout` field; tests cover timeout resolution and assert the route
carries no bare millisecond literals.
* Update Docker build argument from ARCH to CAMOUFOX_ARCH
* fix(cookies): harden path traversal check in readCookieFile
Normalize cookiesDir with path.resolve() before the prefix comparison
and explicitly reject absolute cookiesPath values. Without this,
non-normalized cookiesDir (containing '..', trailing slashes, or
symlink-like segments) can make the startsWith() guard unreliable.
* refactor(mcp,openclaw): share tool contracts via lib/mcp-tool-contracts.mjs
* test(mcp): add mock-HTTP contract tests for all 11 tools
* build(mcp): make mcp/ an independently installable package
* docs(mcp): document CAMOFOX_ACCESS_KEY, contract tests, and standalone install
* fix: add CAMOFOX_MAX_BODY_SIZE env var to control body parser limit
Both the global express.json() parser and the /evaluate endpoint now
read from CAMOFOX_MAX_BODY_SIZE (default: 100kb) via CONFIG.maxBodySize.
The setting is defined in lib/config.js alongside all other env vars.
Closes jo-inc#8397
* fix: resolve npm audit vulnerabilities
* fix(evaluate): route errors through handleRouteError
* fix(cookies): contain resolved cookie paths
Co-authored-by: Sebastion <sebastion@sebastion.dev>
* fix(sessions): lease pages during creation
Refines the session-reaping approach from jo-inc#8319 without adding admission queues or HTTP 429 behavior.\n\nFixes jo-inc#8555\nRefs jo-inc#8319\n\nCo-authored-by: batumilove <batumilove@users.noreply.github.com>
* fix(evaluate): isolate large request bodies
Fixes jo-inc#8397
Refs jo-inc#8398
Co-authored-by: Francois Botha <igitur@users.noreply.github.com>
* fix(upload): contain file paths within upload directory
Resolve upload paths before attaching files. Reject paths outside CAMOFOX_UPLOADS_DIR, including symlink escapes, and require regular files.
Co-authored-by: Leone Parise <1442927+leoneparise@users.noreply.github.com>
* test(upload): cover HTTP file attachment
Exercise an in-root upload through a real browser file input and verify outside-root paths return 400.
* test(sessions): assert page lease return
* ci: mirror Camoufox releases daily
* fix(evaluate): forward body size configuration
* test(config): cover evaluate body size forwarding
* fix(mcp): package standalone adapter dependencies
* fix(mcp): use browser-mcp package name
* docs(mcp): credit initial implementation
* test(release): synchronize MCP package version
* fix(mcp): align adapter binary name
* fix(mcp): keep adapter binary name concise
* fix(mcp): use consistent package and binary name
* v1.13.1
---------
Co-authored-by: epicsagas <wowinno@gmail.com>
Co-authored-by: Leone Parise <1442927+leoneparise@users.noreply.github.com>
Co-authored-by: Xu Chen <79107215+xuc323@users.noreply.github.com>
Co-authored-by: Sebastion <sebastion@sebastion.dev>
Co-authored-by: Francois Botha <igitur@gmail.com>
Co-authored-by: Dividesbyzer0 <54127744+zoomdbz@users.noreply.github.com>
Co-authored-by: Mattia Trapani <mattia.trapani@gmail.com>
Co-authored-by: Pradeep Elankumaran <pradeepe@gmail.com>
Co-authored-by: Francois Botha <igitur@users.noreply.github.com>
Co-authored-by: jac-agent[bot] <4165859+jac-agent[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <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.
Problem
The
/tabs/:tabId/evaluateendpoint has a 1MB body limit override, but it's dead code — the globalexpress.json({ limit: '100kb' })middleware on line 120 runs first and rejects any body larger than 100KB before the evaluate-specific parser ever fires.This makes it impossible to pass large expressions to evaluate, which is important for:
Fix
Add
CAMOFOX_MAX_BODY_SIZEenv var (default:'100kb') tolib/config.js— the centralized config module where all other env vars live. Then useCONFIG.maxBodySizein both places:lib/config.js:maxBodySize: process.env.CAMOFOX_MAX_BODY_SIZE || '100kb'express.json({ limit: CONFIG.maxBodySize })express.json({ limit: CONFIG.maxBodySize })The cookies endpoint (
512kb) and extract endpoint (256kb) are intentionally unchanged — they have their own specific limits.Usage
Closes #8397