logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

merge-mcp-adapter

Facilitates connection between the Merge API ecosystem and arbitrary Large Language Model platforms adhering to the MCP specification. This enables conversational access for reading, synthesizing, and modifying data objects across various Merge categories such as Human Resources Information Systems (HRIS) and Applicant Tracking Systems (ATS).

Author

merge-mcp-adapter logo

merge-api

No License

Quick Info

GitHub GitHub Stars 15
NPM Weekly Downloads 0
Tools 1
Last Updated 2026-02-19

Tags

mergetoolsapimerge apitools mergeapi merge

Merge MCP Server Implementation

This Model Context Protocol (MCP) service acts as a bridge, translating natural language requests from an MCP-compatible LLM provider (like Claude Desktop) into actionable calls against the Merge API, providing deep, context-aware data interaction.

Key Capabilities

  • Natural Language Data Access: Formulate queries against Merge entities using plain English.
  • Schema Introspection: Programmatically retrieve metadata regarding available Merge data structures and their constituent attributes.
  • Transactional Operations: Execute data creation and modification requests via conversational prompts.
  • Broad Coverage: Supports integration across major Merge domains, including HRIS, ATS, and others.

📦 Setup Guide

Prerequisites

Before deployment, ensure you have the following:

  1. Valid credentials for the Merge API (Key and Account Token).
  2. Python version 3.10 or newer installed.
  3. The uv package manager utility installed.

Install uv using its dedicated installer script: bash

For Unix-like systems (macOS/Linux).

curl -LsSf https://astral.sh/uv/install.sh | sh

For Windows environments (PowerShell).

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Alternatively, use standard Python tooling: bash

Using pip.

pip install uv

Using pipx.

pipx install uv

🔌 MCP Configuration

This configuration block is typically placed within the host LLM application's MCP settings file (e.g., claude_desktop_config.json).

{ "mcpServers": { "merge-mcp-adapter": { "command": "uvx", "args": ["merge-mcp"], "env": { "MERGE_API_KEY": "your_api_key", "MERGE_ACCOUNT_TOKEN": "your_account_token" } } } }

Note: If the uvx executable is not found in your PATH, substitute it with the full absolute path (e.g., /home/user/.local/bin/uvx).

Example Integration with Claude Desktop

  1. Confirm uvx is accessible in your terminal.
  2. Download and install Claude Desktop.
  3. Access the configuration editor within the application: Settings → Developer → Edit Config to open claude_desktop_config.json.
  4. Insert the JSON snippet above into the appropriate section.
  5. Crucially, replace placeholders (your_api_key, your_account_token) and ensure the executable path (uvx) is correct based on your system.
  6. Save the file and relaunch Claude Desktop for the new tool service to initialize.

Example Python Client Setup (client.py)

Environment Setup: bash

Initialize project structure

mkdir mcp-client && cd mcp-client python -m venv .venv && source .venv/bin/activate # (Use .venv\Scripts\activate on Windows)

Install dependencies

pip install mcp uv anthropic python-dotenv touch client.py

Credentials Management: bash

Securely store keys (create .env)

echo "ANTHROPIC_API_KEY=" >> .env echo "MERGE_API_KEY=" >> .env echo ".env" >> .gitignore

Core Client Class Structure: python import os import asyncio from typing import Optional from contextlib import AsyncExitStack

from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client

from anthropic import Anthropic from dotenv import load_dotenv

load_dotenv() # Load keys from .env file

class MCPClient: def init(self): self.session: Optional[ClientSession] = None self.exit_stack = AsyncExitStack() self.anthropic = Anthropic()

# --- Connection and Execution Methods defined below ---

Connection Method (connect_to_server): python async def connect_to_server(self, token_for_linked_account: str): """Establishes the asynchronous communication channel to the MCP server.""" server_params = StdioServerParameters( command="uvx", args=["merge-mcp"], env={ "MERGE_API_KEY": os.getenv("MERGE_API_KEY"), "MERGE_ACCOUNT_TOKEN": token_for_linked_account } )

stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
self.stdio, self.write = stdio_transport
self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))

await self.session.initialize()

# Verify connection by listing available functions
response = await self.session.list_tools()
print(f"\nSuccessfully connected. Tools exposed: {[tool.name for tool in response.tools]}")

Query Processing Method (process_query): python async def process_query(self, user_input: str) -> str: """Handles the full LLM interaction loop, including tool invocation/feedback.""" current_messages = [{"role": "user", "content": user_input}]

tool_definitions = await self.session.list_tools()
available_tools = [
    {"name": t.name, "description": t.description, "input_schema": t.inputSchema} 
    for t in tool_definitions.tools
]

# 1. Initial API call to Claude
response = self.anthropic.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1000,
    messages=current_messages,
    tools=available_tools
)

final_output_log = []
# Process Claude's initial output
for content_block in response.content:
    if content_block.type == 'text':
        final_output_log.append(content_block.text)
        current_messages.append({"role": "assistant", "content": [content_block]})

    elif content_block.type == 'tool_use':
        tool_name = content_block.name
        tool_args = content_block.input

        # User confirmation step
        confirm = input(f"Execute tool '{tool_name}' with args {tool_args}? (y/n): ").strip().lower()

        if confirm.startswith('y'):
            tool_result = await self.session.call_tool(tool_name, tool_args)
            final_output_log.append(f"[Tool Execution Successful: {tool_name}]")

            # Append tool use to messages
            current_messages.append({"role": "assistant", "content": [content_block]})

            # Append tool result to messages
            result_content = {"type": "tool_result", "tool_use_id": content_block.id, "content": tool_result.content}
            current_messages.append({"role": "user", "content": [result_content]})

            # 2. Secondary API call using the tool result
            final_response = self.anthropic.messages.create(
                model="claude-3-5-sonnet-20241022",
                max_tokens=1000,
                messages=current_messages,
                tools=available_tools
            )
            final_output_log.append(final_response.content[0].text)
        else:
            final_output_log.append(f"[Tool Execution Declined: {tool_name}]")

return "\n".join(final_output_log)

Interactive Loop and Cleanup: python async def run_interactive_session(self): """Manages the continuous user interaction session.""" print("\n--- Merge MCP Client Activated ---") print("Enter 'exit' or 'quit' to terminate.")

    while True:
        try:
            user_prompt = input("\nUSER PROMPT: ").strip()

            if user_prompt.lower() in ('quit', 'exit'):
                break

            result_text = await self.process_query(user_prompt)
            print("\n--- LLM RESPONSE ---\n" + result_text)

        except Exception as e:
            print(f"\nCRITICAL ERROR encountered: {type(e).__name__}: {str(e)}")
            break

async def shutdown(self):
    """Gracefully close all open asynchronous resources."""
    await self.exit_stack.aclose()

async def entrypoint(): client = MCPClient() try: # IMPORTANT: Replace placeholder token await client.connect_to_server("") await client.run_interactive_session() finally: await client.shutdown()

if name == "main": asyncio.run(entrypoint())

Execution: bash python client.py

🔒 Access Control (Scopes)

Scopes define the granular permissions granted to the adapter, dictating which Merge API endpoints are exposed as callable tools. If no scopes are explicitly set, the system defaults to enabling all accessible operations.

To constrain functionality, supply the --scopes argument when invoking merge-mcp:

{ "mcpServers": { "merge-mcp-adapter": { "command": "uvx", "args": [ "merge-mcp", "--scopes", "ats.Job:read", "ats.Candidate", "ats.Application:write" ], "env": { "MERGE_API_KEY": "your_api_key", "MERGE_ACCOUNT_TOKEN": "your_account_token" } } } }

Scope Syntax

Permissions adhere to a structured format:

<API_Category>.<Common_Model_Name>:<Access_Level>

Where: * <API_Category>: e.g., hris, ats, accounting. * <Common_Model_Name>: e.g., Employee, Candidate, Invoice. * <Access_Level>: read or write. If omitted, both levels are included for that model.

Examples: * hris.Employee:read: Read-only access for HR Employee records. * ats.Candidate:write: Ability to create/modify Candidate records in ATS. * accounting.Account: Full read/write permissions for Accounting Accounts.

Authorization Caveats

Tool availability is contingent upon three factors:

  1. Linked Account Capabilities: The scope must map to models accessible by the specific Linked Account.
  2. Category Alignment: A scope like ats.Job will yield no tools if the Linked Account is exclusively HRIS-based.
  3. Permission Match: If a scope requires write access (:write) but the underlying linkage only permits reading, the write-enabled tool will be suppressed.

The server enforces strict validation, ensuring only fully authorized tools are presented to the LLM interface.

🛠️ Exposed Functions

This service dynamically registers Merge API operations as callable tools based on authorized scopes. These tools abstract the underlying HTTP interactions and include capabilities for:

  • Fetching individual record details.
  • Retrieving lists of records.
  • Initiating new entity records.
  • Applying modifications to existing records.

Limitation: File download operations are currently outside the scope of this adapter and are slated for a future enhancement.

⚙️ Environment Variables

Configuration relies on the following environment settings to authenticate with the Merge infrastructure:

  • MERGE_API_KEY: Your primary API authentication credential.
  • MERGE_ACCOUNT_TOKEN: The unique identifier for the Linked Account being utilized.
  • MERGE_TENANT (Optional): Specifies the geographic deployment region. Acceptable values are US, EU, or APAC. Defaults to US if unspecified.

WIKIPEDIA: Business management tools encompass the entire spectrum of systems, computational aids, governing structures, procedural frameworks, and analytical methodologies employed by an enterprise to navigate market shifts, maintain competitive advantage, and elevate operational efficacy.== Overview == Management resources span functional divisions, covering aspects like strategic foresight, workflow optimization, documentation maintenance, workforce administration, critical judgment facilitation, and performance monitoring. A functional breakdown often includes:

Resources dedicated to initial data entry and verification across departments. Resources focused on process oversight and refinement. Resources for data synthesis and high-level decision support. Modern management technology has undergone radical transformation recently due to rapid technological acceleration, making the selection process challenging. This complexity is driven by persistent pressure to reduce expenditures while maximizing revenue, accurately gauging consumer demands, and perfecting product delivery methods. Strategic adoption, rather than reflexive adoption of the newest solution, is paramount for managers. Over-reliance on unadapted tools often destabilizes operations. Business management instruments must be judiciously chosen and then tailored precisely to the organization's unique requirements.

== Prominent Selections == In a 2013 assessment by Bain & Company, global usage patterns of business tools were analyzed, reflecting regional priorities shaped by economic conditions. The top ten utilized strategies included:

Strategic formulation Client lifecycle management (CRM) Personnel sentiment analysis Comparative performance analysis (Benchmarking) Integrated performance measurement (Balanced Scorecard) Identification of core organizational strengths Offshoring/Outsourcing arrangements Organizational transition programs Logistics and fulfillment oversight (SCM) Defining organizational purpose and vision Target demographic identification (Segmentation) Comprehensive quality assurance (TQM)

== Enterprise Software == Software packages utilized by organizational personnel to execute diverse operational tasks are termed business applications. These applications serve to augment throughput, quantify performance metrics, and execute operational mandates with high fidelity. The evolution progressed from rudimentary Management Information Systems (MIS) to comprehensive Enterprise Resource Planning (ERP) suites, subsequently incorporating Customer Relationship Management (CRM), culminating in today's prevalent cloud-based management platforms. While a demonstrable link exists between IT investment and corporate outcomes, value realization hinges on two critical elements: the efficacy of the deployment process and the appropriateness of the initial tool selection and subsequent customization.

== Resources for Small/Medium Enterprises (SMEs) == Tools specifically tailored for SMEs are vital as they offer pathways to optimize operational expenditure (OPEX) and enhance efficiency by addressing resource constraints inherent in smaller organizations. They frequently focus on affordability and ease of integration rather than sprawling, complex architectures.

See Also

`