iam-mcp-server

alejandrogarcia-hub/iam-mcp-server

3.3

If you are the rightful owner of iam-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The Individual Applicant Mesh MCP Server is designed to facilitate seamless communication and data exchange between various applications using the Model Context Protocol (MCP).

IAM MCP SERVER ... kind of πŸ€”

The Individual Applicant Mesh (IAM) MCP Server is designed to process and manage applicant resumes, as well as facilitate job searches. It offers specialized tools and prompts for job searching, resume aggregation, generating job-specific resumes, and creating tailored cover letters.

Note: This server does not fully handle system integrations. Instead, it provides focused functionality specifically for an MCP hostβ€”hence the "kind of πŸ€”".

πŸ’‘ Community & Support
If you found this project helpful, please consider giving it a star ⭐️. Found a bug or have suggestions? Open an issueβ€”your feedback is welcome!

πŸš€ Quickstart

1. Use Claude Desktop as MCP host

The IAM MCP Server is designed to work with Claude Desktop, which provides the necessary MCP host environment. For more details on setting up Claude Desktop with MCP, see the official MCP quickstart guide.

2. Add filesystem MCP server

Add the filesystem MCP server to Claude Desktop to enable file system access (see Requirements section below for configuration example).

3. Get JSearch API token

Create a free account at JSearch to get your API token (200 free requests/month).

⚠️ Note: This step is optional. You can let the MCP host or another MCP server handle job searches instead.

4. Configure IAM MCP Server

Add the following to your Claude Desktop configuration to run the server directly from PyPI using uvx:

{
  "mcpServers": {
    "iam": {
      "command": "uvx",
      "args": [
        "--from", 
        "iam-mcp-server@latest",
        "mcp-server-iam"
      ],
      "env": {
        "LOG_LEVEL": "INFO",
        "RAPIDAPI_KEY": "<YOUR_API_KEY>",
        "RAPIDAPI_HOST": "jsearch.p.rapidapi.com",
        "MCP_TRANSPORT": "stdio"
      }
    }
  }
}

πŸš€ Ready to start using IAM MCP Server?
Check out the Features section to learn how to use the available tools and prompts.

πŸ“ Requirements

  1. πŸ—‚οΈ The MCP host must have read and write access to the local file system where it is running. For example, you can run the IAM MCP Server within Claude Desktop, alongside the filesystem MCP Server, which provides this capability. This file access requirement applies to version 1.0 and is necessary for proper operation.

    1.1. Add the filesystem MCP server

        {
            "mcpServers": {
                "filesystem": {
                    "command": "npx",
                    "args": [
                        "-y",
                        "@modelcontextprotocol/server-filesystem",
                        "<add directory for filesystem server>"
                    ]
                }
            }
        }
    
  2. πŸ” The search job MCP tool requires access to JSearch. You can create an account and get 200 requests per month for free.

✨ Features

Prompts

πŸ“Š Analyze Job Market

Directs the LLM step-by-step to perform tasks such as conducting a job search, then summarizes and analyzes the resulting job listings. Refer to the full prompt for detailed instructions and context.

πŸ“„ Resume Mesh

Easily combine multiple targeted resumes into a single, comprehensive Markdown document.

What is Resume Mesh?
If you’ve applied to similar jobs, you’ve likely created several versions of your resume to match different job descriptions. Resume Mesh brings all those versions together into one unified Markdown file. This gives the MCP host a complete view of your experience and makes it easy to generate new, tailored resumes for future applications.

🎯 Job-Specific Resume Generation

Generate customized resumes for individual job postings.

To use this feature, make sure the MCP host already has access to the resume mesh. Each tailored resume is generated using both the resume mesh and the specific job description. You need to attach the resume mesh to the MCP host conversation in advance, because the resume generation prompt does not instruct the LLM to load the resume mesh from the file system.

Cover-Letter Generation

Easily generate a customized cover letter tailored to a specific job description, using the corresponding generated resume.

How to use:
Before generating a cover letter, ensure the MCP host has access to the relevant generated resume for the target job. You must manually attach this resume to the MCP host conversation, as the cover letter prompt does not automatically retrieve it from the file system.

πŸ’Ύ Save Job

Directs the LLM step-by-step to save jobs.

How to use:

Start by searching for jobs using the search jobs MCP tool. After obtaining the results, you can then instruct the LLM to save those job listings.

Tools

πŸš€ Search Jobs

Performs a job search using the following parameters:

  • role: The job title or position to search for
  • city: (optional) Target city for the job search
  • country: (optional) Target country for the job search
  • platform: (optional) Specific job platform to use
  • number of jobs: (default 5) Number of job listings to retrieve
  • slice job description: (optional) Option to include only a portion of the job description

πŸ› οΈ Installation & Setup

The IAM MCP Server can be installed in multiple ways:

πŸ“¦ Desktop Extension (DXT) - Recommended

One-click installation for MCP hosts! DXT (Desktop Extension) format provides the easiest way to install and use the IAM MCP Server.

Why DXT?

Desktop Extensions eliminate the complexity of manual MCP server setup by bundling everything into a single installable package:

  • No Python installation required - All dependencies included
  • One-click installation - Just like browser extensions
  • Automatic updates - MCP hosts can manage updates
  • Cross-platform - Works on macOS, Windows, and Linux
  • Self-contained - No environment conflicts
Download Latest DXT

Get the latest pre-built DXT file from our GitHub releases:

πŸ“₯ Download Latest DXT β†’

🐳 Container Sidecar

Build a self-contained image and run it alongside your MCP host:

# Build image using published wheel (set APP_VERSION to released tag)
docker build --no-cache --build-arg APP_VERSION=2.1.0 -t iam-mcp-server:2.1.0 .

# For local source builds, omit APP_VERSION or pass APP_VERSION=local
docker build -t iam-mcp-server:dev .

# Start the server with a writable data volume and required secrets
docker run --rm \
  --name iam-mcp-server \
  -e RAPIDAPI_KEY=your_rapidapi_key \
  -e LOG_LEVEL=INFO \
  -e MCP_TRANSPORT=stdio \
  -v $(pwd)/data:/data \
  iam-mcp-server:2.1.0

# OR
docker run --rm -i \
    -e RAPIDAPI_KEY="your-api-key-here" \
    -e LOG_LEVEL=DEBUG \
    -v $(pwd)/data:/data \
    iam-mcp-server:dev

# Interactive stdio communication with Docker

When running the container interactively, you can send JSON-RPC messages directly:

```bash
# Start the container in interactive mode
docker run -i --rm ghcr.io/alejandrogarcia-hub/iam-mcp-server:latest

# 1. Initialize the server (send this JSON and press Enter)
{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"0.1.0","capabilities":{},"clientInfo":{"name":"client","version":"1.0.0"}},"id":1}

# 2. Send initialized notification
{"jsonrpc":"2.0","method":"notifications/initialized","params":{"capabilities":{}}}

# 3. List available prompts
{"jsonrpc":"2.0","method":"prompts/list","params":{},"id":2}

# 4. List available tools
{"jsonrpc":"2.0","method":"tools/list","params":{},"id":3}

# 5. Graceful shutdown (optional - see note below)
{"jsonrpc":"2.0","id":4,"method":"shutdown"}
# Server responds with: {"jsonrpc":"2.0","id":4,"result":null}

# 6. Exit notification
{"jsonrpc":"2.0","method":"exit"}

Note on Shutdown: While MCP supports graceful shutdown via shutdown request followed by exit notification, in practice:

  • Ctrl+C immediately terminates the container (SIGINT) - fast but not graceful
  • Ctrl+D sends EOF to close stdin - cleaner than Ctrl+C
  • Graceful shutdown sequence allows the server to properly clean up resources, save state, and acknowledge before terminating

The graceful shutdown is particularly important in production environments where the server might be handling ongoing operations or needs to persist state before terminating.


#### Production Deployment with Kubernetes

For production environments, deploy the MCP server to Kubernetes and connect via HTTP/SSE:

##### Step 1: Deploy to Kubernetes

```bash
# Deploy to local Docker Desktop Kubernetes
./ops/k8s/deploy-local.sh

# Or deploy to production cluster
kubectl apply -k ops/k8s/

After deployment, the server will be accessible at:

  • Local: http://localhost:9999 (with port-forward)
  • Production: Your configured ingress URL
Step 2: Configure Claude Desktop for Kubernetes Connection

Claude Desktop supports HTTP/SSE MCP servers through Settings > Connectors (Pro, Max, Team, and Enterprise plans):

For Local Kubernetes Deployment:

  1. Ensure the server is deployed and port-forward is active:

    ./ops/k8s/deploy-local.sh
    # This will set up port-forward on localhost:9999
    
  2. Open Claude Desktop and navigate to Settings > Connectors

  3. Click "Add custom connector" at the bottom

  4. Enter the MCP server URL:

    • For local Kubernetes: http://localhost:9999
    • For production Kubernetes: https://your-mcp-server.domain.com
  5. (Optional) Configure authentication in "Advanced settings"

  6. Click "Add" to save

Important Notes:

  • HTTP/SSE connectors are configured via Settings > Connectors, NOT in claude_desktop_config.json
  • This feature is currently in beta
  • For local Kubernetes, ensure kubectl port-forward is running (the deploy script handles this)
  • The server uses SSE for streaming responses back to Claude Desktop
Step 3: Test HTTP/SSE Connection

The HTTP/SSE transport works differently than stdio. Here's how to test it:

Step 1: First, establish SSE connection to get session ID:

# Connect to SSE endpoint and get the session ID
curl -N -H "Accept: text/event-stream" "http://localhost:9999/sse"
# Response will include: data: /messages/?session_id=YOUR_SESSION_ID

Step 2: Initialize the MCP session (two-step process):

# Step 1: Send initialize request
curl -X POST "http://localhost:9999/messages/?session_id=YOUR_SESSION_ID" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"0.1.0","capabilities":{"prompts":{},"tools":{}},"clientInfo":{"name":"test-client","version":"1.0.0"}},"id":1}'
# Response: "Accepted" (actual response comes via SSE)

# Step 2: Send initialized notification
curl -X POST "http://localhost:9999/messages/?session_id=YOUR_SESSION_ID" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{"capabilities":{}}}'
# Response: "Accepted"

Step 3: List available prompts and tools:

# List prompts
curl -X POST "http://localhost:9999/messages/?session_id=YOUR_SESSION_ID" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"prompts/list","params":{},"id":2}'
# Response: "Accepted" (actual list comes via SSE)

# List tools
curl -X POST "http://localhost:9999/messages/?session_id=YOUR_SESSION_ID" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":3}'
# Response: "Accepted" (actual list comes via SSE)

Note: All HTTP POST requests return "Accepted" immediately. The actual MCP responses are streamed through the SSE connection.

Local Development with Docker

For local development without Kubernetes, use Docker with stdio transport:

{
  "mcpServers": {
    "iam-docker": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "--name", "iam-mcp-claude",
        "-e", "RAPIDAPI_KEY=your_api_key",
        "-e", "LOG_LEVEL=INFO",
        "-e", "MCP_TRANSPORT=stdio",
        "-v", "/path/to/data:/data",
        "iam-mcp-server:latest"
      ]
    }
  }
}

Important notes:

  • Container must run in interactive mode (-i) for stdio transport
  • Use --rm to clean up containers after disconnection
  • Mount a volume (-v) to persist data between sessions
  • Replace /path/to/data with your actual data directory
Test the container
echo '{"jsonrpc": "2.0", "method": "initialize", "params": {"protocolVersion": "0.1.0", "capabilities": {}, 
  "clientInfo": {"name": "test", "version": "1.0.0"}}, "id": 1}' | docker run --rm -i iam-mcp-server:dev

# List available tools
echo '{"jsonrpc": "2.0", "method": "tools/list", "params": {}, "id": 2}' | docker run --rm -i iam-mcp-server:dev

# List available prompts
echo '{"jsonrpc": "2.0", "method": "prompts/list", "params": {}, "id": 3}' | docker run --rm -i iam-mcp-server:dev

Key runtime environment variables:

  • RAPIDAPI_KEY / RAPIDAPI_HOST – credentials for the JSearch integration.
  • IAM_DATA_ROOT (defaults to /data) – location where resume meshes and exports are written.
  • LOG_LEVEL – structured JSON logs emitted via stdout.
  • MCP_TRANSPORT – keep stdio for sidecar usage or swap for another supported transport when needed.

Attach the container to your MCP host by pointing the host's configuration at the container entry point. Share the /data volume with the host if it needs direct access to generated artifacts.

Look for iam_mcp_server-[version].dxt in the release assets.

Installation in Claude Desktop
  1. Download the latest .dxt file from releases
  2. Open Claude Desktop β†’ Settings β†’ Extensions
  3. Install the downloaded .dxt file
  4. Configure during installation with these settings:
    • jsearch_api_key: Your RapidAPI key from JSearch (optional - 200 free requests/month)
    • path_to_uvx: Path to your uvx executable (usually ~/.local/bin on macOS/Linux, %USERPROFILE%\.local\bin on Windows)
Build DXT Locally

Want to build your own DXT file?

make dxt

The built DXT file will be available in the dxt/ directory as iam_mcp_server-[version].dxt.

🐍 Python Package from PyPI

You can also install this project as a Python package from PyPI: iam-mcp-server.

πŸ–₯️ Alternative: Manual MCP Configuration

For manual installation or other MCP hosts:

  1. Locate your claude_desktop_config.json file:
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%\Claude\claude_desktop_config.json
Option 1: Using uvx with PyPI package
{
  "mcpServers": {
    "iam": {
        "command": "uvx",
        "args": [
            "--from", 
            "iam-mcp-server@latest",
            "mcp-server-iam"
        ],
        "env": {
            "LOG_LEVEL": "INFO",
            "RAPIDAPI_KEY": "<API KEY>",
            "RAPIDAPI_HOST": "jsearch.p.rapidapi.com",
            "MCP_TRANSPORT": "stdio"
        }
    }
}
Option 2: Using source code
{
  "mcpServers": {
    "iam": {
      "command": "<path to>/uv",
      "args": [
        "--directory",
        "<path to>/iam-mcp-server/src/mcp_server_iam",
        "run",
        "__main__.py"
      ],
      "env": {
        "LOG_LEVEL": "INFO",
        "RAPIDAPI_KEY": "<API KEY>",
        "RAPIDAPI_HOST": "jsearch.p.rapidapi.com",
        "MCP_TRANSPORT": "stdio"
      }
    }
  }
}
Restart your MCP host
  • Completely quit and restart your MCP host
  • The server will automatically initialize when the host starts
Verify the connection

In your MCP host, ask: "What MCP tools are available?" or "List the available MCP servers"

πŸ” MCP Inspector

In terminal, run PYTHONPATH=src mcp dev src/mcp_server_iam/__main__.py and accept installing the MCP Inspector. In the web inspector UI, click connect and interact with the MCP server.

⚠️ Important, this is for dev purposes only.

βš™οΈ Environment Variables

IAM supports configuration through environment variables. Create a .env file in the project root or set these variables in your system:

VariableDefaultDescription
APP_NAMEiamApplication name for logging and identification
LOG_LEVELINFOLogging level: DEBUG, INFO, WARNING, ERROR, CRITICAL
MCP_TRANSPORTstdioApplication transport version
RESUME_MESH_FILENAMEresume_meshDefault filename for resume mesh
RAPIDAPI_KEY""RapidAPI key for external API access (optional)
RAPIDAPI_HOSTjsearch.p.rapidapi.comRapidAPI host endpoint

πŸ“‚ Repository Structure

iam-mcp-server/
β”œβ”€β”€ ops/                        # Production deployment configuration
β”‚   β”œβ”€β”€ k8s/                    # Kubernetes manifests and scripts
β”‚   β”‚   β”œβ”€β”€ deploy-local.sh     # Local Docker Desktop deployment script
β”‚   β”‚   β”œβ”€β”€ teardown-local.sh   # Local deployment teardown script
β”‚   β”‚   β”œβ”€β”€ deployment.yaml     # Kubernetes deployment manifest
β”‚   β”‚   β”œβ”€β”€ deployment-local.yaml # Local deployment manifest
β”‚   β”‚   β”œβ”€β”€ namespace.yaml      # Namespace configuration
β”‚   β”‚   β”œβ”€β”€ service.yaml        # Service configuration
β”‚   β”‚   └── ingress.yaml        # Ingress configuration
β”‚   └── README.md               # Deployment documentation
β”œβ”€β”€ src/                        # Source code
β”‚   └── mcp_server_iam/         # Main MCP server package
β”‚       β”œβ”€β”€ __init__.py         # Package initialization
β”‚       β”œβ”€β”€ __main__.py         # Entry point for running the server
β”‚       β”œβ”€β”€ config.py           # Configuration management
β”‚       β”œβ”€β”€ logging.py          # Logging configuration
β”‚       β”œβ”€β”€ prompt.py           # LLM prompts and instructions
β”‚       β”œβ”€β”€ server.py           # MCP server implementation
β”‚       β”œβ”€β”€ server_http.py      # HTTP/SSE transport wrapper
β”‚       β”œβ”€β”€ tool.py             # MCP tools implementation
β”‚       └── utils.py            # Utility functions
β”œβ”€β”€ tests/                      # Test suite
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ test_config.py          # Configuration tests
β”‚   β”œβ”€β”€ test_logging.py         # Logging tests
β”‚   β”œβ”€β”€ test_manifest.py        # Manifest tests
β”‚   β”œβ”€β”€ test_mcp_tools.py       # MCP tools tests
β”‚   └── test_utils.py           # Utility tests
β”œβ”€β”€ .dockerignore               # Docker ignore file
β”œβ”€β”€ .env_example                # Environment variables template
β”œβ”€β”€ AGENTS.md                   # Agent documentation
β”œβ”€β”€ CLAUDE.md                   # Claude Code instructions
β”œβ”€β”€ Dockerfile                  # Docker container definition
β”œβ”€β”€ LICENSE                     # MIT License
β”œβ”€β”€ makefile                    # Build and development tasks
β”œβ”€β”€ manifest.json               # Package manifest
β”œβ”€β”€ pyproject.toml              # Project configuration and dependencies
β”œβ”€β”€ pytest.ini                  # Pytest configuration
β”œβ”€β”€ README.md                   # This file
β”œβ”€β”€ requirements.txt            # Python dependencies
β”œβ”€β”€ requirements-dev.txt        # Development dependencies
β”œβ”€β”€ ruff.toml                   # Ruff linter configuration
└── uv.lock                     # UV dependency lock file

πŸ”‘ Key Components

  • ops/: Production deployment and operations

    • k8s/: Kubernetes deployment manifests and automation scripts
    • HTTP/SSE server configuration for production environments
    • Local Docker Desktop Kubernetes deployment support
  • src/mcp_server_iam/: Core MCP server implementation

    • server.py: Main MCP server class and protocol handling
    • server_http.py: HTTP/SSE transport implementation
    • tool.py: Implementation of MCP tools (job search, etc.)
    • prompt.py: LLM prompts for resume generation and job analysis
    • config.py: Configuration management and environment variables
    • logging.py: Structured logging configuration
    • utils.py: Helper functions and utilities
  • tests/: Comprehensive test suite for MCP tools and functionality

  • Docker support: Containerized deployment with both stdio and HTTP/SSE transports

  • Configuration files: Project setup, linting, and dependency management

πŸ“ License

MIT License - see LICENSE file for details