diff --git a/apify/agents/apify.agent.md b/apify/agents/apify.agent.md index 2a57d10..4d1485b 100644 --- a/apify/agents/apify.agent.md +++ b/apify/agents/apify.agent.md @@ -29,23 +29,28 @@ For Route 1, prefer MCP tools for straightforward tasks. Only invoke the `apify- ## MCP vs CLI selection -Route 1 (use existing Actors: search, fetch details, run, get results, look up docs) is exposed through **two interchangeable transports**: the Apify MCP server and the Apify CLI. Routes 2 and 3 are CLI-only or SDK-only by nature and are unaffected by this section. +Route 1 (use existing Actors: search, fetch details, run, get results, look up docs) is exposed through **two transports**: the Apify MCP server and the Apify CLI. They are usually interchangeable, but not always — an unauthenticated MCP server can search Actors without being able to run them (see Detection). Routes 2 and 3 are CLI-only or SDK-only by nature and are unaffected by this section. Detect available transports **once** at the start of the conversation and reuse the result for every Route 1 operation. Skills downstream (`apify-ultimate-scraper`, etc.) provide both MCP and CLI variants per step — they will not re-detect. ### Detection -1. **MCP available** if a tool named `search-actors` appears in your available tool list. (Other Apify MCP tools — `fetch-actor-details`, `run-actor`, `get-dataset-items`, `search-apify-docs`, `fetch-apify-docs` — are part of the same server.) -2. **CLI available** if `apify --help` exits 0 in the shell. +MCP state — judge by capability, not tool names: +- **full**: run Actors and tasks, read datasets and key-value stores, search Actors, fetch Actor details, search and fetch docs +- **discovery-only**: search Actors, fetch Actor details, search and fetch docs only (not authenticated) +- **none**: no Apify MCP tools present + +CLI: **installed** if `apify --help` exits 0; **usable** if `apify info 2>&1` also exits 0. ### Selection rule | MCP | CLI | Use for Route 1 | |-----|-----|-----------------| -| yes | yes | **MCP** (no shell, no install friction, OAuth handles auth) | -| yes | no | MCP | -| no | yes | CLI | -| no | no | Offer to install the CLI (`npm install -g apify-cli`) or point the user to a host that ships the Apify MCP server (`https://mcp.apify.com`). Do not attempt Route 1 until one is available. | +| full | any | **MCP** (no shell, no install friction, auth is handled by the host) | +| discovery-only | usable | **MCP for discovery, CLI for runs and results** | +| discovery-only | not usable | Discovery over MCP. For anything authenticated there is **no transport** — report that, and see Authentication for the fix | +| none | usable | CLI | +| none | not usable | Offer to install the CLI (`npm install -g apify-cli`) or point the user to a host that ships the Apify MCP server (`https://mcp.apify.com`). Do not attempt Route 1 until one is available. | Route 2 always requires the CLI regardless of MCP availability — `apify init`, `apify run`, and `apify push` operate on the local filesystem and have no MCP equivalent. Route 3 uses the `apify-client` package over HTTPS and needs neither. @@ -59,16 +64,16 @@ State the chosen transport once when you start a Route 1 task ("Using MCP for th Three auth flows exist. Use the correct one based on the route: -- **Route 1 (MCP):** OAuth. No setup needed. The user will be prompted to sign in via browser on first MCP tool call that requires auth. Do not ask for an API token. -- **Route 1 (CLI fallback) and Route 2 (CLI):** The CLI **ignores** the `APIFY_TOKEN` env var. Run `apify login --token TOKEN` once (requires `required_permissions: ["all"]` in Cursor). Credentials are stored in `~/.apify/auth.json` and reused automatically. Token from: https://console.apify.com/settings/integrations +- **Route 1 (MCP):** If your Apify MCP tools already cover authenticated operations, auth is working — say nothing. OAuth is the preferred auth method, but if the host does not support it, direct the user to set `APIFY_TOKEN`. Token from: https://console.apify.com/settings/integrations +- **Route 1 (CLI fallback) and Route 2 (CLI):** Prefer `apify login` (opens browser) — credentials persist in `~/.apify/auth.json`. In headless environments, the CLI also reads `APIFY_TOKEN` from the environment automatically. Token from: https://console.apify.com/settings/integrations - **Route 3 (SDK):** Requires `APIFY_TOKEN` environment variable. Direct the user to **Console > Settings > Integrations** at https://console.apify.com/settings/integrations to create one. If they don't have an account, point them to https://console.apify.com/sign-up (free, no credit card). ### Apify CLI instructions: -- Before using the CLI, always check if it is installed (always check first, with short `block_until_ms` to avoid blocking the conversation): +- Before using the CLI, always check if it is installed. Keep the timeout short so the check cannot stall the conversation: ```bash apify --help ``` -- If the CLI is installed, check if it is logged in (always check, with short `block_until_ms` to avoid blocking the conversation): +- If the CLI is installed, check if it is logged in. Keep the timeout short so the check cannot stall the conversation: ```bash # Auth check — do NOT pipe to /dev/null, you need to see errors apify info 2>&1 @@ -77,15 +82,15 @@ Three auth flows exist. Use the correct one based on the route: ```bash apify login --token TOKEN ``` -- All of the APify commands needs to be run with the all permissions (depends on Agent sandbox) -- Apify commands blocks with **zero output** until the run completes. Set `block_until_ms` to at least **60000** (60s). +- Authenticated Apify CLI commands need file access to `~/.apify/`, where the CLI keeps its credentials. A host that sandboxes file access can deny this even when the login is valid — that is a sandbox problem, not a login problem, so re-running `apify login` will not fix it. Grant the CLI file access in whatever way the host offers, or authenticate MCP and run through it instead. +- Apify commands block with **zero output** until the run completes, so allow at least **60 seconds** before treating one as stuck. If your shell tool takes a timeout, raise it accordingly. - For long/unknown runs, use the async pattern instead: ```bash apify actors start "ACTOR_ID" -i 'JSON_INPUT' --json 2>/dev/null ``` -Then poll with `apify info`: +Then poll with `apify runs info`: ```bash - apify info actor-runs/RUN_ID --json + apify runs info RUN_ID --json ``` Check `.status` for `SUCCEEDED` or `FAILED`. ## Resources diff --git a/apify/skills/apify-ultimate-scraper/SKILL.md b/apify/skills/apify-ultimate-scraper/SKILL.md index 787b422..480fa1d 100644 --- a/apify/skills/apify-ultimate-scraper/SKILL.md +++ b/apify/skills/apify-ultimate-scraper/SKILL.md @@ -60,9 +60,9 @@ If this fails, install the CLI first: apify login --token TOKEN ``` -3. Run Apify CLI commands with `all` permissions when needed by the agent sandbox. +3. Authenticated Apify CLI commands need file access to `~/.apify/`, where the CLI keeps its credentials. A host that sandboxes file access can deny this even when the login is valid; that is a sandbox problem, not a login problem. -4. Assume many Apify commands block with zero output until completion. For blocking runs, set `block_until_ms` to at least `60000`. +4. Assume many Apify commands block with zero output until completion, so allow at least 60 seconds before treating one as stuck. If your shell tool takes a timeout, raise it accordingly. 5. For long or unknown-duration runs, prefer the async pattern: @@ -73,7 +73,7 @@ If this fails, install the CLI first: Then poll the run status: ```bash - apify info actor-runs/RUN_ID --json + apify runs info RUN_ID --json ``` Check `.status` for `SUCCEEDED` or `FAILED`. @@ -167,7 +167,7 @@ For CSV: `apify datasets get-items DATASET_ID --format csv` ```bash apify actors start "ACTOR_ID" -i 'JSON_INPUT' --json 2>/dev/null ``` -Poll: `apify info actor-runs/RUN_ID --json` (check `.status` for `SUCCEEDED` or `FAILED`). +Poll: `apify runs info RUN_ID --json` (check `.status` for `SUCCEEDED` or `FAILED`). ### Step 4: Deliver results