Skip to content

Commit d0c9fe6

Browse files
committed
Add --config flag and AST_GREP_CONFIG env var support
1 parent b6f0cd0 commit d0c9fe6

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ Add to your Claude Desktop MCP configuration:
9090
}
9191
```
9292

93+
### Custom ast-grep Configuration
94+
95+
The MCP server supports using a custom `sgconfig.yaml` file to configure ast-grep behavior.
96+
See the [ast-grep configuration documentation](https://ast-grep.github.io/guide/project/project-config.html) for details on the config file format.
97+
98+
You can provide the config file in two ways (in order of precedence):
99+
100+
1. **Command-line argument**: `--config /path/to/sgconfig.yaml`
101+
2. **Environment variable**: `AST_GREP_CONFIG=/path/to/sgconfig.yaml`
102+
93103
## Usage
94104

95105
This repository includes comprehensive ast-grep rule documentation in [ast-grep.mdc](https://github.com/ast-grep/ast-grep-mcp/blob/main/ast-grep.mdc). The documentation covers all aspects of writing effective ast-grep rules, from simple patterns to complex multi-condition searches.

main.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,51 @@
44
from pydantic import Field
55
import json
66
from enum import Enum
7+
import argparse
8+
import os
9+
import sys
10+
11+
# Determine how the script was invoked
12+
if sys.argv[0].endswith('main.py'):
13+
# Direct execution: python main.py
14+
prog = 'python main.py'
15+
else:
16+
# Installed script execution (via uvx, pip install, etc.)
17+
prog = None # Let argparse use the default
18+
19+
# Parse command-line arguments
20+
parser = argparse.ArgumentParser(
21+
prog=prog,
22+
description='ast-grep MCP Server - Provides structural code search capabilities via Model Context Protocol',
23+
epilog='''
24+
environment variables:
25+
AST_GREP_CONFIG Path to sgconfig.yaml file (overridden by --config flag)
26+
27+
For more information, see: https://github.com/ast-grep/ast-grep-mcp
28+
''',
29+
formatter_class=argparse.RawDescriptionHelpFormatter
30+
)
31+
parser.add_argument(
32+
'--config',
33+
type=str,
34+
metavar='PATH',
35+
help='Path to sgconfig.yaml file for customizing ast-grep behavior (language mappings, rule directories, etc.)'
36+
)
37+
args = parser.parse_args()
38+
39+
# Determine config path with precedence: --config flag > AST_GREP_CONFIG env > None
40+
CONFIG_PATH = None
41+
if args.config:
42+
if not os.path.exists(args.config):
43+
print(f"Error: Config file '{args.config}' does not exist")
44+
sys.exit(1)
45+
CONFIG_PATH = args.config
46+
elif os.environ.get('AST_GREP_CONFIG'):
47+
env_config = os.environ.get('AST_GREP_CONFIG')
48+
if not os.path.exists(env_config):
49+
print(f"Error: Config file '{env_config}' specified in AST_GREP_CONFIG does not exist")
50+
sys.exit(1)
51+
CONFIG_PATH = env_config
752

853
# Initialize FastMCP server
954
mcp = FastMCP("ast-grep")
@@ -40,6 +85,8 @@ def test_match_code_rule(
4085
This is useful to test a rule before using it in a project.
4186
"""
4287
args = ["ast-grep", "scan","--inline-rules", yaml, "--json", "--stdin"]
88+
if CONFIG_PATH:
89+
args.extend(["--config", CONFIG_PATH])
4390
try:
4491
# Run command and capture output
4592
result = subprocess.run(
@@ -82,7 +129,9 @@ def find_code_by_rule(
82129
return run_ast_grep_yaml(yaml, project_folder)
83130

84131
def run_ast_grep_dump(code: str, language: str, format: str) -> str:
85-
args = ["ast-grep", "--pattern", code, "--lang", language, f"--debug-query={format}"]
132+
args = ["ast-grep", "run", "--pattern", code, "--lang", language, f"--debug-query={format}"]
133+
if CONFIG_PATH:
134+
args.extend(["--config", CONFIG_PATH])
86135
try:
87136
result = subprocess.run(
88137
args,
@@ -98,9 +147,12 @@ def run_ast_grep_dump(code: str, language: str, format: str) -> str:
98147

99148
def run_ast_grep_command(pattern: str, project_folder: str, language: Optional[str]) -> List[dict[str, Any]]:
100149
try:
101-
args = ["ast-grep", "--pattern", pattern, "--json", project_folder]
150+
args = ["ast-grep", "run", "--pattern", pattern, "--json"]
151+
if CONFIG_PATH:
152+
args.extend(["--config", CONFIG_PATH])
102153
if language:
103154
args.extend(["--lang", language])
155+
args.append(project_folder)
104156
# Run command and capture output
105157
result = subprocess.run(
106158
args,
@@ -120,6 +172,8 @@ def run_ast_grep_command(pattern: str, project_folder: str, language: Optional[s
120172
def run_ast_grep_yaml(yaml: str, project_folder: str) -> List[dict[str, Any]]:
121173
try:
122174
args = ["ast-grep", "scan","--inline-rules", yaml, "--json", project_folder]
175+
if CONFIG_PATH:
176+
args.extend(["--config", CONFIG_PATH])
123177
# Run command and capture output
124178
result = subprocess.run(
125179
args,

0 commit comments

Comments
 (0)