How the LinkedIn Channel Routes Requests Between linkedin-mcp and Jina Reader Backends

The LinkedIn channel automatically routes requests to the linkedin-scraper-mcp backend when the mcporter CLI is detected and configured, otherwise falling back to Jina Reader, with the active_backend attribute determining the runtime dispatch path.

The Agent-Reach repository implements a robust LinkedIn integration that transparently switches between two distinct backends. Understanding how the LinkedIn channel routes requests between the linkedin-mcp and Jina Reader backends reveals a sophisticated health-check mechanism that prioritizes structured data extraction while maintaining universal accessibility.

Backend Declaration and MCP Health Detection

Declaring Available Backends

In agent_reach/channels/linkedin.py, the LinkedInChannel class explicitly declares its supported backends:

backends = ["linkedin-scraper-mcp", "Jina Reader"]

This ordered list establishes the preference hierarchy, with the MCP server offering richer structured data and Jina Reader providing a reliable fallback.

Probing the MCP Server

The check() method determines availability by probing the local mcporter installation using the probe_command utility from agent_reach/probe.py:

probe = probe_command("mcporter", ["config", "list"], timeout=10, package="mcporter")

If the probe succeeds and the output contains the string "linkedin", the channel sets:

self.active_backend = "linkedin-scraper-mcp"

Otherwise, the channel remains operational but relies on the Jina Reader fallback, ensuring continuous functionality even without the MCP server installed.

Runtime Routing Logic in BaseChannel

The actual request dispatch occurs in the BaseChannel class defined in agent_reach/channels/base.py. When read() or search() methods are invoked, the base class inspects self.active_backend to determine which concrete implementation to execute.

linkedin-scraper-mcp path: When active_backend equals "linkedin-scraper-mcp", the channel delegates to the MCP server via the run_backend helper, executing structured profile extraction through the npm-based MCP server.

Jina Reader fallback: If active_backend is unset or the MCP probe failed, requests route to the Jina Reader API, which fetches raw HTML and extracts textual content without requiring local MCP infrastructure.

Practical Implementation Examples

The following examples demonstrate how the routing operates in practice:


# Automatic backend selection

from agent_reach.core import AgentReach

ar = AgentReach()
profile = ar.read("https://www.linkedin.com/in/jane-doe-12345")
print(profile)  # Structured data if MCP active, plain text otherwise

For advanced use cases, you can inspect the backend selection explicitly:

from agent_reach.channels.linkedin import LinkedInChannel

chan = LinkedInChannel()
chan.check()  # Detects active_backend based on mcporter probe

if chan.active_backend == "linkedin-scraper-mcp":
    data = chan.read("https://www.linkedin.com/jobs/view/123456")
else:
    data = chan.read("https://www.linkedin.com/jobs/view/123456")
print(data)

Key Source Files and Responsibilities

  • agent_reach/channels/linkedin.py: Defines the LinkedInChannel class, declares the backends list, and implements the check() method that sets active_backend based on mcporter probe results.

  • agent_reach/channels/base.py: Contains the generic BaseChannel class that routes requests to the backend specified in self.active_backend.

  • agent_reach/probe.py: Provides the probe_command utility used to detect external tool availability and configuration.

  • agent_reach/core.py: Exposes the public AgentReach facade that forwards requests to the appropriate channel.

Summary

  • The LinkedIn channel maintains a backends list prioritizing "linkedin-scraper-mcp" over "Jina Reader".
  • The check() method probes mcporter via probe_command to determine if the MCP server is configured for LinkedIn scraping.
  • The active_backend attribute stores the runtime selection, driving the routing decision in BaseChannel.
  • Requests automatically fall back to Jina Reader when the MCP server is unavailable, ensuring graceful degradation.
  • All routing logic is implemented in the open-source Agent-Reach repository under the agent_reach/channels/ directory.

Frequently Asked Questions

What triggers the fallback to Jina Reader?

The fallback activates when the probe_command call to mcporter fails, returns no output, or lacks the "linkedin" configuration string. In these cases, active_backend remains unset or inaccessible, causing BaseChannel to route requests to the Jina Reader API instead of attempting MCP server communication.

How does the channel detect if linkedin-mcp is available?

Detection occurs through the check() method in LinkedInChannel, which executes probe_command("mcporter", ["config", "list"], timeout=10, package="mcporter"). If this command exits successfully and its output contains the substring "linkedin", the channel sets active_backend = "linkedin-scraper-mcp" and subsequent requests use the MCP backend.

Can I force the channel to use a specific backend?

While the public AgentReach API abstracts backend selection, you can instantiate LinkedInChannel directly and manually assign chan.active_backend = "linkedin-scraper-mcp" or "Jina Reader" before calling read() or search(). Note that manual override bypasses the automatic health checking provided by the check() method.

Where is the routing logic implemented?

The routing logic spans two files: agent_reach/channels/linkedin.py sets the active_backend attribute during initialization based on the mcporter probe, while agent_reach/channels/base.py implements the actual dispatch logic that reads this attribute and delegates to the appropriate backend handler.

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 →