Skip to content

Commit 4463737

Browse files
authored
FIX: use a nightly spec.types.ts (#1087)
1 parent 11f04e1 commit 4463737

File tree

6 files changed

+1784
-7
lines changed

6 files changed

+1784
-7
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Update Spec Types
2+
3+
on:
4+
schedule:
5+
# Run nightly at 4 AM UTC
6+
- cron: '0 4 * * *'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
update-spec-types:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: '24'
24+
25+
- name: Install dependencies
26+
run: npm ci
27+
28+
- name: Fetch latest spec types
29+
run: npm run fetch:spec-types
30+
31+
- name: Check for changes
32+
id: check_changes
33+
run: |
34+
if git diff --quiet src/spec.types.ts; then
35+
echo "has_changes=false" >> $GITHUB_OUTPUT
36+
else
37+
echo "has_changes=true" >> $GITHUB_OUTPUT
38+
LATEST_SHA=$(grep "Last updated from commit:" src/spec.types.ts | cut -d: -f2 | tr -d ' ')
39+
echo "sha=$LATEST_SHA" >> $GITHUB_OUTPUT
40+
fi
41+
42+
- name: Create Pull Request
43+
if: steps.check_changes.outputs.has_changes == 'true'
44+
env:
45+
GH_TOKEN: ${{ github.token }}
46+
run: |
47+
git config user.name "github-actions[bot]"
48+
git config user.email "github-actions[bot]@users.noreply.github.com"
49+
50+
git checkout -B update-spec-types
51+
git add src/spec.types.ts
52+
git commit -m "chore: update spec.types.ts from upstream"
53+
git push -f origin update-spec-types
54+
55+
# Create PR if it doesn't exist, or update if it does
56+
PR_BODY="This PR updates \`src/spec.types.ts\` from the Model Context Protocol specification.
57+
58+
Source file: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/${{ steps.check_changes.outputs.sha }}/schema/draft/schema.ts
59+
60+
This is an automated update triggered by the nightly cron job."
61+
62+
if gh pr view update-spec-types &>/dev/null; then
63+
echo "PR already exists, updating description..."
64+
gh pr edit update-spec-types --body "$PR_BODY"
65+
else
66+
gh pr create \
67+
--title "chore: update spec.types.ts from upstream" \
68+
--body "$PR_BODY" \
69+
--base main \
70+
--head update-spec-types
71+
fi

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,6 @@ web_modules/
6969
# Output of 'npm pack'
7070
*.tgz
7171

72-
# Output of 'npm run fetch:spec-types'
73-
spec.types.ts
74-
7572
# Yarn Integrity file
7673
.yarn-integrity
7774

.prettierignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ node_modules
77
**/build
88
**/dist
99
.github/CODEOWNERS
10-
pnpm-lock.yaml
10+
pnpm-lock.yaml
11+
12+
# Ignore generated files
13+
src/spec.types.ts

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"dist"
6060
],
6161
"scripts": {
62-
"fetch:spec-types": "curl -o ./src/spec.types.ts https://raw.githubusercontent.com/modelcontextprotocol/modelcontextprotocol/refs/heads/main/schema/draft/schema.ts",
62+
"fetch:spec-types": "tsx scripts/fetch-spec-types.ts",
6363
"typecheck": "tsgo --noEmit",
6464
"build": "npm run build:esm && npm run build:cjs",
6565
"build:esm": "mkdir -p dist/esm && echo '{\"type\": \"module\"}' > dist/esm/package.json && tsc -p tsconfig.prod.json",
@@ -70,8 +70,8 @@
7070
"prepack": "npm run build:esm && npm run build:cjs",
7171
"lint": "eslint src/ && prettier --check .",
7272
"lint:fix": "eslint src/ --fix && prettier --write .",
73-
"check": "npm run fetch:spec-types && npm run typecheck && npm run lint",
74-
"test": "npm run fetch:spec-types && jest",
73+
"check": "npm run typecheck && npm run lint",
74+
"test": "jest",
7575
"start": "npm run server",
7676
"server": "tsx watch --clear-screen=false scripts/cli.ts server",
7777
"client": "tsx scripts/cli.ts client"

scripts/fetch-spec-types.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { writeFileSync } from 'node:fs';
2+
import { dirname, join } from 'node:path';
3+
import { fileURLToPath } from 'node:url';
4+
5+
const __filename = fileURLToPath(import.meta.url);
6+
const __dirname = dirname(__filename);
7+
const PROJECT_ROOT = join(__dirname, '..');
8+
9+
interface GitHubCommit {
10+
sha: string;
11+
}
12+
13+
async function fetchLatestSHA(): Promise<string> {
14+
const url = 'https://api.github.com/repos/modelcontextprotocol/modelcontextprotocol/commits?path=schema/draft/schema.ts&per_page=1';
15+
16+
const response = await fetch(url);
17+
if (!response.ok) {
18+
throw new Error(`Failed to fetch commit info: ${response.status} ${response.statusText}`);
19+
}
20+
21+
const commits = (await response.json()) as GitHubCommit[];
22+
if (!commits || commits.length === 0) {
23+
throw new Error('No commits found');
24+
}
25+
26+
return commits[0].sha;
27+
}
28+
29+
async function fetchSpecTypes(sha: string): Promise<string> {
30+
const url = `https://raw.githubusercontent.com/modelcontextprotocol/modelcontextprotocol/${sha}/schema/draft/schema.ts`;
31+
32+
const response = await fetch(url);
33+
if (!response.ok) {
34+
throw new Error(`Failed to fetch spec types: ${response.status} ${response.statusText}`);
35+
}
36+
37+
return await response.text();
38+
}
39+
40+
async function main() {
41+
try {
42+
// Check if SHA is provided as command line argument
43+
const providedSHA = process.argv[2];
44+
45+
let latestSHA: string;
46+
if (providedSHA) {
47+
console.log(`Using provided SHA: ${providedSHA}`);
48+
latestSHA = providedSHA;
49+
} else {
50+
console.log('Fetching latest commit SHA...');
51+
latestSHA = await fetchLatestSHA();
52+
}
53+
54+
console.log(`Fetching spec.types.ts from commit: ${latestSHA}`);
55+
56+
const specContent = await fetchSpecTypes(latestSHA);
57+
58+
// Read header template
59+
const headerTemplate = `/**
60+
* This file is automatically generated from the Model Context Protocol specification.
61+
*
62+
* Source: https://github.com/modelcontextprotocol/modelcontextprotocol
63+
* Pulled from: https://raw.githubusercontent.com/modelcontextprotocol/modelcontextprotocol/main/schema/draft/schema.ts
64+
* Last updated from commit: {SHA}
65+
*
66+
* DO NOT EDIT THIS FILE MANUALLY. Changes will be overwritten by automated updates.
67+
* To update this file, run: npm run fetch:spec-types
68+
*/`;
69+
70+
const header = headerTemplate.replace('{SHA}', latestSHA);
71+
72+
// Combine header and content
73+
const fullContent = header + specContent;
74+
75+
// Write to file
76+
const outputPath = join(PROJECT_ROOT, 'src', 'spec.types.ts');
77+
writeFileSync(outputPath, fullContent, 'utf-8');
78+
79+
console.log('Successfully updated src/spec.types.ts');
80+
} catch (error) {
81+
console.error('Error:', error instanceof Error ? error.message : String(error));
82+
process.exit(1);
83+
}
84+
}
85+
86+
main();

0 commit comments

Comments
 (0)