Skip to main content
Glama

create_custom_style

Define and apply custom styles in Microsoft Word documents by specifying font, size, bold, italic, and color settings. Enhances document formatting and consistency for professional results.

Instructions

Create a custom style in the document.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
base_styleNo
boldNo
colorNo
filenameYes
font_nameNo
font_sizeNo
italicNo
style_nameYes

Implementation Reference

  • Primary handler implementing the tool: loads document, builds font properties, calls create_style helper, saves document.
    async def create_custom_style(filename: str, style_name: str, 
                                 bold: Optional[bool] = None, italic: Optional[bool] = None,
                                 font_size: Optional[int] = None, font_name: Optional[str] = None,
                                 color: Optional[str] = None, base_style: Optional[str] = None) -> str:
        """Create a custom style in the document.
        
        Args:
            filename: Path to the Word document
            style_name: Name for the new style
            bold: Set text bold (True/False)
            italic: Set text italic (True/False)
            font_size: Font size in points
            font_name: Font name/family
            color: Text color (e.g., 'red', 'blue')
            base_style: Optional existing style to base this on
        """
        filename = ensure_docx_extension(filename)
        
        if not os.path.exists(filename):
            return f"Document {filename} does not exist"
        
        # Check if file is writeable
        is_writeable, error_message = check_file_writeable(filename)
        if not is_writeable:
            return f"Cannot modify document: {error_message}. Consider creating a copy first."
        
        try:
            doc = Document(filename)
            
            # Build font properties dictionary
            font_properties = {}
            if bold is not None:
                font_properties['bold'] = bold
            if italic is not None:
                font_properties['italic'] = italic
            if font_size is not None:
                font_properties['size'] = font_size
            if font_name is not None:
                font_properties['name'] = font_name
            if color is not None:
                font_properties['color'] = color
            
            # Create the style
            new_style = create_style(
                doc, 
                style_name, 
                WD_STYLE_TYPE.PARAGRAPH, 
                base_style=base_style,
                font_properties=font_properties
            )
            
            doc.save(filename)
            return f"Style '{style_name}' created successfully."
        except Exception as e:
            return f"Failed to create style: {str(e)}"
  • MCP registration with @mcp.tool() decorator defining input parameters/schema and delegating to format_tools.create_custom_style.
    @mcp.tool()
    async def create_custom_style(filename: str, style_name: str, bold: Optional[bool] = None, 
                          italic: Optional[bool] = None, font_size: Optional[int] = None, 
                          font_name: Optional[str] = None, color: Optional[str] = None, 
                          base_style: Optional[str] = None):
        """Create a custom style in the document."""
        return await format_tools.create_custom_style(
            filename, style_name, bold, italic, font_size, font_name, color, base_style
        )
  • Core helper function that creates the new style object in the document, applies font and paragraph properties, handles color mapping.
    def create_style(doc, style_name, style_type, base_style=None, font_properties=None, paragraph_properties=None):
        """
        Create a new style in the document.
        
        Args:
            doc: Document object
            style_name: Name for the new style
            style_type: Type of style (WD_STYLE_TYPE)
            base_style: Optional base style to inherit from
            font_properties: Dictionary of font properties (bold, italic, size, name, color)
            paragraph_properties: Dictionary of paragraph properties (alignment, spacing)
            
        Returns:
            The created style
        """
        from docx.shared import Pt
        
        try:
            # Check if style already exists
            style = doc.styles.get_by_id(style_name, WD_STYLE_TYPE.PARAGRAPH)
            return style
        except:
            # Create new style
            new_style = doc.styles.add_style(style_name, style_type)
            
            # Set base style if specified
            if base_style:
                new_style.base_style = doc.styles[base_style]
            
            # Set font properties
            if font_properties:
                font = new_style.font
                if 'bold' in font_properties:
                    font.bold = font_properties['bold']
                if 'italic' in font_properties:
                    font.italic = font_properties['italic']
                if 'size' in font_properties:
                    font.size = Pt(font_properties['size'])
                if 'name' in font_properties:
                    font.name = font_properties['name']
                if 'color' in font_properties:
                    from docx.shared import RGBColor
                    
                    # Define common RGB colors
                    color_map = {
                        'red': RGBColor(255, 0, 0),
                        'blue': RGBColor(0, 0, 255),
                        'green': RGBColor(0, 128, 0),
                        'yellow': RGBColor(255, 255, 0),
                        'black': RGBColor(0, 0, 0),
                        'gray': RGBColor(128, 128, 128),
                        'white': RGBColor(255, 255, 255),
                        'purple': RGBColor(128, 0, 128),
                        'orange': RGBColor(255, 165, 0)
                    }
                    
                    color_value = font_properties['color']
                    try:
                        # Handle string color names
                        if isinstance(color_value, str) and color_value.lower() in color_map:
                            font.color.rgb = color_map[color_value.lower()]
                        # Handle RGBColor objects
                        elif hasattr(color_value, 'rgb'):
                            font.color.rgb = color_value
                        # Try to parse as RGB string
                        elif isinstance(color_value, str):
                            font.color.rgb = RGBColor.from_string(color_value)
                        # Use directly if it's already an RGB value
                        else:
                            font.color.rgb = color_value
                    except Exception as e:
                        # Fallback to black if all else fails
                        font.color.rgb = RGBColor(0, 0, 0)
            
            # Set paragraph properties
            if paragraph_properties:
                if 'alignment' in paragraph_properties:
                    new_style.paragraph_format.alignment = paragraph_properties['alignment']
                if 'spacing' in paragraph_properties:
                    new_style.paragraph_format.line_spacing = paragraph_properties['spacing']
            
            return new_style
  • Exposes the create_custom_style function from format_tools for import in main.py registration.
    from word_document_server.tools.format_tools import (
        format_text, create_custom_style, format_table
    )
  • Imports the format_tools module (containing create_custom_style) for use in tool registrations.
    from word_document_server.tools import (
        document_tools,
        content_tools,
        markdown_tools,
        format_tools,
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool creates something, implying a write operation, but doesn't disclose any behavioral traits such as whether it requires specific permissions, what happens if a style with the same name exists, if changes are reversible, or how the style integrates with the document. For a mutation tool with zero annotation coverage, this leaves significant gaps in understanding its behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core action and resource without unnecessary words. It avoids redundancy and wastes no space, making it easy to parse quickly. Every word earns its place by conveying the essential purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of an 8-parameter mutation tool with no annotations and no output schema, the description is incomplete. It doesn't explain the tool's behavior, parameter usage, or expected outcomes, leaving critical gaps for an AI agent to understand how to invoke it correctly. The conciseness comes at the cost of insufficient detail for this context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds no meaning beyond what the input schema provides. With 8 parameters and 0% schema description coverage, the schema only lists parameter names and types without explanations. The description doesn't compensate by explaining what parameters like 'base_style', 'color', or 'filename' represent, their formats, or how they interact. This leaves parameters largely undocumented, falling short of the baseline needed for low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Create') and resource ('a custom style in the document'), making the purpose immediately understandable. It distinguishes this tool from siblings like 'format_text' or 'customize_footnote_style' by focusing on style creation rather than modification or specific footnote styling. However, it doesn't specify what type of document or style system is involved, which slightly limits specificity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing an existing document), compare to similar tools like 'customize_footnote_style' or 'format_text', or indicate scenarios where creating a custom style is preferred over direct formatting. Usage is implied only by the tool name and action.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/franlealp1/mcp-word'

If you have feedback or need assistance with the MCP directory API, please join our Discord server