Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit ccd072c

Browse files
committed
fix: make skills generation deterministic by removing timestamp
1 parent f997890 commit ccd072c

2 files changed

Lines changed: 141 additions & 150 deletions

File tree

src/services/skills/built-in-skills.ts

Lines changed: 141 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
* This file is generated by generate-built-in-skills.ts from the SKILL.md files
55
* in the built-in/ directory. To modify built-in skills, edit the corresponding
66
* SKILL.md file and run: pnpm generate:skills
7-
*
8-
* Generated at: 2026-01-28T23:09:14.137Z
97
*/
108

119
import { SkillMetadata, SkillContent } from "../../shared/skills"
@@ -32,6 +30,7 @@ Unless the user specifies otherwise, new local MCP servers should be created in
3230
MCP servers can be configured in two ways in the MCP settings file:
3331
3432
1. Local (Stdio) Server Configuration:
33+
3534
\`\`\`json
3635
{
3736
"mcpServers": {
@@ -47,6 +46,7 @@ MCP servers can be configured in two ways in the MCP settings file:
4746
\`\`\`
4847
4948
2. Remote (SSE) Server Configuration:
49+
5050
\`\`\`json
5151
{
5252
"mcpServers": {
@@ -61,6 +61,7 @@ MCP servers can be configured in two ways in the MCP settings file:
6161
\`\`\`
6262
6363
Common configuration options for both types:
64+
6465
- \`disabled\`: (optional) Set to true to temporarily disable the server
6566
- \`timeout\`: (optional) Maximum time in seconds to wait for server responses (default: 60)
6667
- \`alwaysAllow\`: (optional) Array of tool names that don't require user confirmation
@@ -105,178 +106,170 @@ weather-server/
105106
106107
\`\`\`typescript
107108
#!/usr/bin/env node
108-
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
109-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
110-
import { z } from "zod";
111-
import axios from 'axios';
109+
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"
110+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
111+
import { z } from "zod"
112+
import axios from "axios"
112113
113-
const API_KEY = process.env.OPENWEATHER_API_KEY; // provided by MCP config
114+
const API_KEY = process.env.OPENWEATHER_API_KEY // provided by MCP config
114115
if (!API_KEY) {
115-
throw new Error('OPENWEATHER_API_KEY environment variable is required');
116+
throw new Error("OPENWEATHER_API_KEY environment variable is required")
116117
}
117118
118119
// Define types for OpenWeather API responses
119120
interface WeatherData {
120-
main: {
121-
temp: number;
122-
humidity: number;
123-
};
124-
weather: Array<{
125-
description: string;
126-
}>;
127-
wind: {
128-
speed: number;
129-
};
121+
main: {
122+
temp: number
123+
humidity: number
124+
}
125+
weather: Array<{
126+
description: string
127+
}>
128+
wind: {
129+
speed: number
130+
}
130131
}
131132
132133
interface ForecastData {
133-
list: Array<WeatherData & {
134-
dt_txt: string;
135-
}>;
134+
list: Array<
135+
WeatherData & {
136+
dt_txt: string
137+
}
138+
>
136139
}
137140
138141
// Create an MCP server
139142
const server = new McpServer({
140-
name: "weather-server",
141-
version: "0.1.0"
142-
});
143+
name: "weather-server",
144+
version: "0.1.0",
145+
})
143146
144147
// Create axios instance for OpenWeather API
145148
const weatherApi = axios.create({
146-
baseURL: 'http://api.openweathermap.org/data/2.5',
147-
params: {
148-
appid: API_KEY,
149-
units: 'metric',
150-
},
151-
});
149+
baseURL: "http://api.openweathermap.org/data/2.5",
150+
params: {
151+
appid: API_KEY,
152+
units: "metric",
153+
},
154+
})
152155
153156
// Add a tool for getting weather forecasts
154157
server.tool(
155-
"get_forecast",
156-
{
157-
city: z.string().describe("City name"),
158-
days: z.number().min(1).max(5).optional().describe("Number of days (1-5)"),
159-
},
160-
async ({ city, days = 3 }) => {
161-
try {
162-
const response = await weatherApi.get<ForecastData>('forecast', {
163-
params: {
164-
q: city,
165-
cnt: Math.min(days, 5) * 8,
166-
},
167-
});
168-
169-
return {
170-
content: [
171-
{
172-
type: "text",
173-
text: JSON.stringify(response.data.list, null, 2),
174-
},
175-
],
176-
};
177-
} catch (error) {
178-
if (axios.isAxiosError(error)) {
179-
return {
180-
content: [
181-
{
182-
type: "text",
183-
text: \`Weather API error: \${
184-
error.response?.data.message ?? error.message
185-
}\`,
186-
},
187-
],
188-
isError: true,
189-
};
190-
}
191-
throw error;
192-
}
193-
}
194-
);
158+
"get_forecast",
159+
{
160+
city: z.string().describe("City name"),
161+
days: z.number().min(1).max(5).optional().describe("Number of days (1-5)"),
162+
},
163+
async ({ city, days = 3 }) => {
164+
try {
165+
const response = await weatherApi.get<ForecastData>("forecast", {
166+
params: {
167+
q: city,
168+
cnt: Math.min(days, 5) * 8,
169+
},
170+
})
171+
172+
return {
173+
content: [
174+
{
175+
type: "text",
176+
text: JSON.stringify(response.data.list, null, 2),
177+
},
178+
],
179+
}
180+
} catch (error) {
181+
if (axios.isAxiosError(error)) {
182+
return {
183+
content: [
184+
{
185+
type: "text",
186+
text: \`Weather API error: \${error.response?.data.message ?? error.message}\`,
187+
},
188+
],
189+
isError: true,
190+
}
191+
}
192+
throw error
193+
}
194+
},
195+
)
195196
196197
// Add a resource for current weather in San Francisco
197-
server.resource(
198-
"sf_weather",
199-
{ uri: "weather://San Francisco/current", list: true },
200-
async (uri) => {
201-
try {
202-
const response = weatherApi.get<WeatherData>('weather', {
203-
params: { q: "San Francisco" },
204-
});
205-
206-
return {
207-
contents: [
208-
{
209-
uri: uri.href,
210-
mimeType: "application/json",
211-
text: JSON.stringify(
212-
{
213-
temperature: response.data.main.temp,
214-
conditions: response.data.weather[0].description,
215-
humidity: response.data.main.humidity,
216-
wind_speed: response.data.wind.speed,
217-
timestamp: new Date().toISOString(),
218-
},
219-
null,
220-
2
221-
),
222-
},
223-
],
224-
};
225-
} catch (error) {
226-
if (axios.isAxiosError(error)) {
227-
throw new Error(\`Weather API error: \${
228-
error.response?.data.message ?? error.message
229-
}\`);
230-
}
231-
throw error;
232-
}
233-
}
234-
);
198+
server.resource("sf_weather", { uri: "weather://San Francisco/current", list: true }, async (uri) => {
199+
try {
200+
const response = weatherApi.get<WeatherData>("weather", {
201+
params: { q: "San Francisco" },
202+
})
203+
204+
return {
205+
contents: [
206+
{
207+
uri: uri.href,
208+
mimeType: "application/json",
209+
text: JSON.stringify(
210+
{
211+
temperature: response.data.main.temp,
212+
conditions: response.data.weather[0].description,
213+
humidity: response.data.main.humidity,
214+
wind_speed: response.data.wind.speed,
215+
timestamp: new Date().toISOString(),
216+
},
217+
null,
218+
2,
219+
),
220+
},
221+
],
222+
}
223+
} catch (error) {
224+
if (axios.isAxiosError(error)) {
225+
throw new Error(\`Weather API error: \${error.response?.data.message ?? error.message}\`)
226+
}
227+
throw error
228+
}
229+
})
235230
236231
// Add a dynamic resource template for current weather by city
237232
server.resource(
238-
"current_weather",
239-
new ResourceTemplate("weather://{city}/current", { list: true }),
240-
async (uri, { city }) => {
241-
try {
242-
const response = await weatherApi.get('weather', {
243-
params: { q: city },
244-
});
245-
246-
return {
247-
contents: [
248-
{
249-
uri: uri.href,
250-
mimeType: "application/json",
251-
text: JSON.stringify(
252-
{
253-
temperature: response.data.main.temp,
254-
conditions: response.data.weather[0].description,
255-
humidity: response.data.main.humidity,
256-
wind_speed: response.data.wind.speed,
257-
timestamp: new Date().toISOString(),
258-
},
259-
null,
260-
2
261-
),
262-
},
263-
],
264-
};
265-
} catch (error) {
266-
if (axios.isAxiosError(error)) {
267-
throw new Error(\`Weather API error: \${
268-
error.response?.data.message ?? error.message
269-
}\`);
270-
}
271-
throw error;
272-
}
273-
}
274-
);
233+
"current_weather",
234+
new ResourceTemplate("weather://{city}/current", { list: true }),
235+
async (uri, { city }) => {
236+
try {
237+
const response = await weatherApi.get("weather", {
238+
params: { q: city },
239+
})
240+
241+
return {
242+
contents: [
243+
{
244+
uri: uri.href,
245+
mimeType: "application/json",
246+
text: JSON.stringify(
247+
{
248+
temperature: response.data.main.temp,
249+
conditions: response.data.weather[0].description,
250+
humidity: response.data.main.humidity,
251+
wind_speed: response.data.wind.speed,
252+
timestamp: new Date().toISOString(),
253+
},
254+
null,
255+
2,
256+
),
257+
},
258+
],
259+
}
260+
} catch (error) {
261+
if (axios.isAxiosError(error)) {
262+
throw new Error(\`Weather API error: \${error.response?.data.message ?? error.message}\`)
263+
}
264+
throw error
265+
}
266+
},
267+
)
275268
276269
// Start receiving messages on stdin and sending messages on stdout
277-
const transport = new StdioServerTransport();
278-
await server.connect(transport);
279-
console.error('Weather MCP server running on stdio');
270+
const transport = new StdioServerTransport()
271+
await server.connect(transport)
272+
console.error("Weather MCP server running on stdio")
280273
\`\`\`
281274
282275
(Remember: This is just an example–you may use different dependencies, break the implementation up into multiple files, etc.)

src/services/skills/generate-built-in-skills.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,6 @@ function generateTypeScript(skills: Record<string, SkillData>): string {
154154
* This file is generated by generate-built-in-skills.ts from the SKILL.md files
155155
* in the built-in/ directory. To modify built-in skills, edit the corresponding
156156
* SKILL.md file and run: pnpm generate:skills
157-
*
158-
* Generated at: ${new Date().toISOString()}
159157
*/
160158
161159
import { SkillMetadata, SkillContent } from "../../shared/skills"

0 commit comments

Comments
 (0)