#!/usr/bin/env python3
"""
MCP Configuration Generator for Generic PDF Server
Generates ready-to-use MCP client configurations for Claude Desktop
"""
import json
import sys
import platform
from pathlib import Path
from typing import Optional
from config import load_config_from_env_or_file
def generate_mcp_config(config_path: Optional[str] = None) -> str:
"""Generate MCP configuration for Claude Desktop"""
try:
# Load server configuration
config = load_config_from_env_or_file(config_path)
# Get absolute paths
current_dir = Path.cwd()
server_script = current_dir / "server.py"
pdf_folder = Path(config.storage.pdf_folder).resolve()
markdown_folder = Path(config.storage.markdown_folder).resolve()
# Generate environment variable names based on server name
server_name_upper = config.server.name.upper().replace('-', '_')
env_vars = {
f"PDF_FOLDER": str(pdf_folder),
f"MARKDOWN_FOLDER": str(markdown_folder)
}
# Create MCP server configuration
mcp_config = {
"mcpServers": {
config.server.name: {
"command": str(sys.executable),
"args": [str(server_script)],
"env": env_vars
}
}
}
return json.dumps(mcp_config, indent=2)
except Exception as e:
raise RuntimeError(f"Failed to generate MCP config: {e}")
def get_claude_config_path() -> str:
"""Get the Claude Desktop configuration file path for the current platform"""
system = platform.system()
if system == "Darwin": # macOS
return "~/Library/Application Support/Claude/claude_desktop_config.json"
elif system == "Windows":
return "%APPDATA%\\Claude\\claude_desktop_config.json"
else: # Linux and others
return "~/.config/claude/claude_desktop_config.json"
def main():
"""Main function to generate and display MCP configuration"""
import argparse
parser = argparse.ArgumentParser(
description="Generate MCP configuration for Claude Desktop",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
%(prog)s # Generate config using default server_config.json
%(prog)s --config /path/to/config.json # Generate config using specific file
%(prog)s --output # Save config to file instead of printing
"""
)
parser.add_argument(
"--config",
help="Path to server configuration file (default: ./server_config.json)"
)
parser.add_argument(
"--output", "-o",
help="Output file to save MCP configuration (default: print to stdout)"
)
parser.add_argument(
"--merge",
action="store_true",
help="Merge with existing Claude Desktop config file"
)
args = parser.parse_args()
try:
# Generate MCP configuration
mcp_config_json = generate_mcp_config(args.config)
if args.output:
# Save to file
with open(args.output, 'w') as f:
f.write(mcp_config_json)
print(f"MCP configuration saved to: {args.output}")
elif args.merge:
# Merge with existing Claude config
claude_config_path = Path(get_claude_config_path()).expanduser()
if claude_config_path.exists():
# Load existing config
with open(claude_config_path, 'r') as f:
existing_config = json.load(f)
else:
existing_config = {}
# Parse new MCP config
new_config = json.loads(mcp_config_json)
# Merge configurations
if "mcpServers" not in existing_config:
existing_config["mcpServers"] = {}
existing_config["mcpServers"].update(new_config["mcpServers"])
# Create backup
if claude_config_path.exists():
backup_path = claude_config_path.with_suffix('.json.backup')
claude_config_path.rename(backup_path)
print(f"Created backup: {backup_path}")
# Save merged config
claude_config_path.parent.mkdir(parents=True, exist_ok=True)
with open(claude_config_path, 'w') as f:
json.dump(existing_config, f, indent=2)
print(f"Updated Claude Desktop configuration: {claude_config_path}")
print("Restart Claude Desktop to load the new server.")
else:
# Print to stdout
print("MCP Configuration for Claude Desktop:")
print("=" * 60)
print(mcp_config_json)
print("=" * 60)
print()
print("Instructions:")
print(f"1. Copy the above configuration")
print(f"2. Add it to your Claude Desktop config file:")
print(f" {get_claude_config_path()}")
print(f"3. Restart Claude Desktop")
print()
print("Or use --merge flag to automatically update your Claude config:")
print(f" python {sys.argv[0]} --merge")
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()