1
+ #! /bin/bash
2
+ set -e
3
+
4
+ # Script to analyze differences between mcp-template and derived MCP servers
5
+ # Usage: ./scripts/analyze-template-diff.sh [options]
6
+ #
7
+ # Options:
8
+ # --template-path <path> Path to local mcp-template repo (default: uses GitHub remote)
9
+ # --output <format> Output format: summary, detailed, or files (default: summary)
10
+ # --help Show this help message
11
+
12
+ # Color codes for output
13
+ RED=' \033[0;31m'
14
+ GREEN=' \033[0;32m'
15
+ YELLOW=' \033[1;33m'
16
+ BLUE=' \033[0;34m'
17
+ CYAN=' \033[0;36m'
18
+ NC=' \033[0m' # No Color
19
+
20
+ # Default values
21
+ TEMPLATE_REMOTE=" https://github.com/Mearman/mcp-template.git"
22
+ TEMPLATE_PATH=" "
23
+ OUTPUT_FORMAT=" summary"
24
+
25
+ # Parse command line arguments
26
+ while [[ $# -gt 0 ]]; do
27
+ case $1 in
28
+ --template-path)
29
+ TEMPLATE_PATH=" $2 "
30
+ shift 2
31
+ ;;
32
+ --output)
33
+ OUTPUT_FORMAT=" $2 "
34
+ shift 2
35
+ ;;
36
+ --help)
37
+ grep ' ^#' " $0 " | head -n 9 | tail -n +2 | sed ' s/^# //'
38
+ exit 0
39
+ ;;
40
+ * )
41
+ echo -e " ${RED} Unknown option: $1 ${NC} "
42
+ echo " Use --help for usage information"
43
+ exit 1
44
+ ;;
45
+ esac
46
+ done
47
+
48
+ echo " MCP Template Difference Analyzer"
49
+ echo " ================================"
50
+ echo " "
51
+
52
+ # Check if we're in a git repository
53
+ if ! git rev-parse --git-dir > /dev/null 2>&1 ; then
54
+ echo -e " ${RED} Error: Not in a git repository${NC} "
55
+ exit 1
56
+ fi
57
+
58
+ # Get current repository info
59
+ REPO_PATH=$( git rev-parse --show-toplevel)
60
+ REPO_NAME=$( basename " $REPO_PATH " )
61
+ echo -e " Current repository: ${GREEN} $REPO_NAME ${NC} "
62
+
63
+ # Validate repository structure
64
+ if [ ! -f " package.json" ] || [ ! -d " src" ]; then
65
+ echo -e " ${RED} Error: This doesn't appear to be a valid MCP repository${NC} "
66
+ exit 1
67
+ fi
68
+
69
+ # Create temporary directory for analysis
70
+ TMP_DIR=$( mktemp -d)
71
+ trap " rm -rf $TMP_DIR " EXIT
72
+
73
+ # Get template files
74
+ echo -e " ${YELLOW} Fetching template files...${NC} "
75
+ if [ -n " $TEMPLATE_PATH " ]; then
76
+ # Use local template
77
+ if [ ! -d " $TEMPLATE_PATH " ]; then
78
+ echo -e " ${RED} Error: Template path does not exist: $TEMPLATE_PATH ${NC} "
79
+ exit 1
80
+ fi
81
+ cp -r " $TEMPLATE_PATH " " $TMP_DIR /template"
82
+ else
83
+ # Clone template from GitHub
84
+ git clone --quiet --depth 1 " $TEMPLATE_REMOTE " " $TMP_DIR /template" 2> /dev/null
85
+ fi
86
+
87
+ # Files to analyze
88
+ COMPARE_FILES=(
89
+ " package.json"
90
+ " tsconfig.json"
91
+ " vitest.config.ts"
92
+ " biome.json"
93
+ " commitlint.config.js"
94
+ " .gitignore"
95
+ " src/index.ts"
96
+ " src/cli.ts"
97
+ )
98
+
99
+ # Directories to analyze
100
+ COMPARE_DIRS=(
101
+ " src/utils"
102
+ " src/tools"
103
+ " .github/workflows"
104
+ )
105
+
106
+ echo " "
107
+ echo -e " ${CYAN} Analysis Results:${NC} "
108
+ echo " =================="
109
+
110
+ case " $OUTPUT_FORMAT " in
111
+ " summary" )
112
+ echo " "
113
+ echo -e " ${BLUE} File Differences:${NC} "
114
+ for file in " ${COMPARE_FILES[@]} " ; do
115
+ if [ -f " $file " ] && [ -f " $TMP_DIR /template/$file " ]; then
116
+ if diff -q " $file " " $TMP_DIR /template/$file " > /dev/null 2>&1 ; then
117
+ echo -e " ${GREEN} ✓${NC} $file (identical)"
118
+ else
119
+ echo -e " ${YELLOW} ↻${NC} $file (modified)"
120
+ fi
121
+ elif [ -f " $file " ]; then
122
+ echo -e " ${CYAN} +${NC} $file (only in $REPO_NAME )"
123
+ elif [ -f " $TMP_DIR /template/$file " ]; then
124
+ echo -e " ${RED} -${NC} $file (missing from $REPO_NAME )"
125
+ fi
126
+ done
127
+
128
+ echo " "
129
+ echo -e " ${BLUE} Directory Differences:${NC} "
130
+ for dir in " ${COMPARE_DIRS[@]} " ; do
131
+ if [ -d " $dir " ] && [ -d " $TMP_DIR /template/$dir " ]; then
132
+ local_count=$( find " $dir " -name " *.ts" -o -name " *.js" 2> /dev/null | wc -l | tr -d ' ' )
133
+ template_count=$( find " $TMP_DIR /template/$dir " -name " *.ts" -o -name " *.js" 2> /dev/null | wc -l | tr -d ' ' )
134
+ if [ " $local_count " -eq " $template_count " ]; then
135
+ echo -e " ${GREEN} ✓${NC} $dir ($local_count files)"
136
+ else
137
+ echo -e " ${YELLOW} ↻${NC} $dir ($local_count files vs $template_count in template)"
138
+ fi
139
+ elif [ -d " $dir " ]; then
140
+ local_count=$( find " $dir " -name " *.ts" -o -name " *.js" 2> /dev/null | wc -l | tr -d ' ' )
141
+ echo -e " ${CYAN} +${NC} $dir ($local_count files, only in $REPO_NAME )"
142
+ elif [ -d " $TMP_DIR /template/$dir " ]; then
143
+ template_count=$( find " $TMP_DIR /template/$dir " -name " *.ts" -o -name " *.js" 2> /dev/null | wc -l | tr -d ' ' )
144
+ echo -e " ${RED} -${NC} $dir ($template_count files, missing from $REPO_NAME )"
145
+ fi
146
+ done
147
+
148
+ echo " "
149
+ echo -e " ${BLUE} Package.json Analysis:${NC} "
150
+ if [ -f " package.json" ] && [ -f " $TMP_DIR /template/package.json" ]; then
151
+ # Compare dependencies
152
+ local_deps=$( cat package.json | grep -A 100 ' "dependencies"' | grep -B 100 ' }' | grep ' "' | grep -v ' dependencies' | wc -l | tr -d ' ' )
153
+ template_deps=$( cat " $TMP_DIR /template/package.json" | grep -A 100 ' "dependencies"' | grep -B 100 ' }' | grep ' "' | grep -v ' dependencies' | wc -l | tr -d ' ' )
154
+ echo -e " Dependencies: $local_deps (vs $template_deps in template)"
155
+
156
+ local_dev_deps=$( cat package.json | grep -A 100 ' "devDependencies"' | grep -B 100 ' }' | grep ' "' | grep -v ' devDependencies' | wc -l | tr -d ' ' )
157
+ template_dev_deps=$( cat " $TMP_DIR /template/package.json" | grep -A 100 ' "devDependencies"' | grep -B 100 ' }' | grep ' "' | grep -v ' devDependencies' | wc -l | tr -d ' ' )
158
+ echo -e " Dev Dependencies: $local_dev_deps (vs $template_dev_deps in template)"
159
+
160
+ # Check version
161
+ local_version=$( grep ' "version"' package.json | head -1 | cut -d' "' -f4)
162
+ template_version=$( grep ' "version"' " $TMP_DIR /template/package.json" | head -1 | cut -d' "' -f4)
163
+ echo -e " Version: $local_version (template: $template_version )"
164
+ fi
165
+ ;;
166
+
167
+ " detailed" )
168
+ for file in " ${COMPARE_FILES[@]} " ; do
169
+ if [ -f " $file " ] && [ -f " $TMP_DIR /template/$file " ]; then
170
+ if ! diff -q " $file " " $TMP_DIR /template/$file " > /dev/null 2>&1 ; then
171
+ echo " "
172
+ echo -e " ${YELLOW} Differences in $file :${NC} "
173
+ echo " ----------------------------------------"
174
+ diff -u " $TMP_DIR /template/$file " " $file " || true
175
+ fi
176
+ fi
177
+ done
178
+ ;;
179
+
180
+ " files" )
181
+ echo -e " ${BLUE} Files only in $REPO_NAME :${NC} "
182
+ find . -type f -name " *.ts" -o -name " *.js" -o -name " *.json" -o -name " *.md" | \
183
+ grep -v node_modules | grep -v dist | grep -v coverage | sort | \
184
+ while read -r file; do
185
+ template_file=" $TMP_DIR /template/${file# ./ } "
186
+ if [ ! -f " $template_file " ]; then
187
+ echo " + $file "
188
+ fi
189
+ done
190
+
191
+ echo " "
192
+ echo -e " ${BLUE} Files only in template:${NC} "
193
+ cd " $TMP_DIR /template"
194
+ find . -type f -name " *.ts" -o -name " *.js" -o -name " *.json" -o -name " *.md" | \
195
+ grep -v node_modules | grep -v dist | grep -v coverage | sort | \
196
+ while read -r file; do
197
+ local_file=" $REPO_PATH /${file# ./ } "
198
+ if [ ! -f " $local_file " ]; then
199
+ echo " - $file "
200
+ fi
201
+ done
202
+ cd - > /dev/null
203
+ ;;
204
+
205
+ * )
206
+ echo -e " ${RED} Invalid output format: $OUTPUT_FORMAT ${NC} "
207
+ echo " Valid formats: summary, detailed, files"
208
+ exit 1
209
+ ;;
210
+ esac
211
+
212
+ echo " "
213
+ echo -e " ${GREEN} Analysis complete!${NC} "
214
+ echo " "
215
+ echo " To merge template updates, run:"
216
+ echo " ./scripts/merge-template-updates.sh"
0 commit comments