Introduction

The Model Context Protocol (MCP) is an open standard that lets AI assistants like Claude connect to external tools and data sources. Instead of copy-pasting context into chat, MCP servers expose structured capabilities — querying AWS costs, browsing documentation, or posting to LinkedIn — directly from within Claude Desktop.

This guide walks through configuring six MCP servers on a Windows machine running WSL2, covering Azure, AWS (four specialized servers), and LinkedIn.

What is MCP?

MCP follows a client-server architecture. Claude Desktop acts as the client, and each MCP server provides a specific set of tools the AI can invoke during a conversation.

ClaudeDewwwwwwssssssskllllllt......oeeeeeepxxxxxxeeeeee(WinAAAAALdzWWWWiouSSSSnwrkseCADPe)oPordMsIciICtscnPMiECMnMSxPCgCepPPrlSMvoeSCSerrePerevrrrevSvreeeMrrrCvPerServer

Each server runs inside WSL2 (Ubuntu), and Claude Desktop launches them via wsl.exe. This approach keeps all dependencies (Python venvs, Node.js, AWS CLI) inside the Linux environment while Claude Desktop runs natively on Windows.

Prerequisites

  • Windows 10/11 with WSL2 enabled
  • Claude Desktop installed on Windows
  • Node.js 22+ installed inside WSL2 (via nvm)
  • Python 3.12+ inside WSL2 (for AWS MCP servers)
  • uv/uvx installed inside WSL2 (for Python package management)
  • AWS CLI configured with a default profile (aws configure)
  • Relevant API keys/tokens for each service

Configuration File Location

Claude Desktop reads its MCP config from:

%APPDATA%\Claude\claude_desktop_config.json

On most Windows machines, this resolves to:

C:\Users\<username>\AppData\Roaming\Claude\claude_desktop_config.json

The file is a single JSON object with an mcpServers key. Each entry defines one MCP server with its launch command, arguments, and optional environment variables.

The WSL2 Bridge Pattern

Since Claude Desktop runs on Windows but our tools live in WSL2, every server uses the same launch pattern:

1
2
3
4
5
6
7
8
{
  "command": "wsl.exe",
  "args": [
    "bash",
    "-lc",
    "<command-to-run-inside-wsl>"
  ]
}

The -l flag ensures bash loads your login profile (~/.profile, ~/.bashrc), so tools like nvm, pyenv, and uv are available on the PATH. The -c flag passes the command as a string.

Server 1: Azure MCP

The official Azure MCP server provides tools for managing Azure resources — listing subscriptions, querying resource groups, inspecting VMs, and more.

Setup

No local installation needed. It runs via npx which downloads the package on first use.

Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "azure": {
    "command": "wsl.exe",
    "args": [
      "bash",
      "-lc",
      "npx -y @azure/mcp@latest server start"
    ]
  }
}

What It Provides

  • List and manage Azure subscriptions
  • Query resource groups, VMs, storage accounts
  • Inspect Azure service configurations

Prerequisites

  • Azure CLI installed and authenticated (az login) inside WSL2

Server 2: AWS Cost Explorer MCP

This server lets Claude query your AWS billing and cost data — monthly spend, service breakdown, cost trends, and forecasts.

Setup

Create a launcher script that manages its own Python virtual environment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
mkdir -p ~/mcp/aws
cat > ~/mcp/aws/start-cost-explorer.sh << 'SCRIPT'
#!/bin/bash
# Launch the AWS Cost Explorer MCP server from a managed virtual environment.
set -euo pipefail

export AWS_PROFILE="${AWS_PROFILE:-default}"
export AWS_REGION="${AWS_REGION:-us-east-1}"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV_DIR="$SCRIPT_DIR/.venv-cost-explorer"
STAMP_FILE="$VENV_DIR/.deps"
REQUIREMENTS_HASH_FILE="$SCRIPT_DIR/.cost-explorer.requirements"

create_venv() {
  python3 -m venv "$VENV_DIR"
  "$VENV_DIR/bin/pip" install --upgrade pip
}

ensure_requirements_installed() {
  local current_hash
  current_hash=$(printf '%s' "cost-explorer" | sha256sum | awk '{print $1}')
  local previous_hash=""
  if [[ -f "$REQUIREMENTS_HASH_FILE" ]]; then
    previous_hash=$(cat "$REQUIREMENTS_HASH_FILE")
  fi
  if [[ ! -f "$STAMP_FILE" ]] || [[ "$current_hash" != "$previous_hash" ]]; then
    "$VENV_DIR/bin/pip" install --upgrade awslabs.cost-explorer-mcp-server "botocore[crt]"
    printf '%s' "$current_hash" >"$REQUIREMENTS_HASH_FILE"
    touch "$STAMP_FILE"
  fi
}

if [[ ! -d "$VENV_DIR" ]]; then
  create_venv
fi

ensure_requirements_installed

exec "$VENV_DIR/bin/python" -m awslabs.cost_explorer_mcp_server.server
SCRIPT
chmod +x ~/mcp/aws/start-cost-explorer.sh

The script uses a hash-based dependency tracking approach: it computes a SHA-256 hash of the package identifier and compares it against a stored hash file. Dependencies are only reinstalled when the hash changes, making subsequent launches fast.

Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "cost-explorer": {
    "command": "wsl.exe",
    "args": [
      "bash",
      "-lc",
      "~/mcp/aws/start-cost-explorer.sh"
    ],
    "env": {
      "AWS_PROFILE": "default",
      "AWS_REGION": "us-east-1"
    }
  }
}

What It Provides

  • Query monthly and daily AWS costs
  • Break down costs by service, region, or account
  • Cost forecasts and trend analysis

Server 3: AWS API MCP

The AWS API MCP server provides direct access to AWS service APIs — allowing Claude to list EC2 instances, check S3 buckets, query DynamoDB tables, and interact with most AWS services.

Setup

This server uses uvx (the uv package runner) for zero-install execution:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
cat > ~/mcp/aws/start-aws-api.sh << 'SCRIPT'
#!/bin/bash
# Launch the official AWS API MCP server via uvx.
set -euo pipefail

export AWS_PROFILE="${AWS_PROFILE:-default}"
export AWS_REGION="${AWS_REGION:-us-east-1}"
export AWS_API_MCP_PROFILE_NAME="${AWS_API_MCP_PROFILE_NAME:-$AWS_PROFILE}"

UVX_BIN="${UVX_BIN:-$HOME/.local/bin/uvx}"
export UV_CACHE_DIR="${UV_CACHE_DIR:-$HOME/.cache/uv-mcp}"

if ! command -v "$UVX_BIN" >/dev/null 2>&1; then
  if command -v uvx >/dev/null 2>&1; then
    UVX_BIN="$(command -v uvx)"
  else
    cat >&2 <<'MSG'
uvx was not found on PATH. Install it with:
  curl -LsSf https://astral.sh/uv/install.sh | sh
MSG
    exit 1
  fi
fi

exec "$UVX_BIN" awslabs.aws-api-mcp-server@latest
SCRIPT
chmod +x ~/mcp/aws/start-aws-api.sh

Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "aws-api": {
    "command": "wsl.exe",
    "args": [
      "bash",
      "-lc",
      "~/mcp/aws/start-aws-api.sh"
    ],
    "env": {
      "AWS_PROFILE": "default",
      "AWS_REGION": "us-east-1"
    }
  }
}

What It Provides

  • List and describe EC2 instances, S3 buckets, Lambda functions
  • Query DynamoDB, RDS, CloudWatch metrics
  • Interact with most AWS service APIs

Server 4: AWS Documentation MCP

This server gives Claude access to the entire AWS documentation library. When asked about AWS services, configuration options, or best practices, Claude can search and reference official docs.

Setup

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat > ~/mcp/aws/start-aws-docs.sh << 'SCRIPT'
#!/bin/bash
# Launch the AWS Documentation MCP server via uvx.
set -euo pipefail

UVX_BIN="${UVX_BIN:-$HOME/.local/bin/uvx}"
export UV_CACHE_DIR="${UV_CACHE_DIR:-$HOME/.cache/uv-mcp}"

if ! command -v "$UVX_BIN" >/dev/null 2>&1; then
  if command -v uvx >/dev/null 2>&1; then
    UVX_BIN="$(command -v uvx)"
  else
    cat >&2 <<'MSG'
uvx was not found on PATH. Install it with:
  curl -LsSf https://astral.sh/uv/install.sh | sh
MSG
    exit 1
  fi
fi

exec "$UVX_BIN" awslabs.aws-documentation-mcp-server@latest
SCRIPT
chmod +x ~/mcp/aws/start-aws-docs.sh

Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "aws-docs": {
    "command": "wsl.exe",
    "args": [
      "bash",
      "-lc",
      "~/mcp/aws/start-aws-docs.sh"
    ]
  }
}

What It Provides

  • Search AWS documentation by keyword or topic
  • Retrieve service configuration guides
  • Reference official AWS best practices

Server 5: AWS Pricing MCP

This server allows Claude to look up current AWS pricing for any service — EC2 instance types, S3 storage tiers, Lambda invocation costs, and more.

Setup

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
cat > ~/mcp/aws/start-aws-pricing.sh << 'SCRIPT'
#!/bin/bash
# Launch the AWS Pricing MCP server from a managed virtual environment.
set -euo pipefail

export AWS_PROFILE="${AWS_PROFILE:-default}"
export AWS_REGION="${AWS_REGION:-us-east-1}"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV_DIR="$SCRIPT_DIR/.venv-aws-pricing"
STAMP_FILE="$VENV_DIR/.deps"
REQUIREMENTS_HASH_FILE="$SCRIPT_DIR/.aws-pricing.requirements"

create_venv() {
  python3 -m venv "$VENV_DIR"
  "$VENV_DIR/bin/pip" install --upgrade pip
}

enforce_requirements() {
  local current_hash
  current_hash=$(printf '%s' "aws-pricing-with-crt" | sha256sum | awk '{print $1}')
  local previous_hash=""
  if [[ -f "$REQUIREMENTS_HASH_FILE" ]]; then
    previous_hash=$(cat "$REQUIREMENTS_HASH_FILE")
  fi
  if [[ ! -f "$STAMP_FILE" ]] || [[ "$current_hash" != "$previous_hash" ]]; then
    "$VENV_DIR/bin/pip" install --upgrade awslabs.aws-pricing-mcp-server "botocore[crt]"
    printf '%s' "$current_hash" > "$REQUIREMENTS_HASH_FILE"
    touch "$STAMP_FILE"
  fi
}

if [[ ! -d "$VENV_DIR" ]]; then
  create_venv
fi

enforce_requirements

exec "$VENV_DIR/bin/python" -m awslabs.aws_pricing_mcp_server.server
SCRIPT
chmod +x ~/mcp/aws/start-aws-pricing.sh

Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "aws-pricing": {
    "command": "wsl.exe",
    "args": [
      "bash",
      "-lc",
      "~/mcp/aws/start-aws-pricing.sh"
    ],
    "env": {
      "AWS_PROFILE": "default",
      "AWS_REGION": "us-east-1"
    }
  }
}

What It Provides

  • Look up EC2 instance pricing by type and region
  • Compare storage costs across S3 tiers
  • Query Lambda, RDS, and other service pricing

Server 6: LinkedIn MCP

This server connects Claude to your LinkedIn account for reading and creating posts, viewing profile data, and managing your professional presence.

Setup

Clone and build the LinkedIn MCP server:

1
2
3
4
git clone https://github.com/your-linkedin-mcp-repo.git ~/linkedin-mcp
cd ~/linkedin-mcp
npm install
npm run build

Create a launcher script with your OAuth credentials:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
cat > ~/linkedin-mcp/start.sh << 'SCRIPT'
#!/bin/bash
export PATH=$HOME/.nvm/versions/node/v25.4.0/bin:$PATH
export LINKEDIN_CLIENT_ID="your-client-id"
export LINKEDIN_CLIENT_SECRET="your-client-secret"
export LINKEDIN_ACCESS_TOKEN="your-access-token"
export LINKEDIN_PERSON_ID="your-person-id"

exec node ~/linkedin-mcp/build/index.js
SCRIPT
chmod +x ~/linkedin-mcp/start.sh

Getting LinkedIn API Credentials

  1. Go to LinkedIn Developer Portal and create an app
  2. Under Auth, note the Client ID and Client Secret
  3. Add the OAuth 2.0 redirect URL (e.g., http://localhost:3000/callback)
  4. Request the w_member_social and r_liteprofile scopes
  5. Generate an access token via the OAuth flow
  6. Find your Person ID from your LinkedIn profile URL or API

Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "linkedin": {
    "command": "wsl.exe",
    "args": [
      "bash",
      "-lc",
      "~/linkedin-mcp/start.sh"
    ]
  }
}

What It Provides

  • Create and publish LinkedIn posts
  • Read your profile information
  • View post engagement and analytics

Complete Configuration

Here is the full claude_desktop_config.json with all six servers:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
{
  "mcpServers": {
    "azure": {
      "command": "wsl.exe",
      "args": [
        "bash",
        "-lc",
        "npx -y @azure/mcp@latest server start"
      ]
    },
    "cost-explorer": {
      "command": "wsl.exe",
      "args": [
        "bash",
        "-lc",
        "~/mcp/aws/start-cost-explorer.sh"
      ],
      "env": {
        "AWS_PROFILE": "default",
        "AWS_REGION": "us-east-1"
      }
    },
    "aws-api": {
      "command": "wsl.exe",
      "args": [
        "bash",
        "-lc",
        "~/mcp/aws/start-aws-api.sh"
      ],
      "env": {
        "AWS_PROFILE": "default",
        "AWS_REGION": "us-east-1"
      }
    },
    "aws-docs": {
      "command": "wsl.exe",
      "args": [
        "bash",
        "-lc",
        "~/mcp/aws/start-aws-docs.sh"
      ]
    },
    "aws-pricing": {
      "command": "wsl.exe",
      "args": [
        "bash",
        "-lc",
        "~/mcp/aws/start-aws-pricing.sh"
      ],
      "env": {
        "AWS_PROFILE": "default",
        "AWS_REGION": "us-east-1"
      }
    },
    "linkedin": {
      "command": "wsl.exe",
      "args": [
        "bash",
        "-lc",
        "~/linkedin-mcp/start.sh"
      ]
    }
  }
}

Verifying MCP Servers

After saving the config, restart Claude Desktop. You can verify servers are connected by:

  1. Opening Claude Desktop
  2. Clicking the MCP tools icon (hammer icon) in the chat input area
  3. Each connected server will list its available tools

If a server fails to start, check the Claude Desktop logs:

%APPDATA%\Claude\logs\

Or test the server manually inside WSL2:

1
2
3
4
5
# Test Azure MCP
npx -y @azure/mcp@latest server start

# Test AWS Cost Explorer
~/mcp/aws/start-cost-explorer.sh

Troubleshooting

IssueFix
Server not showing in ClaudeRestart Claude Desktop after editing claude_desktop_config.json
wsl.exe not foundEnsure WSL2 is installed: wsl --install
npx not found inside WSLUse full path: /home/user/.nvm/versions/node/v25.4.0/bin/npx
uvx not foundInstall uv: curl -LsSf https://astral.sh/uv/install.sh | sh
AWS auth errorsRun aws configure inside WSL2 and verify credentials
LinkedIn token expiredRegenerate the OAuth access token via the developer portal
Python venv errorsDelete the .venv-* directory and let the script recreate it

Security Best Practices

  1. Never commit claude_desktop_config.json to git — it may reference scripts containing secrets
  2. Keep secrets in start scripts, not in the config — the env block in config is visible to Claude; use export in shell scripts instead
  3. Use scoped API tokens — create tokens with minimum required permissions
  4. Rotate tokens regularly — especially LinkedIn access tokens
  5. Use AWS profiles — avoid hardcoding AWS credentials; rely on aws configure profiles
  6. Restrict file permissionschmod 700 on start scripts containing secrets

Conclusion

With six MCP servers configured, Claude Desktop becomes a unified interface for cloud infrastructure (Azure + AWS), professional networking (LinkedIn), and cost analysis. The WSL2 bridge pattern keeps all dependencies cleanly inside Linux while Claude Desktop runs natively on Windows.

The key architectural decisions that make this setup work:

  • WSL2 as the runtime — All tools, SDKs, and credentials live in Linux
  • Launcher scripts — Each server manages its own virtual environment and dependencies
  • Self-healing venvs — Python servers auto-create and update their virtual environments on first run
  • uvx for zero-install servers — AWS API and Docs servers run without manual installation

For more information on MCP, visit the Model Context Protocol documentation or the Claude Desktop MCP guide.