Skip to content

feat(jobs): add optional file output to job tools#519

Draft
ghul0 wants to merge 1 commit into
stickerdaniel:mainfrom
ghul0:feature/518-job-output-file
Draft

feat(jobs): add optional file output to job tools#519
ghul0 wants to merge 1 commit into
stickerdaniel:mainfrom
ghul0:feature/518-job-output-file

Conversation

@ghul0

@ghul0 ghul0 commented Jun 18, 2026

Copy link
Copy Markdown

Summary

Adds an optional file-output mode to the two job tools so results can be written to disk instead of (or alongside) being returned to the MCP client. Implements #518.

Job results are large; fanning an agent over many postings and returning every full payload into the model context burns the window fast. With output_mode="file" the tool persists the result and returns only a compact confirmation, so an agent can scrape many jobs without flooding context, hand the files to a downstream step (CV tailoring, scoring, human review), and keep a local record.

What's in scope

  • Two new optional parameters on get_job_details and search_jobs:
    • output_mode: "display" | "file" | "both" — default "display", which is the existing behaviour unchanged.
    • output_path: str | None — required when mode is file/both. The extension drives the format: .json dumps the full result dict; any other extension writes a readable text rendering of url/sections/job_ids.
  • New apply_output_mode(result, output_path, output_mode) in common_utils.py, reusing the existing secure_write_text helper (atomic temp-file write, 0o600) so file writes stay safe and consistent with the rest of the module.
  • In file mode the tool returns a compact confirmation (saved_path, url, job_ids, section names) instead of the full payload; both writes and still returns the full result.
  • Tests: tests/test_common_utils.py::TestApplyOutputMode (display/file/both, .json vs text rendering, missing-path ValueError, ~ expansion) and tool-level pass-through tests in tests/test_tools.py (file mode returns confirmation + writes the file; default mode still returns content).
  • Docs: README tool table, docs/docker-hub.md, manifest.json.

Intentionally out of scope

  • Only the two job tools are wired up. apply_output_mode is generic and can wrap other tools later if there's appetite, but this PR keeps the surface small and reviewable.
  • No change to the default return contract — display callers see identical behaviour.

Testing

  • uv run pytest: 551 passed locally. One pre-existing failure in test_browser_security.py::test_harden_linkedin_tree_noop_outside_linkedin reproduces on main before this branch with umask=002; it's environmental and unrelated.
  • uv run ruff check .: clean. uv run ty check: clean.
  • manifest.json validated as JSON.

Synthetic prompt

Add an optional file-output mode to get_job_details and search_jobs: two new params output_mode ("display" default | "file" | "both") and output_path. Implement a generic apply_output_mode(result, output_path, output_mode) in common_utils.py that reuses the existing secure_write_text (atomic, 0o600); .json dumps the full dict, other extensions write a readable url/sections/job_ids rendering. In "file" mode return a compact confirmation (saved_path, url, job_ids, section names) instead of the full payload; "both" writes and returns full; "display" is unchanged. Thread the params through both job tools, add unit tests for the helper and tool-level pass-through tests, and update README, docs/docker-hub.md, and manifest.json.

Generated with Claude Opus 4.7

Closes #518

Closes stickerdaniel#518.

get_job_details and search_jobs gain two optional parameters:

- output_mode: "display" (default, unchanged) | "file" | "both"
- output_path: target path; the extension selects the format (.json
  dumps the full result dict, any other extension writes a readable
  text rendering of url/sections/job_ids).

In "file" mode the tool persists the result and returns a compact
confirmation (saved_path, url, job_ids, section names) instead of the
full payload, so an agent can fan out over many postings without
flooding the model context. "both" writes the file and still returns
the full result. "display" preserves the existing behaviour exactly.

The new apply_output_mode helper lives in common_utils.py and reuses
the existing secure_write_text (atomic temp-file write, 0o600).

Tests: unit coverage for apply_output_mode (display/file/both, json vs
text rendering, missing-path error, ~ expansion) plus tool-level
pass-through tests. Docs: README, docs/docker-hub.md, manifest.json.
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.

[FEATURE] Optional file output for get_job_details / search_jobs

1 participant