How the `contacto` Mode Discovers and Drafts LinkedIn Messages to Hiring Managers

The contacto mode is a read-only outreach assistant that uses web search to find hiring managers and recruiters, classifies each contact by type, selects a primary target, and generates a tailored three-sentence LinkedIn message while enforcing platform character limits and requiring manual confirmation before saving any contact.

The contacto mode in the santifer/career-ops repository automates the research and composition stages of job-search outreach without ever automating delivery. By combining deterministic web search with a templated message framework, it gives candidates a reproducible pipeline for discovering the right stakeholder and drafting a concise, policy-compliant introduction. This article breaks down exactly how the mode discovers contacts, selects the best target, and drafts LinkedIn messages grounded in the source code.

How the contacto Mode Discovers Hiring Managers and Recruiters

The pipeline begins with a WebSearch query scoped to the role the candidate is targeting. According to the specification in modes/contacto.md, the search locates four distinct contact types: Hiring Manager, Recruiter, Peer, and Interviewer (lines 23–27). These results form the initial candidate pool that the mode will classify and prioritize.

Contact Classification and Primary Target Selection

Once search results are returned, the mode classifies each person by type. It either prompts the candidate directly or infers the role from the search context (lines 29–33). After classification, the system selects the primary target—the single person who stands to gain the most from receiving the candidate’s outreach (line 35). This step ensures the message is directed at the decision-maker or best-connected stakeholder rather than blasting a generic note to multiple recipients.

Drafting LinkedIn Messages Using the Three-Sentence Framework

Message generation follows a strict three-sentence framework tailored to the contact type (lines 38–59). Each template respects the candidate’s language output setting and any channel preference stored in config/profile.yml (lines 76–85).

Recruiter Outreach: Fit, Proof, CTA

For recruiters, the structure is Fit, Proof, CTA. The first sentence establishes role fit, the second provides concise proof, and the third delivers a clear call-to-action.

Hiring Manager Outreach: Hook, Proof, CTA

For hiring managers, the structure shifts to Hook, Proof, CTA. The opening sentence grabs attention with a relevant hook, followed by evidence of value and a closing ask.

Peer Outreach: Interest, Connection, CTA

Peer messages use Interest, Connection, CTA and explicitly omit a job pitch. The goal is relationship-building rather than immediate role solicitation.

Interviewer Outreach: Research, Context, CTA

For interviewers, the framework is Research, Context, CTA. The message demonstrates pre-interview research and frames the candidate’s background in the context of the team’s work.

Enforcing LinkedIn Character Limits and Tier Rules

Before returning the draft, the mode enforces LinkedIn’s connection-request limits. Free accounts are constrained to 200 characters, while Premium and Sales Navigator tiers allow 300 characters (lines 90–94). The mode trims the output to fit unless the user has explicitly confirmed a higher tier in their configuration.

Safely Saving Contacts to the Phone-Book

The contacto mode never saves contacts automatically. After the user approves a target, it offers to append the record to data/contacts.tsv using the required TSV schema (lines 67–73). All scraped LinkedIn and company-profile text is treated as untrusted external content used for data only (line 5).

For export, contacts.mjs provides deterministic vCard generation through its buildVcf and contactUid functions (lines 38–45). You can generate a vCard from the stored TSV phone-book by running:

node contacts.mjs --vcf

The test suite enforces the “Never save” rule, verifying that no contact is persisted without explicit user confirmation (test-all.mjs, lines 3710–3715).

Running the contacto Mode

To start an interactive outreach session from the repository root:

career-ops contacto

This prompts for the target role or job description, executes the discovery pipeline, and returns a draft message ready for manual review.

Summary

  • The contacto mode launches a WebSearch to find Hiring Managers, Recruiters, Peers, and Interviewers for a target role.
  • It classifies each result and selects a primary target who benefits most from outreach.
  • Messages follow a type-specific three-sentence framework (Fit/Proof/CTA, Hook/Proof/CTA, Interest/Connection/CTA, or Research/Context/CTA).
  • Output is capped at 200 characters for free LinkedIn accounts and 300 characters for Premium tiers.
  • Contacts are only saved to data/contacts.tsv after explicit user confirmation, with optional vCard export handled by contacts.mjs.

Frequently Asked Questions

What contact types does the contacto mode search for?

The mode searches for four contact types: Hiring Manager, Recruiter, Peer, and Interviewer. It classifies each result either by asking the candidate or by inferring the role from the search context.

How does contacto decide which hiring manager to message?

After classification, the mode selects the primary target—the single person who will gain the most value from the candidate’s outreach. This prevents generic mass-messaging and focuses the draft on the most relevant stakeholder.

Can the contacto mode automatically send LinkedIn messages?

No. The contacto mode is read-only and does not automate delivery. It drafts the message for manual review, and it never saves a contact to data/contacts.tsv without explicit user confirmation, as enforced by the test suite.

Where does the mode read language and channel preferences?

It reads config/profile.yml for the candidate’s language output setting and contact_preferences.preferred_channel. These values shape the greeting, call-to-action, and overall character budget.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →