mirror of
https://github.com/yamadashy/repomix.git
synced 2026-09-19 06:00:49 +08:00
fix(mcp): Mark the launch arguments required and add -y for npx
intent(mcp-registry): address PR review before the first publish, since server.json values are immutable once a version lands on the registry
decision(server-json): mark `--mcp` `isRequired: true` — a client rendering only the required arguments would otherwise emit bare `npx repomix`, which runs the packer and writes repomix-output.xml instead of speaking MCP over stdio
decision(server-json): add `runtimeArguments` with `-y`, matching the `npx -y repomix --mcp` in every mcp-server.md; without it npx can stall on its install prompt on a cold cache, which over stdio is indistinguishable from a server that never starts
learned(mcp-registry): confirmed against the live registry that npm-based entries express this as a positional `-y` in `runtimeArguments`, and that `mcp-publisher validate` accepts the new shape
learned(mcp-registry): verified the hand-written verify URL by hand against a real entry — `/v0.1/servers/{encodedName}/versions/{version}` returns the nested `.server.version` the workflow asserts — so the first real publish is no longer the first exercise of that path
decision(mcp-registry): retry the `npm view mcpName` check 5x10s like the registry verify step, since it runs right after npm-publish.yml and a miss there is more likely propagation lag than a genuinely absent version
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,7 @@ jobs:
|
||||
- name: Install mcp-publisher
|
||||
run: |
|
||||
ARCHIVE="mcp-publisher_linux_amd64.tar.gz"
|
||||
curl -fsSL -o "${ARCHIVE}" \
|
||||
curl -fsSL --retry 3 --retry-delay 2 -o "${ARCHIVE}" \
|
||||
"https://github.com/modelcontextprotocol/registry/releases/download/v${MCP_PUBLISHER_VERSION}/${ARCHIVE}"
|
||||
echo "${MCP_PUBLISHER_SHA256} ${ARCHIVE}" | sha256sum --check
|
||||
tar xzf "${ARCHIVE}" mcp-publisher
|
||||
@@ -73,9 +73,21 @@ jobs:
|
||||
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
||||
SERVER_NAME=$(node -p "require('./server.json').name")
|
||||
# `npm view <pkg> <field>` exits 0 with empty output when the field is
|
||||
# absent and non-zero when the version itself is missing, so npm's own
|
||||
# error is left to surface rather than being collapsed into "empty".
|
||||
PUBLISHED_MCP_NAME=$(npm view "repomix@${PACKAGE_VERSION}" mcpName)
|
||||
# absent and non-zero when the version itself is missing. This workflow
|
||||
# runs right after npm-publish.yml, so a miss here is more likely to be
|
||||
# registry propagation lag than a genuinely absent version: retry on the
|
||||
# non-zero exit, and let npm's own stderr stay in the log either way.
|
||||
for attempt in 1 2 3 4 5; do
|
||||
if PUBLISHED_MCP_NAME=$(npm view "repomix@${PACKAGE_VERSION}" mcpName); then
|
||||
break
|
||||
fi
|
||||
if [ "${attempt}" -eq 5 ]; then
|
||||
echo "::error::repomix@${PACKAGE_VERSION} is not visible on npm"
|
||||
exit 1
|
||||
fi
|
||||
echo "npm metadata not visible yet, retrying in 10s (${attempt}/5)"
|
||||
sleep 10
|
||||
done
|
||||
if [ -z "${PUBLISHED_MCP_NAME}" ]; then
|
||||
echo "::error::repomix@${PACKAGE_VERSION} is published but has no mcpName field"
|
||||
exit 1
|
||||
|
||||
@@ -20,10 +20,19 @@
|
||||
"transport": {
|
||||
"type": "stdio"
|
||||
},
|
||||
"runtimeArguments": [
|
||||
{
|
||||
"type": "positional",
|
||||
"value": "-y",
|
||||
"isRequired": true,
|
||||
"description": "Skip the npx install prompt, which would otherwise stall the stdio handshake on a cold cache"
|
||||
}
|
||||
],
|
||||
"packageArguments": [
|
||||
{
|
||||
"type": "positional",
|
||||
"value": "--mcp",
|
||||
"isRequired": true,
|
||||
"description": "Run Repomix as an MCP server over stdio"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -35,6 +35,10 @@ const getDeclaredCliFlags = (): Set<string> => {
|
||||
// published package.json and comparing it to the `name` in server.json. That
|
||||
// check only runs at publish time, after the npm version is already published
|
||||
// and therefore immutable, so a mismatch is caught here instead.
|
||||
//
|
||||
// Note that the `version` fields committed in server.json are not asserted here:
|
||||
// mcp-registry-publish.yml overwrites them from package.json before publishing,
|
||||
// so the committed values are placeholders and drift from package.json by design.
|
||||
describe('server.json (MCP Registry metadata)', () => {
|
||||
test('mcpName in package.json matches the server.json name', () => {
|
||||
expect(packageJson.mcpName).toBe(serverJson.name);
|
||||
@@ -68,4 +72,25 @@ describe('server.json (MCP Registry metadata)', () => {
|
||||
expect(declaredFlags).toContain(flag);
|
||||
}
|
||||
});
|
||||
|
||||
// Every packaged argument here is a constant needed to start the server, so a
|
||||
// client that renders only the required arguments must still emit all of them.
|
||||
test('every packaged argument is marked required', () => {
|
||||
const npmPackage = serverJson.packages.find((pkg: { registryType: string }) => pkg.registryType === 'npm');
|
||||
|
||||
for (const arg of npmPackage.packageArguments) {
|
||||
expect(arg.isRequired).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
// runtimeArguments go to npx rather than to repomix, so they are checked
|
||||
// against the documented launch command instead of against the CLI flags.
|
||||
// Without `-y`, npx can stall on its install prompt on a cold cache, which
|
||||
// over stdio is indistinguishable from a server that never starts.
|
||||
test('the npx runtime arguments match the documented launch command', () => {
|
||||
const npmPackage = serverJson.packages.find((pkg: { registryType: string }) => pkg.registryType === 'npm');
|
||||
|
||||
expect(npmPackage.runtimeHint).toBe('npx');
|
||||
expect(npmPackage.runtimeArguments.map((arg: { value: string }) => arg.value)).toContain('-y');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user