refresh_skills
Update the skills cache from the repository to ensure access to current AI agent capabilities for document processing, security analysis, and web development tasks.
Instructions
Refresh skills cache from the repository
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/server.ts:339-363 (handler)The MCP tool handler for 'refresh_skills' that executes the onRefresh callback if available, or returns a default message indicating the refresh was triggered.case 'refresh_skills': { if (this.onRefresh) { const result = await this.onRefresh(); return { content: [ { type: 'text', text: JSON.stringify(result), }, ], isError: !result.success, }; } return { content: [ { type: 'text', text: JSON.stringify({ success: true, message: 'Skills refresh triggered. Use list_skills to see updated skills.', }), }, ], }; }
- src/server.ts:194-217 (registration)Schema definition and registration of the 'refresh_skills' tool, including its name, description, input/output schemas, and annotations (marked as idempotent).{ name: 'refresh_skills', description: 'Refresh skills cache from the repository', inputSchema: { type: 'object', properties: {}, }, outputSchema: { type: 'object', properties: { success: { type: 'boolean' }, skillsUpdated: { type: 'number' }, skillsAdded: { type: 'number' }, skillsRemoved: { type: 'number' }, message: { type: 'string' }, }, }, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, },
- src/index.ts:107-152 (handler)The actual implementation of the refresh logic (handleRefresh callback) that syncs with git, parses skills, updates the registry, saves to cache, and returns statistics about the refresh operation.const handleRefresh = async () => { const oldCount = registry.getSkillCount(); logger.info('Manual refresh triggered via MCP tool...'); const result = await gitSync.sync(); if (result.success && result.skillsChanged) { const skills = await skillParser.parseSkillsFromRepo(paths.repoDir, 'repository'); registry.clear(); for (const skill of skills) { registry.registerSkill(skill); } // Load local skills if configured if (config.localSkillsPath) { const localSkills = await skillParser.parseSkillsFromRepo( config.localSkillsPath, 'local' ); for (const skill of localSkills) { registry.registerSkill(skill); } } await cacheManager.saveSkills(registry); registry.setLastSync(new Date()); mcpServer.notifyToolsChanged(); const newCount = registry.getSkillCount(); return { success: true, skillsUpdated: newCount, skillsAdded: Math.max(0, newCount - oldCount), skillsRemoved: Math.max(0, oldCount - newCount), message: `Skills refreshed successfully. Now have ${newCount} skills.`, }; } return { success: result.success, skillsUpdated: registry.getSkillCount(), skillsAdded: 0, skillsRemoved: 0, message: result.success ? 'No changes detected' : result.message, }; };
- src/services/git-sync.ts:70-113 (helper)GitSyncService.sync() method that fetches the latest changes from the git repository and determines if skills have changed by comparing commit hashes.async sync(): Promise<GitSyncResult> { try { if (!existsSync(join(this.repoDir, '.git'))) { return await this.initialize(); } logger.debug('Fetching latest changes...'); // Fetch with depth 1 to check for updates await this.git.fetch(['--depth', '1', 'origin', this.branch]); // Get current and remote HEAD const currentRev = await this.git.revparse(['HEAD']); const remoteRev = await this.git.revparse([`origin/${this.branch}`]); if (currentRev === remoteRev) { logger.debug('Repository is up to date'); return { success: true, updated: false, message: 'Repository is up to date', skillsChanged: false, }; } logger.info('Updates found, pulling changes...'); await this.git.reset(['--hard', `origin/${this.branch}`]); logger.info('Repository updated successfully'); return { success: true, updated: true, message: 'Repository updated successfully', skillsChanged: true, }; } catch (error) { logger.error('Failed to sync repository:', error); return { success: false, updated: false, message: `Sync failed: ${error instanceof Error ? error.message : String(error)}`, }; } }
- src/services/skill-parser.ts:50-76 (helper)SkillParser.parseSkillsFromRepo() method that parses skills from the repository, handling both awesome-list style repositories (README with links) and traditional skills directory structures.async parseSkillsFromRepo(repoDir: string, source: 'repository' | 'local'): Promise<Skill[]> { const skills: Skill[] = []; try { // Check if this is a VoltAgent-style "awesome list" repo (just README with links) const readmePath = join(repoDir, 'README.md'); const skillsDir = join(repoDir, 'skills'); if (existsSync(readmePath) && !existsSync(skillsDir)) { // This is an awesome-list style repo - parse README for skill links logger.info('Detected awesome-list style repository, parsing README for skills...'); const readmeSkills = await this.parseSkillsFromReadme(readmePath, source); skills.push(...readmeSkills); } else if (existsSync(skillsDir)) { // Traditional skills directory structure const dirSkills = await this.parseSkillsFromDirectory(skillsDir, source); skills.push(...dirSkills); } else { logger.warn(`No skills found in ${repoDir}`); } return skills; } catch (error) { logger.error('Failed to parse skills from repository:', error); return skills; } }