Skip to content

Commit 2045a64

Browse files
committed
fix: rename server files with transport suffix
- community.1password.json -> community.1password-npx.json (id: community.1password-npx) Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
1 parent f569fcc commit 2045a64

3 files changed

Lines changed: 268 additions & 2 deletions

File tree

inventory.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""Inventory all NEW server definitions across fix branches with transport details."""
2+
import json, subprocess, re
3+
4+
main_files = set(subprocess.check_output(
5+
['git', 'ls-tree', '-r', '--name-only', 'main', '--', 'servers/'],
6+
text=True
7+
).strip().split('\n'))
8+
9+
branches = subprocess.check_output(['git', 'branch', '--list', 'fix/*'], text=True).strip().split('\n')
10+
branches = [b.strip().lstrip('* ') for b in branches if b.strip()]
11+
12+
servers = []
13+
14+
for branch in sorted(branches):
15+
try:
16+
files = subprocess.check_output(
17+
['git', 'ls-tree', '-r', '--name-only', branch, '--', 'servers/'],
18+
text=True
19+
).strip().split('\n')
20+
except:
21+
continue
22+
23+
new_files = [f for f in files if f not in main_files and f.endswith('.json')]
24+
25+
for f in new_files:
26+
try:
27+
content = subprocess.check_output(['git', 'show', f'{branch}:{f}'], text=True)
28+
defn = json.loads(content)
29+
except:
30+
continue
31+
32+
transport = defn.get('transport', {})
33+
t_type = transport.get('type', '?')
34+
command = transport.get('command', '')
35+
url = transport.get('url', '')
36+
repo = defn.get('links', {}).get('repository', '')
37+
name = defn.get('name', '?')
38+
defn_id = defn.get('id', '?')
39+
40+
if t_type == 'stdio':
41+
tool = command # npx, uvx, docker, etc.
42+
elif t_type == 'http':
43+
tool = 'http'
44+
else:
45+
tool = '?'
46+
47+
# Check if filename already has transport suffix
48+
base = f.replace('servers/', '').replace('.json', '')
49+
has_suffix = any(base.endswith(s) for s in ['-npx', '-uvx', '-docker', '-http'])
50+
51+
servers.append({
52+
'branch': branch,
53+
'file': f,
54+
'id': defn_id,
55+
'name': name,
56+
'transport': t_type,
57+
'tool': tool,
58+
'repo': repo,
59+
'has_suffix': has_suffix,
60+
})
61+
62+
# Print grouped by branch
63+
print(f"{'Branch':<25} {'File':<45} {'Tool':<8} {'Has Suffix':<12} {'Repo'}")
64+
print('-' * 160)
65+
for s in servers:
66+
print(f"{s['branch']:<25} {s['file']:<45} {s['tool']:<8} {str(s['has_suffix']):<12} {s['repo']}")
67+
68+
# Summary: files needing rename (no transport suffix for stdio)
69+
print(f"\n\n=== FILES NEEDING RENAME (no transport suffix) ===")
70+
need_rename = [s for s in servers if not s['has_suffix'] and s['tool'] in ('npx', 'uvx', 'docker')]
71+
for s in need_rename:
72+
suggested = s['file'].replace('.json', f"-{s['tool']}.json")
73+
print(f" {s['branch']}: {s['file']} -> {suggested}")
74+
print(f"\nTotal needing rename: {len(need_rename)}")
75+
76+
# Unique repos for Docker check
77+
print(f"\n\n=== UNIQUE REPOS TO CHECK FOR DOCKER ===")
78+
repos = sorted(set(s['repo'] for s in servers if s['repo'] and 'github.com' in s['repo']))
79+
for r in repos:
80+
print(f" {r}")
81+
print(f"\nTotal repos: {len(repos)}")

rename_files.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
"""Rename server definition files to include transport tool suffix.
2+
Also updates the 'id' and 'name' fields inside each JSON file.
3+
Skips HTTP-only servers (they don't need a suffix since HTTP implies remote).
4+
Skips files that already have the correct suffix.
5+
"""
6+
import json, subprocess, sys, os
7+
8+
# Files that should NOT get renamed (HTTP-only, no stdio variant, or special cases)
9+
SKIP_BRANCHES = set()
10+
# HTTP servers don't need transport suffix - they use the URL as transport
11+
HTTP_ONLY_FILES = {
12+
'com.asana-mcp.json',
13+
'com.clerk-mcp.json',
14+
'com.cloudflare-observability.json',
15+
'com.figma-mcp.json',
16+
'com.honeycomb-mcp.json',
17+
'io.intercom-mcp.json',
18+
'io.sanity-mcp.json',
19+
'com.stytch-mcp.json',
20+
'com.vercel-mcp.json',
21+
'town.val-mcp.json',
22+
# These already have proper suffixes
23+
'com.apify-mcp-http.json',
24+
'com.linear-mcp-http.json',
25+
'com.square-mcp-http.json',
26+
'com.vercel-mcp-http.json',
27+
'com.mongodb-mcp-npx.json',
28+
'com.mongodb-mcp-docker.json',
29+
}
30+
31+
# Special: snyk uses 'snyk' command not npx/uvx/docker
32+
SPECIAL_TOOLS = {
33+
'com.snyk-mcp.json': 'cli', # snyk cli, not a standard transport
34+
}
35+
36+
def get_tool_suffix(transport):
37+
"""Determine the suffix based on transport command."""
38+
if transport.get('type') == 'http':
39+
return 'http'
40+
cmd = transport.get('command', '')
41+
if cmd in ('npx', 'uvx', 'docker'):
42+
return cmd
43+
if cmd == 'snyk':
44+
return 'cli'
45+
return cmd if cmd else None
46+
47+
def run(args, **kwargs):
48+
return subprocess.run(args, capture_output=True, text=True, **kwargs)
49+
50+
def main():
51+
os.chdir('d:\\mcpmux\\mcp-servers')
52+
53+
# Get main files to skip
54+
main_files = set(run(['git', 'ls-tree', '-r', '--name-only', 'main', '--', 'servers/']).stdout.strip().split('\n'))
55+
56+
branches = run(['git', 'branch', '--list', 'fix/*']).stdout.strip().split('\n')
57+
branches = [b.strip().lstrip('* ') for b in branches if b.strip()]
58+
59+
results = []
60+
61+
for branch in sorted(branches):
62+
if branch in SKIP_BRANCHES:
63+
continue
64+
65+
# Get new files in this branch
66+
files_out = run(['git', 'ls-tree', '-r', '--name-only', branch, '--', 'servers/'])
67+
if files_out.returncode != 0:
68+
continue
69+
all_files = files_out.stdout.strip().split('\n')
70+
new_files = [f for f in all_files if f not in main_files and f.endswith('.json')]
71+
72+
if not new_files:
73+
continue
74+
75+
# Check out branch
76+
co = run(['git', 'checkout', branch])
77+
if co.returncode != 0:
78+
print(f"SKIP {branch}: checkout failed")
79+
continue
80+
81+
changed = False
82+
renames = []
83+
84+
for f in new_files:
85+
basename = os.path.basename(f)
86+
87+
if basename in HTTP_ONLY_FILES:
88+
continue
89+
90+
# Check if already has suffix
91+
name_no_ext = basename.replace('.json', '')
92+
if any(name_no_ext.endswith(s) for s in ['-npx', '-uvx', '-docker', '-http', '-cli']):
93+
continue
94+
95+
# Read and parse
96+
try:
97+
with open(f) as fh:
98+
defn = json.load(fh)
99+
except:
100+
print(f"SKIP {branch}/{basename}: can't parse")
101+
continue
102+
103+
transport = defn.get('transport', {})
104+
suffix = get_tool_suffix(transport)
105+
106+
if not suffix:
107+
print(f"SKIP {branch}/{basename}: unknown tool")
108+
continue
109+
110+
# For HTTP-only servers (no stdio), skip suffix
111+
if suffix == 'http' and basename not in HTTP_ONLY_FILES:
112+
# This is an HTTP file paired with a stdio variant - already has -http suffix check above
113+
continue
114+
115+
# Compute new filename and id
116+
new_basename = name_no_ext + f'-{suffix}.json'
117+
new_path = f'servers/{new_basename}'
118+
new_id = defn['id'] + f'-{suffix}'
119+
120+
# Update name to include tool
121+
old_name = defn.get('name', '')
122+
suffix_label = suffix.upper() if suffix == 'uvx' else suffix
123+
if suffix == 'npx':
124+
new_name = f"{old_name} (npx)"
125+
elif suffix == 'uvx':
126+
new_name = f"{old_name} (uvx)"
127+
elif suffix == 'docker':
128+
new_name = f"{old_name} (Docker)"
129+
elif suffix == 'cli':
130+
new_name = f"{old_name} (CLI)"
131+
else:
132+
new_name = old_name
133+
134+
# Update definition
135+
defn['id'] = new_id
136+
defn['name'] = new_name
137+
138+
with open(f, 'w') as fh:
139+
json.dump(defn, fh, indent=2)
140+
fh.write('\n')
141+
142+
# Git mv
143+
mv = run(['git', 'mv', f, new_path])
144+
if mv.returncode != 0:
145+
print(f"ERROR {branch}: git mv {f} -> {new_path} failed: {mv.stderr}")
146+
continue
147+
148+
renames.append((basename, new_basename, new_id))
149+
changed = True
150+
151+
if changed:
152+
# Stage and commit
153+
run(['git', 'add', '-A'])
154+
msg = f"fix: rename server files with transport suffix\n\n"
155+
for old, new, nid in renames:
156+
msg += f"- {old} -> {new} (id: {nid})\n"
157+
158+
commit = run(['git', 'commit', '-s',
159+
'--author=Mohammod Al Amin Ashik <maa.ashik00@gmail.com>',
160+
'-m', msg])
161+
if commit.returncode != 0:
162+
print(f"ERROR {branch}: commit failed: {commit.stderr}")
163+
continue
164+
165+
# Push
166+
push = run(['git', 'push', 'origin', branch])
167+
if push.returncode != 0:
168+
print(f"ERROR {branch}: push failed: {push.stderr}")
169+
continue
170+
171+
for old, new, nid in renames:
172+
print(f"OK {branch}: {old} -> {new}")
173+
results.append((branch, old, new))
174+
else:
175+
# Nothing to rename in this branch
176+
pass
177+
178+
# Switch back to main
179+
run(['git', 'checkout', 'main'])
180+
181+
print(f"\n=== SUMMARY ===")
182+
print(f"Renamed {len(results)} files across {len(set(r[0] for r in results))} branches")
183+
184+
if __name__ == '__main__':
185+
main()
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "../schemas/server-definition.schema.json",
3-
"id": "community.1password",
4-
"name": "1Password",
3+
"id": "community.1password-npx",
4+
"name": "1Password (npx)",
55
"alias": "1password",
66
"description": "Access secrets from 1Password vaults. List vaults, retrieve items, and search for credentials using a service account token.",
77
"icon": "https://avatars.githubusercontent.com/u/38230737?v=4",

0 commit comments

Comments
 (0)