mcpcn-office-powerpoint-mcp-server 2.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tools/__init__.py ADDED
@@ -0,0 +1,28 @@
1
+ """
2
+ Tools package for PowerPoint MCP Server.
3
+ Organizes tools into logical modules for better maintainability.
4
+ """
5
+
6
+ from .presentation_tools import register_presentation_tools
7
+ from .content_tools import register_content_tools
8
+ from .structural_tools import register_structural_tools
9
+ from .professional_tools import register_professional_tools
10
+ from .template_tools import register_template_tools
11
+ from .hyperlink_tools import register_hyperlink_tools
12
+ from .chart_tools import register_chart_tools
13
+ from .connector_tools import register_connector_tools
14
+ from .master_tools import register_master_tools
15
+ from .transition_tools import register_transition_tools
16
+
17
+ __all__ = [
18
+ "register_presentation_tools",
19
+ "register_content_tools",
20
+ "register_structural_tools",
21
+ "register_professional_tools",
22
+ "register_template_tools",
23
+ "register_hyperlink_tools",
24
+ "register_chart_tools",
25
+ "register_connector_tools",
26
+ "register_master_tools",
27
+ "register_transition_tools"
28
+ ]
tools/chart_tools.py ADDED
@@ -0,0 +1,82 @@
1
+ """
2
+ Chart data management tools for PowerPoint MCP Server.
3
+ Implements advanced chart data manipulation capabilities.
4
+ """
5
+
6
+ from typing import Dict, List, Optional, Any
7
+ from pptx.chart.data import ChartData
8
+
9
+ def register_chart_tools(app, presentations, get_current_presentation_id, validate_parameters,
10
+ is_positive, is_non_negative, is_in_range, is_valid_rgb):
11
+ """Register chart data management tools with the FastMCP app."""
12
+
13
+ @app.tool()
14
+ def update_chart_data(
15
+ slide_index: int,
16
+ shape_index: int,
17
+ categories: List[str],
18
+ series_data: List[Dict],
19
+ presentation_id: str = None
20
+ ) -> Dict:
21
+ """
22
+ Replace existing chart data with new categories and series.
23
+
24
+ Args:
25
+ slide_index: Index of the slide (0-based)
26
+ shape_index: Index of the chart shape (0-based)
27
+ categories: List of category names
28
+ series_data: List of dictionaries with 'name' and 'values' keys
29
+ presentation_id: Optional presentation ID (uses current if not provided)
30
+
31
+ Returns:
32
+ Dictionary with operation results
33
+ """
34
+ try:
35
+ # Get presentation
36
+ pres_id = presentation_id or get_current_presentation_id()
37
+ if pres_id not in presentations:
38
+ return {"error": "Presentation not found"}
39
+
40
+ pres = presentations[pres_id]
41
+
42
+ # Validate slide index
43
+ if not (0 <= slide_index < len(pres.slides)):
44
+ return {"error": f"Slide index {slide_index} out of range"}
45
+
46
+ slide = pres.slides[slide_index]
47
+
48
+ # Validate shape index
49
+ if not (0 <= shape_index < len(slide.shapes)):
50
+ return {"error": f"Shape index {shape_index} out of range"}
51
+
52
+ shape = slide.shapes[shape_index]
53
+
54
+ # Check if shape is a chart
55
+ if not hasattr(shape, 'has_chart') or not shape.has_chart:
56
+ return {"error": "Shape is not a chart"}
57
+
58
+ chart = shape.chart
59
+
60
+ # Create new ChartData
61
+ chart_data = ChartData()
62
+ chart_data.categories = categories
63
+
64
+ # Add series data
65
+ for series in series_data:
66
+ if 'name' not in series or 'values' not in series:
67
+ return {"error": "Each series must have 'name' and 'values' keys"}
68
+
69
+ chart_data.add_series(series['name'], series['values'])
70
+
71
+ # Replace chart data
72
+ chart.replace_data(chart_data)
73
+
74
+ return {
75
+ "message": f"Updated chart data on slide {slide_index}, shape {shape_index}",
76
+ "categories": categories,
77
+ "series_count": len(series_data),
78
+ "series_names": [s['name'] for s in series_data]
79
+ }
80
+
81
+ except Exception as e:
82
+ return {"error": f"Failed to update chart data: {str(e)}"}
@@ -0,0 +1,91 @@
1
+ """
2
+ Connector and line tools for PowerPoint MCP Server.
3
+ Implements connector line/arrow drawing capabilities.
4
+ """
5
+
6
+ from typing import Dict, List, Optional, Any
7
+ from pptx.util import Inches, Pt
8
+ from pptx.enum.shapes import MSO_CONNECTOR
9
+ from pptx.dml.color import RGBColor
10
+
11
+ def register_connector_tools(app, presentations, get_current_presentation_id, validate_parameters,
12
+ is_positive, is_non_negative, is_in_range, is_valid_rgb):
13
+ """Register connector tools with the FastMCP app."""
14
+
15
+ @app.tool()
16
+ def add_connector(
17
+ slide_index: int,
18
+ connector_type: str,
19
+ start_x: float,
20
+ start_y: float,
21
+ end_x: float,
22
+ end_y: float,
23
+ line_width: float = 1.0,
24
+ color: List[int] = None,
25
+ presentation_id: str = None
26
+ ) -> Dict:
27
+ """
28
+ Add connector lines/arrows between points on a slide.
29
+
30
+ Args:
31
+ slide_index: Index of the slide (0-based)
32
+ connector_type: Type of connector ("straight", "elbow", "curved")
33
+ start_x: Starting X coordinate in inches
34
+ start_y: Starting Y coordinate in inches
35
+ end_x: Ending X coordinate in inches
36
+ end_y: Ending Y coordinate in inches
37
+ line_width: Width of the connector line in points
38
+ color: RGB color as [r, g, b] list
39
+ presentation_id: Optional presentation ID (uses current if not provided)
40
+
41
+ Returns:
42
+ Dictionary with operation results
43
+ """
44
+ try:
45
+ # Get presentation
46
+ pres_id = presentation_id or get_current_presentation_id()
47
+ if pres_id not in presentations:
48
+ return {"error": "Presentation not found"}
49
+
50
+ pres = presentations[pres_id]
51
+
52
+ # Validate slide index
53
+ if not (0 <= slide_index < len(pres.slides)):
54
+ return {"error": f"Slide index {slide_index} out of range"}
55
+
56
+ slide = pres.slides[slide_index]
57
+
58
+ # Map connector types
59
+ connector_map = {
60
+ 'straight': MSO_CONNECTOR.STRAIGHT,
61
+ 'elbow': MSO_CONNECTOR.ELBOW,
62
+ 'curved': MSO_CONNECTOR.CURVED
63
+ }
64
+
65
+ if connector_type.lower() not in connector_map:
66
+ return {"error": f"Invalid connector type. Use: {list(connector_map.keys())}"}
67
+
68
+ # Add connector
69
+ connector = slide.shapes.add_connector(
70
+ connector_map[connector_type.lower()],
71
+ Inches(start_x), Inches(start_y),
72
+ Inches(end_x), Inches(end_y)
73
+ )
74
+
75
+ # Apply formatting
76
+ if line_width:
77
+ connector.line.width = Pt(line_width)
78
+
79
+ if color and is_valid_rgb(color):
80
+ connector.line.color.rgb = RGBColor(*color)
81
+
82
+ return {
83
+ "message": f"Added {connector_type} connector to slide {slide_index}",
84
+ "connector_type": connector_type,
85
+ "start_point": [start_x, start_y],
86
+ "end_point": [end_x, end_y],
87
+ "shape_index": len(slide.shapes) - 1
88
+ }
89
+
90
+ except Exception as e:
91
+ return {"error": f"Failed to add connector: {str(e)}"}