setup_mcp.pyā¢21.8 kB
# Import necessary Python standard libraries
import os # For operating with file system, handling files and directory paths
import json # For processing JSON format data
import subprocess # For creating and managing subprocesses
import sys # For accessing Python interpreter related variables and functions
import platform # For getting current operating system information
import shutil # For checking if executables exist in PATH
def check_prerequisites():
"""
Check if necessary prerequisites are installed
Returns:
tuple: (python_ok, uv_installed, uvx_installed, ppt_server_installed)
"""
# Check Python version
python_version = sys.version_info
python_ok = python_version.major >= 3 and python_version.minor >= 6
# Check if uv/uvx is installed
uv_installed = shutil.which("uv") is not None
uvx_installed = shutil.which("uvx") is not None
# Check if office-powerpoint-mcp-server is already installed via pip
try:
result = subprocess.run(
[sys.executable, "-m", "pip", "show", "office-powerpoint-mcp-server"],
capture_output=True,
text=True,
check=False
)
ppt_server_installed = result.returncode == 0
except Exception:
ppt_server_installed = False
return (python_ok, uv_installed, uvx_installed, ppt_server_installed)
def setup_venv():
"""
Function to set up Python virtual environment
Features:
- Checks if Python version meets requirements (3.6+)
- Creates Python virtual environment (if it doesn't exist)
- Installs required dependencies in the newly created virtual environment
No parameters required
Returns: Path to Python interpreter in the virtual environment
"""
# Check Python version
python_version = sys.version_info
if python_version.major < 3 or (python_version.major == 3 and python_version.minor < 6):
print("Error: Python 3.6 or higher is required.")
sys.exit(1)
# Get absolute path of the directory containing the current script
base_path = os.path.abspath(os.path.dirname(__file__))
# Set virtual environment directory path
venv_path = os.path.join(base_path, '.venv')
# Determine pip and python executable paths based on operating system
is_windows = platform.system() == "Windows"
if is_windows:
pip_path = os.path.join(venv_path, 'Scripts', 'pip.exe')
python_path = os.path.join(venv_path, 'Scripts', 'python.exe')
else:
pip_path = os.path.join(venv_path, 'bin', 'pip')
python_path = os.path.join(venv_path, 'bin', 'python')
# Check if virtual environment already exists and is valid
venv_exists = os.path.exists(venv_path)
pip_exists = os.path.exists(pip_path)
if not venv_exists or not pip_exists:
print("Creating new virtual environment...")
# Remove existing venv if it's invalid
if venv_exists and not pip_exists:
print("Existing virtual environment is incomplete, recreating it...")
try:
shutil.rmtree(venv_path)
except Exception as e:
print(f"Warning: Could not remove existing virtual environment: {e}")
print("Please delete the .venv directory manually and try again.")
sys.exit(1)
# Create virtual environment
try:
subprocess.run([sys.executable, '-m', 'venv', venv_path], check=True)
print("Virtual environment created successfully!")
except subprocess.CalledProcessError as e:
print(f"Error creating virtual environment: {e}")
sys.exit(1)
else:
print("Valid virtual environment already exists.")
# Double-check that pip exists after creating venv
if not os.path.exists(pip_path):
print(f"Error: pip executable not found at {pip_path}")
print("Try creating the virtual environment manually with: python -m venv .venv")
sys.exit(1)
# Install or update dependencies
print("\nInstalling requirements...")
try:
# Install mcp package
subprocess.run([pip_path, 'install', 'mcp[cli]'], check=True)
# Install python-pptx package
subprocess.run([pip_path, 'install', 'python-pptx'], check=True)
# Also install dependencies from requirements.txt if it exists
requirements_path = os.path.join(base_path, 'requirements.txt')
if os.path.exists(requirements_path):
subprocess.run([pip_path, 'install', '-r', requirements_path], check=True)
print("Requirements installed successfully!")
except subprocess.CalledProcessError as e:
print(f"Error installing requirements: {e}")
sys.exit(1)
except FileNotFoundError:
print(f"Error: Could not execute {pip_path}")
print("Try activating the virtual environment manually and installing requirements:")
if is_windows:
print(f".venv\\Scripts\\activate")
else:
print("source .venv/bin/activate")
print("pip install mcp[cli] python-pptx")
sys.exit(1)
return python_path
def generate_mcp_config_local(python_path):
"""
Generate MCP configuration for locally installed office-powerpoint-mcp-server
Parameters:
- python_path: Path to Python interpreter in the virtual environment
Returns: Path to the generated config file
"""
# Get absolute path of the directory containing the current script
base_path = os.path.abspath(os.path.dirname(__file__))
# Path to PowerPoint Server script
server_script_path = os.path.join(base_path, 'ppt_mcp_server.py')
# Path to templates directory
templates_path = os.path.join(base_path, 'templates')
# Create MCP configuration dictionary
config = {
"mcpServers": {
"ppt": {
"command": python_path,
"args": [server_script_path],
"env": {
"PYTHONPATH": base_path,
"PPT_TEMPLATE_PATH": templates_path
}
}
}
}
# Save configuration to JSON file
config_path = os.path.join(base_path, 'mcp-config.json')
with open(config_path, 'w') as f:
json.dump(config, f, indent=2) # indent=2 gives the JSON file good formatting
return config_path
def generate_mcp_config_uvx():
"""
Generate MCP configuration for PyPI-installed office-powerpoint-mcp-server using UVX
Returns: Path to the generated config file
"""
# Get absolute path of the directory containing the current script
base_path = os.path.abspath(os.path.dirname(__file__))
# Path to templates directory (optional for UVX installs)
templates_path = os.path.join(base_path, 'templates')
# Create MCP configuration dictionary
env_config = {}
if os.path.exists(templates_path):
env_config["PPT_TEMPLATE_PATH"] = templates_path
config = {
"mcpServers": {
"ppt": {
"command": "uvx",
"args": ["--from", "office-powerpoint-mcp-server", "ppt_mcp_server"],
"env": env_config
}
}
}
# Save configuration to JSON file
config_path = os.path.join(base_path, 'mcp-config.json')
with open(config_path, 'w') as f:
json.dump(config, f, indent=2) # indent=2 gives the JSON file good formatting
return config_path
def generate_mcp_config_module():
"""
Generate MCP configuration for PyPI-installed office-powerpoint-mcp-server using Python module
Returns: Path to the generated config file
"""
# Get absolute path of the directory containing the current script
base_path = os.path.abspath(os.path.dirname(__file__))
# Path to templates directory (optional for module installs)
templates_path = os.path.join(base_path, 'templates')
# Create MCP configuration dictionary
env_config = {}
if os.path.exists(templates_path):
env_config["PPT_TEMPLATE_PATH"] = templates_path
config = {
"mcpServers": {
"ppt": {
"command": sys.executable,
"args": ["-m", "office_powerpoint_mcp_server"],
"env": env_config
}
}
}
# Save configuration to JSON file
config_path = os.path.join(base_path, 'mcp-config.json')
with open(config_path, 'w') as f:
json.dump(config, f, indent=2) # indent=2 gives the JSON file good formatting
return config_path
def install_from_pypi():
"""
Install office-powerpoint-mcp-server from PyPI
Returns: True if successful, False otherwise
"""
print("\nInstalling office-powerpoint-mcp-server from PyPI...")
try:
subprocess.run([sys.executable, "-m", "pip", "install", "office-powerpoint-mcp-server"], check=True)
print("office-powerpoint-mcp-server successfully installed from PyPI!")
return True
except subprocess.CalledProcessError:
print("Failed to install office-powerpoint-mcp-server from PyPI.")
return False
def print_config_instructions(config_path):
"""
Print instructions for using the generated config
Parameters:
- config_path: Path to the generated config file
"""
print(f"\nMCP configuration has been written to: {config_path}")
with open(config_path, 'r') as f:
config = json.load(f)
print("\nMCP configuration for Claude Desktop:")
print(json.dumps(config, indent=2))
# Provide instructions for adding configuration to Claude Desktop configuration file
if platform.system() == "Windows":
claude_config_path = os.path.expandvars("%APPDATA%\\Claude\\claude_desktop_config.json")
else: # macOS
claude_config_path = os.path.expanduser("~/Library/Application Support/Claude/claude_desktop_config.json")
print(f"\nTo use with Claude Desktop, merge this configuration into: {claude_config_path}")
def create_package_structure():
"""
Create necessary package structure and directories
"""
# Get absolute path of the directory containing the current script
base_path = os.path.abspath(os.path.dirname(__file__))
# Create __init__.py file
init_path = os.path.join(base_path, '__init__.py')
if not os.path.exists(init_path):
with open(init_path, 'w') as f:
f.write('# PowerPoint MCP Server')
print(f"Created __init__.py at: {init_path}")
# Create requirements.txt file
requirements_path = os.path.join(base_path, 'requirements.txt')
if not os.path.exists(requirements_path):
with open(requirements_path, 'w') as f:
f.write('mcp[cli]\npython-pptx\n')
print(f"Created requirements.txt at: {requirements_path}")
# Create templates directory for PowerPoint templates
templates_dir = os.path.join(base_path, 'templates')
if not os.path.exists(templates_dir):
os.makedirs(templates_dir)
print(f"Created templates directory at: {templates_dir}")
# Create a README file in templates directory
readme_path = os.path.join(templates_dir, 'README.md')
with open(readme_path, 'w') as f:
f.write("""# PowerPoint Templates
This directory is for storing PowerPoint template files (.pptx or .potx) that can be used with the MCP server.
## Usage
1. Place your template files in this directory
2. Use the `create_presentation_from_template` tool with the template filename
3. The server will automatically search for templates in this directory
## Supported Formats
- `.pptx` - PowerPoint presentation files
- `.potx` - PowerPoint template files
## Example
```python
# Create presentation from template
result = create_presentation_from_template("company_template.pptx")
```
The server will search for templates in:
- Current directory
- ./templates/ (this directory)
- ./assets/
- ./resources/
""")
print(f"Created templates README at: {readme_path}")
# Offer to create a sample template
create_sample = input("\nWould you like to create a sample template for testing? (y/n): ").lower().strip()
if create_sample in ['y', 'yes']:
create_sample_template(templates_dir)
def create_sample_template(templates_dir):
"""
Create a sample PowerPoint template for testing
Parameters:
- templates_dir: Directory where templates are stored
"""
try:
# Import required modules for creating a sample template
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
print("Creating sample template...")
# Create a new presentation
prs = Presentation()
# Get the title slide layout
title_slide_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_slide_layout)
# Set title and subtitle
title = slide.shapes.title
subtitle = slide.placeholders[1]
title.text = "Sample Company Template"
subtitle.text = "Professional Presentation Template\nCreated by PowerPoint MCP Server"
# Format title
title_paragraph = title.text_frame.paragraphs[0]
title_paragraph.font.size = Pt(44)
title_paragraph.font.bold = True
title_paragraph.font.color.rgb = RGBColor(31, 73, 125) # Dark blue
# Format subtitle
for paragraph in subtitle.text_frame.paragraphs:
paragraph.font.size = Pt(18)
paragraph.font.color.rgb = RGBColor(68, 84, 106) # Gray blue
paragraph.alignment = PP_ALIGN.CENTER
# Add a content slide
content_slide_layout = prs.slide_layouts[1]
content_slide = prs.slides.add_slide(content_slide_layout)
content_title = content_slide.shapes.title
content_title.text = "Sample Content Slide"
# Add bullet points to content
content_placeholder = content_slide.placeholders[1]
text_frame = content_placeholder.text_frame
text_frame.text = "Key Features"
# Add bullet points
bullet_points = [
"Professional theme and colors",
"Custom layouts and placeholders",
"Ready for content creation",
"Compatible with MCP server tools"
]
for point in bullet_points:
p = text_frame.add_paragraph()
p.text = point
p.level = 1
# Add a section header slide
section_slide_layout = prs.slide_layouts[2] if len(prs.slide_layouts) > 2 else prs.slide_layouts[0]
section_slide = prs.slides.add_slide(section_slide_layout)
if section_slide.shapes.title:
section_slide.shapes.title.text = "Template Features"
# Save the sample template
template_path = os.path.join(templates_dir, 'sample_template.pptx')
prs.save(template_path)
print(f"ā
Sample template created: {template_path}")
print(" You can now test the template feature with:")
print(" ⢠get_template_info('sample_template.pptx')")
print(" ⢠create_presentation_from_template('sample_template.pptx')")
except ImportError:
print("ā ļø Cannot create sample template: python-pptx not installed yet")
print(" Run the setup first, then manually create templates in the templates/ directory")
except Exception as e:
print(f"ā Failed to create sample template: {str(e)}")
print(" You can manually add template files to the templates/ directory")
# Main execution entry point
if __name__ == '__main__':
# Check prerequisites
python_ok, uv_installed, uvx_installed, ppt_server_installed = check_prerequisites()
if not python_ok:
print("Error: Python 3.6 or higher is required.")
sys.exit(1)
print("PowerPoint MCP Server Setup")
print("===========================\n")
# Create necessary files
create_package_structure()
# If office-powerpoint-mcp-server is already installed, offer config options
if ppt_server_installed:
print("office-powerpoint-mcp-server is already installed via pip.")
if uvx_installed:
print("\nOptions:")
print("1. Generate MCP config for UVX (recommended)")
print("2. Generate MCP config for Python module")
print("3. Set up local development environment")
choice = input("\nEnter your choice (1-3): ")
if choice == "1":
config_path = generate_mcp_config_uvx()
print_config_instructions(config_path)
elif choice == "2":
config_path = generate_mcp_config_module()
print_config_instructions(config_path)
elif choice == "3":
python_path = setup_venv()
config_path = generate_mcp_config_local(python_path)
print_config_instructions(config_path)
else:
print("Invalid choice. Exiting.")
sys.exit(1)
else:
print("\nOptions:")
print("1. Generate MCP config for Python module")
print("2. Set up local development environment")
choice = input("\nEnter your choice (1-2): ")
if choice == "1":
config_path = generate_mcp_config_module()
print_config_instructions(config_path)
elif choice == "2":
python_path = setup_venv()
config_path = generate_mcp_config_local(python_path)
print_config_instructions(config_path)
else:
print("Invalid choice. Exiting.")
sys.exit(1)
# If office-powerpoint-mcp-server is not installed, offer installation options
else:
print("office-powerpoint-mcp-server is not installed.")
print("\nOptions:")
print("1. Install from PyPI (recommended)")
print("2. Set up local development environment")
choice = input("\nEnter your choice (1-2): ")
if choice == "1":
if install_from_pypi():
if uvx_installed:
print("\nNow generating MCP config for UVX...")
config_path = generate_mcp_config_uvx()
else:
print("\nUVX not found. Generating MCP config for Python module...")
config_path = generate_mcp_config_module()
print_config_instructions(config_path)
elif choice == "2":
python_path = setup_venv()
config_path = generate_mcp_config_local(python_path)
print_config_instructions(config_path)
else:
print("Invalid choice. Exiting.")
sys.exit(1)
print("\nSetup complete! You can now use the PowerPoint MCP server with compatible clients like Claude Desktop.")
print("\n" + "="*60)
print("POWERPOINT MCP SERVER - NEW FEATURES")
print("="*60)
print("\nš Template Support:")
print(" ⢠Place PowerPoint templates (.pptx/.potx) in the ./templates/ directory")
print(" ⢠Use 'create_presentation_from_template' tool to create presentations from templates")
print(" ⢠Use 'get_template_info' tool to inspect template layouts and properties")
print(" ⢠Templates preserve branding, themes, and custom layouts")
print(" ⢠Template path configured via PPT_TEMPLATE_PATH environment variable")
print("\nš§ Available MCP Tools:")
print(" Presentations:")
print(" ⢠create_presentation - Create new blank presentation")
print(" ⢠create_presentation_from_template - Create from template file")
print(" ⢠get_template_info - Inspect template file details")
print(" ⢠open_presentation - Open existing presentation")
print(" ⢠save_presentation - Save presentation to file")
print("\n Content:")
print(" ⢠add_slide - Add slides with various layouts")
print(" ⢠add_textbox - Add formatted text boxes")
print(" ⢠add_image - Add images from files or base64")
print(" ⢠add_table - Add formatted tables")
print(" ⢠add_shape - Add various auto shapes")
print(" ⢠add_chart - Add column, bar, line, and pie charts")
print("\nš Documentation:")
print(" ⢠Full API documentation available in README.md")
print(" ⢠Template usage examples included")
print(" ⢠Check ./templates/README.md for template guidelines")
print("\nš Quick Start with Templates:")
print(" 1. Copy your .pptx template to ./templates/")
print(" 2. Use: create_presentation_from_template('your_template.pptx')")
print(" 3. Add slides using template layouts")
print(" 4. Save your presentation")
print("\nš” Custom Template Paths:")
print(" ⢠Set PPT_TEMPLATE_PATH environment variable for custom locations")
print(" ⢠Supports multiple paths (colon-separated on Unix, semicolon on Windows)")
print(" ⢠Example: PPT_TEMPLATE_PATH='/path/to/templates:/path/to/more/templates'")
print("\n" + "="*60)