钩子
STDIO基于YAML配置的MCP服务器用于安全的开发命令和提示
基于YAML配置的MCP服务器用于安全的开发命令和提示
  
  
.env file loading, define required secrets without checking them in, supports exit codes/stdout/stderr, etc
uv tool install hooks-mcp
hooks_mcp.yaml file in your project root defining your tools and prompts. For example:actions: - name: "all_tests" description: "Run all tests in the project" command: "uv run python -m pytest ./tests" - name: "check_format" description: "Check if the source code is formatted correctly" command: "uvx ruff format --check ." - name: "typecheck" description: "Typecheck the source code" command: "uv run pyright ." - name: "test_file" description: "Run tests in a specific file or directory" command: "python -m pytest $TEST_PATH" parameters: - name: "TEST_PATH" type: "project_file_path" description: "Path to test file or directory" prompts: - name: "test_guide.md" description: "Guide for testing best practices in this library" prompt-file: "agents/test_guide.md"
uvx hooks-mcp
We recommend running HooksMCP with uvx:
# Install uv tool install hooks-mcp # Run uvx hooks-mcp
Optional command line arguments include:
--working-directory/-wd: Typically the path to your project root. Set if not running from project root.--disable-prompt-tool: Disable the get_prompt tool entirely, similar to setting get_prompt_tool_filter to an empty array.hooks_mcp.yaml file, if not using the default ./hooks_mcp.yamlOr open this cursor deeplink.
Most other IDEs use a variant of mcp.json. Create an entry for HooksMCP.
Note: Be sure it's run from the root of your project, or manually pass the working directory on startup:
{ "HooksMCP": { "command": "uvx", "args": [ "hooks-mcp", "--working-directory", "." ] } }
The hooks_mcp.yaml file defines the tools that will be exposed through the MCP server.
See this project's hooks_mcp.yaml as an example.
server_name (optional): Name of the MCP server (default: "HooksMCP")server_description (optional): Description of the MCP server (default: "Project-specific development tools and prompts exposed via MCP")actions (optional): Array of action definitions. If not provided, only prompts will be available.prompts (optional): Array of prompt definitionsget_prompt_tool_filter (optional): Array of prompt names to expose via the get_prompt tool. If unset, all prompts are exposed. If empty, the get_prompt tool is not exposed.Each action in the actions array can have the following fields:
name (required): Unique identifier for the tooldescription (required): Human-readable description of what the tool doescommand (required): The CLI command to execute. May include dynamic parameters like $TEST_FILE_PATH.parameters (optional): Definitions of each parameter used in the command.run_path (optional): Relative path from project root where the command should be executed. Useful for mono-repos.timeout (optional): Timeout in seconds for command execution (default: 60 seconds)Each parameter in an action's parameters array can have the following fields:
name (required): The parameter name to substitute into the command. For example TEST_FILE_PATH.type (required): One of the following parameter types:
project_file_path: A local path within the project, relative to project root.insecure_string: Any string from the model. No validation. Use with caution.required_env_var: An environment variable that must be set before the server starts.optional_env_var : An optional environment variable. Not specified by the calling model.description (optional): description of the parameterdefault (optional): Default value for the parameter if not passedThis parameter type ensures security by validating that the path parameter is within the project boundaries:
- name: "test_file" description: "Run tests in a specific file" command: "python -m pytest $TEST_FILE" parameters: - name: "TEST_FILE" type: "project_file_path" description: "Path to test file" default: "./tests"
Allows any string input from the agent without validation. Use with caution:
- name: "grep_code" description: "Search code for pattern" command: "grep -r $PATTERN src/" parameters: - name: "PATTERN" type: "insecure_string" description: "Pattern to search for"
This is a tool parameter expected to exist as an environment variable. The server will fail to start if the environment is missing this var.
This is useful for specifying that a secret (e.g., API key) is needed, without checking the value into your repository. Typically set up when you configure your MCP server (in mcp.json and similar). When trying to set up the MCP server, it will output a user‑friendly message informing the user they need to add the env var to continue.
HooksMCP will load env vars from the environment, and any set in a .env file in your working directory.
This cannot be passed by the calling model.
- name: "deploy" description: "Deploy the application" command: "deploy-tool --key=$DEPLOY_KEY" parameters: - name: "DEPLOY_KEY" type: "required_env_var" description: "Deployment key for the service"
Similar to required_env_var but optional. The server will not error on startup if this is missing.
- name: "build" description: "Build the application" command: "build-tool" parameters: - name: "BUILD_FLAGS" type: "optional_env_var" description: "Additional build flags"
HooksMCP can be used to share prompts. For example, a "test_guide" prompt explaining preferred test libraries and best practices for tests.
Each prompt in the prompts array can have the following fields:
name (required): Unique identifier for the prompt (max 32 characters)description (required): description of what the prompt does (max 256 characters)prompt (optional): Inline prompt text content. Either prompt or prompt-file must be specified.prompt-file (optional): Relative path to a file containing the prompt text content. Either prompt or prompt-file must be specified.arguments (optional): Definitions of each argument used in the prompt.Each argument in a prompt's arguments array can have the following fields:
name (required): The argument namedescription (optional): description of the argumentrequired (optional): Boolean indicating if the argument is required (default: false)To add a prompt in your template, include it in double curly brackets: {{CODE_SNIPPET}}
Prompts can be defined inline or loaded from files:
prompts: - name: "code_review" description: "Review code for best practices and potential bugs" prompt: "Please review this code for best practices and potential bugs:\n\n{{CODE_SNIPPET}}" arguments: - name: "CODE_SNIPPET" description: "The code to review" required: true - name: "architecture_review" description: "Review system architecture decisions" prompt-file: "./prompts/architecture_review.md"
The MCP protocol supports prompts natively; HooksMCP will provide prompts through the official protocol.
However, many clients only support MCP for tool calls. They either completely ignore prompts, or only expose prompts via a dropdown requiring manual human selection. For these clients, we also expose a MCP tool called get_prompt. This tool automatically enabled when prompts are defined, allowing coding agents to retrieve prompt content by name. Note: the get_prompt tool does not support argument substitution. The model will have to infer how to use the prompt from it's template.
To disable the get_prompt tool you can set:
--disable-prompt-tool CLI argument. This is local to each user.get_prompt_tool_filter in the yaml to limit which prompts are exposed, with an empty list disabling the tool. This is for all users.get_prompt_tool_filter: - "code_review" - "architecture_review"
HooksMCP implements several security measures to help improve security of giving agents access to terminal commands:
Allow List of Commands: Your agents can only run the commands you give it access to in your hooks_mcp.yaml, not arbitrary terminal commands.
Path Parameter Validation All project_file_path parameters are validated to ensure they:
Environment Variable Controls:
required_env_var and optional_env_var parameters are managed by the developer, not the coding assistant. This prevents coding assistants from accessing sensitive variables.Safe Command Execution:
subprocess.run with shell=False to prevent shell injectionshlex.split to properly separate command argumentsThere are some risks to using HooksMCP:
If your agent can edit your hooks_mcp.yaml, it can add commands which it can then run via MCP
If your agent can add code to your project and any of your actions will invoke arbitrary code (like a test runner), the agent can use this pattern to run arbitrary code
HooksMCP may contain bugs or security issues
We don't promise it's perfect, but it's probably better than giving an agent unfettered terminal access. Running inside a container is always recommended for agents.
I built this for my own use building Kiln. The first draft was written by Qwen-Coder-405b, and then it was edited by me. See the initial commit for the prompt.
MIT