Skip to content

fix: Respect robots.txt by default in website-content-crawler - #1581

Closed
jirispilka wants to merge 2 commits into
masterfrom
fix/wcc-respect-robots-default
Closed

jirispilka wants to merge 2 commits into
masterfrom
fix/wcc-respect-robots-default

Conversation

@jirispilka

@jirispilka jirispilka commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Why

Closes #1574.

apify/website-content-crawler declares respectRobotsTxtFile with default: false (the Console prefills true, which API runs don't get). A tool call that omits the field crawls without consulting robots.txt. The Actor's default stays as is; this server sets it.

What changed

Tool contract change: the WCC input schema now serves default: true for respectRobotsTxtFile.

  • The apify--website-content-crawler tool schema and fetch-actor-details for WCC show default: true.
  • The direct tool, call-actor and call-actor-widget send respectRobotsTxtFile: true when the caller omits it. An explicit false or true is kept. AJV here does not apply schema defaults, and the platform would fill the Actor's own false, so the value is set when the run starts.
  • call-actor is included because it prints the same tool schema in its errors and points to fetch-actor-details for the schema; all of them now agree.
  • Other Actors are unchanged. Runs started by schedules or saved tasks still get the Actor's own default.

We don't like this. A per-Actor default table (SERVED_INPUT_DEFAULTS) that the schema step and the run-start step both read is a special case in server code for one Actor's input. We don't see a better way: the Actor's default can't change, AJV here doesn't fill defaults, and turning that on (useDefaults) would make every Actor's defaults explicit in stored INPUT, which is a wider change than this fix. If a cleaner hook turns up, the table is the only thing to move.

Notes for reviewers (human-written)

Proof it works

mcpc against a local stdio build (0.18.3 + this branch).

tools-get apify--website-content-crawler, respectRobotsTxtFile (before: "default": false):

{
  "title": "Respect the robots.txt file",
  "description": "If enabled, the crawler will consult the robots.txt file for the target website before crawling each page. At the moment, the crawler does not use any specific user agent identifier. The crawl-delay directive is also not supported yet.\nExample values: true",
  "type": "boolean",
  "default": true,
  "prefill": true,
  "examples": [true]
}

fetch-actor-details for apify/website-content-crawler shows the same "default": true.

One crawl with the Claude connector tool set, field omitted: apify--website-content-crawler with {"startUrls":[{"url":"https://example.com"}],"maxCrawlPages":1,"crawlerType":"cheerio"} → run gBo139MGZuHIHFUrY, SUCCEEDED, 1 page. Its stored INPUT (apify key-value-stores get-value NzdUXEc9BxZobpfKg INPUT) has "respectRobotsTxtFile": true. That run used an earlier revision of this branch, where only the direct tool filled the value; the direct-tool path is the same in this revision. The call-actor and widget paths are covered by unit tests, including a call by Actor ID.

The new tests failed on master.

AI-assisted: Claude Code wrote the change, tests and this description, and ran the mcpc probes and the crawl.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CPzYK17FoL2F3cuVonqnej


Generated by Claude Code

The Actor declares respectRobotsTxtFile with default false, so an API run
that omits it ignores robots.txt. The website-content-crawler tool and
fetch-actor-details now show default true, and the direct tool,
call-actor and call-actor-widget send true when the caller omits the
field. An explicit false is kept.

Closes #1574

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@jirispilka

Copy link
Copy Markdown
Collaborator Author

Closed in favor of #1585, which combines this change and the input restrictions from #1580 in one declarative direct-tool contract. This keeps the served schema, validation, run input, and annotations consistent.

The agreed scope is the direct WCC tool: respectRobotsTxtFile defaults to true, and an explicit false is preserved. Generic Actor calls, widgets, and Actor details retain the original Actor input contract.

#1586 is a separate PR stacked on #1585 that moves the existing RAG Web Browser and Web Fetch presentation rules into the same registry without changing their behavior.

jirispilka added a commit that referenced this pull request Oct 15, 2026
## Why

Closes #1574. Closes #1575. Supersedes #1580 and #1581.

WCC's API defaults robots.txt handling to false. Its direct MCP tool
also accepts page code and session cookies, preventing read-only
classification under the existing rule.

## What changed

One declarative direct-tool policy controls defaults, denied inputs, and
restriction text. The factory derives annotations from permitted inputs
while retaining ownership, permission, and side-effect checks.

For `apify--website-content-crawler`, robots.txt defaults to true and
explicit false remains valid. `pageFunction` and `initialCookies` are
absent from the offered properties, and the call engine refuses a call
that carries either before validation runs, so no run starts even when
AJV would otherwise strip an undeclared field. The served schema stays a
plain object: OpenAI rejects a function schema with `allOf`, `anyOf`,
`oneOf` or `not` at the top level, strict or not.

Generic calls, widgets, and Actor details keep the original Actor input
contract. Restricted direct-tool errors point to their own tools/list
schema. Other Actors are unchanged.

Contract change: WCC's direct input schema, description, validation, and
annotations. Applies to the hosted server through the core package; no
internal exports, shared types, result shapes, or client-specific
routing changed.

## Notes for reviewers (human-written)

## Proof it works

- New regression tests failed before implementation. Final suite: 2,661
passed, 1 skipped. Type-check, lint, format, check:agents, and build
passed.
- mcpc on the local build: WCC has read-only/non-destructive/open-world
annotations; the three other direct tools retain their annotations. Both
denied fields were refused with an error naming them, and no run
started. Other validation errors point to tools/list.
`fetch-actor-details` and a `call-actor` validation error still show the
original schema with both fields and `default: false`.
- The exact served WCC schema is accepted by OpenAI's Responses API
(HTTP 200). The earlier `allOf` version was refused with HTTP 400
("schema must have type 'object' and not have
'oneOf'/'anyOf'/'allOf'/'enum'/'const'/'not' at the top level").
- One-page [Actor
run](https://console.apify.com/actors/runs/iaftEn6QeCMUKorMX) succeeded
with the robots.txt field omitted. `apify key-value-stores get-value
qEgw9ZA6yIZ6u5WQh INPUT` confirmed `respectRobotsTxtFile: true`. A
second one-page run on the final head (`ykzc28KDS26DtXPq1`) stored
`respectRobotsTxtFile: true` in `vXvkNIfxOm7acBeWl` with neither denied
field present.
- Generic and widget regression tests use the real factory and
validator, including lookup by Actor ID, to verify original
inputs/defaults and error schemas.

AI-assisted: Codex wrote the implementation, tests, documentation, and
this description, ran verification, and used an independent review
agent. Claude Code reviewed the PR, replaced the schema-level `allOf`
denial with the call-engine check after finding the OpenAI rejection,
and reran the mcpc checks and the second run.

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

fix: Default respectRobotsTxtFile to true in the website-content-crawler tool

3 participants