Skip to content

Add the Apify CLI and mcpc as a surface - #36

Open
RobertCrupa wants to merge 1 commit into
stack/3-surfacesfrom
stack/4-cli-surface
Open

RobertCrupa wants to merge 1 commit into
stack/3-surfacesfrom
stack/4-cli-surface

Conversation

@RobertCrupa

@RobertCrupa RobertCrupa commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Stack 4 of 4, on top of #35.

The cli surface gives the agent the Apify CLI and mcpc in Bash. The agent has no MCP tools of its own.

What changes

  • Image: pins apify-cli 1.10.0 and @apify/mcpc 0.7.0, off PATH. The cliVersion and mcpcVersion inputs install another build at run time.
  • Per-session wrappers: the CLI logs in once per run, with file credentials, because the CLI ignores APIFY_TOKEN. mcpc connects to the Apify MCP server as @apify before the agent starts, and closes after. Neither reads the developer's login or Keychain. On a surface without them, the wrappers also hide any apify or mcpc that is on PATH.
  • Evidence:
    • A Node preload adds the session marker to the CLI's API requests, so the runner finds apify call -s runs, which print no run id.
    • The runner reads run ids from mcpc output and arguments.
    • The runner finds runs through the dataset ids that mcpc prints.
  • Preflight: runs apify info and an mcpc connect.

Tests: workflow-runner 108 (14 new for the CLI surface).

@RobertCrupa
RobertCrupa added this pull request to stack #40 October 19, 2026 11:43
@artogahr artogahr added the adhoc Ad-hoc unplanned task added during the sprint. label Oct 19, 2026
const home = mkdtempSync(join(tmpdir(), 'eval-session-'));
try {
const shimDir = ctx.surface ? installCliShim(home, ctx.surface, ctx.runMarker) : undefined;
if (ctx.surface?.mcpcBinDir) await connectMcpc(home, ctx.surface, ctx.mcpUrl);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This connects to the bare MCP URL, and surfaceItemMetadata sets tools: [] for the cli surface. So the cli agent sees the server's default tool set while the mcp agent sees the scenario's allowlist. An mcp vs cli comparison then compares two different setups. Either pass the item's tools into the connect URL or if not possibe we should probably document the difference?

Comment on lines +295 to +304
export async function connectMcpc(sessionHome: string, surface: ResolvedSurface, mcpUrl: string): Promise<void> {
if (!surface.mcpcBinDir) return;
const token = surface.env.APIFY_TOKEN;
if (!token) throw new Error(`surface "${surface.name}": mcpc needs APIFY_TOKEN in the surface env`);
await execFile(
join(sessionHome, 'bin', 'mcpc'),
['connect', mcpUrl, MCPC_SESSION, '--header', `Authorization: Bearer ${token}`],
{ timeout: 60_000, env: { PATH: process.env.PATH, HOME: sessionHome } },
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this connect call fails once, the whole session fails and is counted as not completed. On the mcp surface the session is retried when the MCP server doesn't answer at startup. Can we retry here too?

The `cli` surface gives the agent the Apify CLI and mcpc in Bash, with
no MCP tools of its own.

- The image pins apify-cli 1.10.0 and @apify/mcpc 0.7.0 off PATH;
  `cliVersion` and `mcpcVersion` install another build at run time.
- Each session gets its own wrappers: the CLI logged in once per run
  with file credentials, mcpc connected to the Apify MCP server as
  @apify and closed after. Neither reads the developer's login or
  Keychain, and a surface without them hides any on PATH.
- A Node preload marks the CLI's API requests with the session marker,
  so `apify call -s` runs are found. Evidence reads run ids and dataset
  ids from mcpc output and arguments.
- Preflight checks `apify info` and an mcpc connect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

adhoc Ad-hoc unplanned task added during the sprint.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants