Skip to main content
Glama

make

Run any target from a Makefile by specifying the target name and optional arguments to automate development tasks such as testing or code formatting.

Instructions

Run a make target from the Makefile

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
targetYesMake target to run
argsNoList of command line arguments (e.g. VAR=value)

Implementation Reference

  • The call_tool handler that executes the 'make' tool logic. It parses the Make arguments, builds the make command, runs it as a subprocess, and returns the output.
    @server.call_tool()
    async def call_tool(name: str, arguments: Dict[str, Any]) -> List[TextContent]:
        """Execute a tool.
    
        Args:
            name: Name of the tool to execute
            arguments: Arguments for the tool
    
        Returns:
            List of text content with tool execution results
        """
        if name != "make":
            return [TextContent(type="text", text=f"Unknown tool: {name}")]
    
        try:
            make_args = Make(**arguments)
        except Exception as e:
            return [TextContent(type="text", text=f"Invalid arguments: {str(e)}")]
    
        try:
            # Run make command
            cmd = ["make", "-f", make_path, make_args.target]
            cmd.extend(make_args.args)
    
            proc = await asyncio.create_subprocess_exec(
                *cmd,
                stdout=PIPE,
                stderr=PIPE,
                # Ensure proper error propagation from child process
                start_new_session=True,
            )
        except Exception as e:
            return [
                TextContent(type="text", text=f"Failed to start make process: {str(e)}")
            ]
    
        try:
            stdout, stderr = await proc.communicate()
        except asyncio.CancelledError:
            # Handle task cancellation
            if proc.returncode is None:
                try:
                    proc.terminate()
                    await asyncio.sleep(0.1)
                    if proc.returncode is None:
                        proc.kill()
                except Exception:
                    pass
            raise
        except Exception as e:
            return [
                TextContent(type="text", text=f"Error during make execution: {str(e)}")
            ]
    
        stderr_text = stderr.decode() if stderr else ""
        stdout_text = stdout.decode() if stdout else ""
    
        if proc.returncode != 0:
            return [
                TextContent(
                    type="text",
                    text=f"Make failed with exit code {proc.returncode}:\n{stderr_text}\n{stdout_text}",
                )
            ]
    
        return [TextContent(type="text", text=stdout_text)]
  • The Make Pydantic model that defines the input schema for the 'make' tool, with 'target' (string) and 'args' (list of strings) fields.
    class Make(BaseModel):
        """Parameters for running make."""
    
        target: str = Field(description="Make target to run")
        args: List[str] = Field(
            default_factory=list,
            description="List of command line arguments (e.g. VAR=value)",
        )
  • Registration of the 'make' tool via list_tools. Returns a Tool object with name='make', description, and inputSchema from the Make model.
    @server.list_tools()
    async def list_tools() -> List[Tool]:
        """List available tools.
    
        Returns:
            List of available tools, currently only the make tool.
        """
        return [
            Tool(
                name="make",
                description="Run a make target from the Makefile",
                inputSchema=Make.model_json_schema(),
            )
        ]
  • Main entry point that parses command line arguments (--make-path, --working-dir) and calls serve() to start the MCP server.
    def main() -> NoReturn:
        """Run the MCP Make Server.
    
        This function is the entry point for the MCP Make Server. It parses command line
        arguments and starts the server process.
    
        Raises:
            SystemExit: Always exits the program after running.
        """
        import argparse
        import asyncio
        import sys
    
        parser = argparse.ArgumentParser(
            description="give a model the ability to run make commands"
        )
        parser.add_argument(
            "--make-path", type=str, default="Makefile", help="Path to makefile"
        )
        parser.add_argument(
            "--working-dir", type=str, default=str(Path.cwd()), help="Working directory"
        )
    
        args = parser.parse_args()
        try:
            asyncio.run(serve(args.make_path, args.working_dir))
            sys.exit(0)  # Successful execution
        except KeyboardInterrupt:
            sys.exit(0)  # Clean exit on interrupt
        except Exception as e:
            print(f"Error: {e}", file=sys.stderr)
            sys.exit(1)  # Exit with error
Behavior2/5

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

The description does not mention potential side effects like file creation or environment changes, and with no annotations, the agent lacks awareness of destructive 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?

A single, direct sentence with no unnecessary words; highly concise and front-loaded.

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

Completeness4/5

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

The description covers the essential functionality for a simple tool, though it could mention that the Makefile must exist in the current working directory.

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

Parameters3/5

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

Schema coverage is 100%, so the description adds no extra meaning beyond the schema's parameter descriptions, earning a baseline score.

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

Purpose5/5

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

The description clearly states the action (run) and the resource (make target from the Makefile), leaving no ambiguity about the tool's purpose.

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

Usage Guidelines3/5

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

No explicit guidance on when to use this tool or prerequisites, but given the absence of sibling tools, the description is minimally adequate.

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

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/wrale/mcp-server-make'

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