Skip to main content
Glama
grafana
by grafana
03-local-repo-support.md7.32 kB
# Local Grafana Repository Support Specification ## Overview Add a new CLI option `--grafana-repo-path` (and equivalent environment variable `GRAFANA_REPO_PATH`) to allow users to specify a local Grafana repository path. This option takes precedence over GitHub API access, enabling the MCP server to read components directly from a local filesystem. ## Implementation Plan ### 1. CLI Interface Updates (`src/index.ts`) **Add new CLI option:** - `--grafana-repo-path <path>` / `-l <path>` - Path to local Grafana repository - Environment variable: `GRAFANA_REPO_PATH` - Update help text to document the new option - Precedence: Local repo → GitHub API key → Unauthenticated GitHub **Configuration logic:** ```typescript const { githubApiKey, grafanaRepoPath } = await parseArgs(); if (grafanaRepoPath) { axios.setLocalGrafanaRepo(grafanaRepoPath); console.error("Local Grafana repository configured"); } else if (githubApiKey) { axios.setGitHubApiKey(githubApiKey); console.error("GitHub API key configured"); } ``` ### 2. Core Utilities Enhancement (`src/utils/axios.ts`) **Add local filesystem support:** - New function: `setLocalGrafanaRepo(repoPath: string)` - New internal flag: `localRepoPath: string | null` - Update all existing functions to check local repo first before GitHub API - Add filesystem utilities using Node.js `fs` module **Function modifications:** - `getComponentSource()` - Check local filesystem first - `getComponentDemo()` - Read local `.story.tsx` files - `getAvailableComponents()` - Use `fs.readdir()` on local components directory - `getComponentMetadata()` - Parse local directory structure - `getComponentDocumentation()` - Read local `.mdx` files - `getComponentTests()` - Read local test files - `searchComponents()` - Search local filesystem - `getThemeFiles()` - Read local theme files - `getComponentDependencies()` - Analyze local files - `buildDirectoryTree()` - Build tree from local filesystem **Path resolution:** ```typescript const LOCAL_COMPONENTS_PATH = "packages/grafana-ui/src/components"; const resolveLocalPath = (subPath: string) => path.join(localRepoPath!, subPath); ``` ### 3. Error Handling & Validation **Validation checks:** - Verify local path exists and is readable - Check if path contains expected Grafana structure (`packages/grafana-ui/src/components/`) - Graceful fallback to GitHub API if local files are missing - Clear error messages for invalid local repository paths **Graceful degradation:** - If local file doesn't exist, try GitHub API as fallback - Maintain same error message format for consistency - Log source (local vs GitHub) for debugging ### 4. Performance Optimizations **Local filesystem advantages:** - No rate limiting concerns - Faster file access (no network latency) - Support for modified/uncommitted components - Real-time development workflow support **Caching strategy:** - Minimal caching needed for local files - Optional file modification time checking - Preserve existing GitHub API caching when used as fallback ### 5. Documentation Updates **Help text updates:** - Document new `--grafana-repo-path` option - Explain precedence order (local → GitHub API → unauthenticated) - Add usage examples for local development workflow - Update environment variable documentation **README.md updates:** - New "Local Development" section - Examples of local repository setup - Benefits of local vs GitHub API access - Troubleshooting section for local path issues ## Benefits 1. **Development Workflow**: Developers can work with local, potentially modified components 2. **No Rate Limits**: Unlimited access to components without GitHub API constraints 3. **Faster Access**: Direct filesystem reads are faster than HTTP requests 4. **Offline Support**: Works without internet connection 5. **Real-time Updates**: Reflects local changes immediately 6. **Backward Compatibility**: Existing GitHub API workflow remains unchanged ## Files to Modify 1. `specs/03-local-repo-support.md` - **NEW** - This specification document 2. `src/index.ts` - Add CLI argument parsing for `--grafana-repo-path` option 3. `src/utils/axios.ts` - Add filesystem support and local repo precedence logic 4. `README.md` - Document new local repository feature ## Success Criteria - [ ] CLI accepts `--grafana-repo-path` option and `GRAFANA_REPO_PATH` environment variable - [ ] All 11 MCP tools work with local repository path - [ ] Graceful fallback to GitHub API when local files missing - [ ] Path validation with clear error messages - [ ] Maintains backward compatibility with existing GitHub API workflow - [ ] Documentation updated with local development examples - [ ] No breaking changes to existing functionality ## Implementation Details ### CLI Argument Parsing ```typescript // In parseArgs() function const grafanaRepoPathIndex = args.findIndex( (arg) => arg === "--grafana-repo-path" || arg === "-l", ); let grafanaRepoPath = null; if (grafanaRepoPathIndex !== -1 && args[grafanaRepoPathIndex + 1]) { grafanaRepoPath = args[grafanaRepoPathIndex + 1]; } else if (process.env.GRAFANA_REPO_PATH) { grafanaRepoPath = process.env.GRAFANA_REPO_PATH; } return { githubApiKey, grafanaRepoPath }; ``` ### Filesystem Functions ```typescript // New filesystem utilities in axios.ts import fs from 'fs'; import path from 'path'; let localRepoPath: string | null = null; function setLocalGrafanaRepo(repoPath: string): void { // Validate path exists and has expected structure const componentsPath = path.join(repoPath, LOCAL_COMPONENTS_PATH); if (!fs.existsSync(componentsPath)) { throw new Error(`Invalid Grafana repository path: ${componentsPath} not found`); } localRepoPath = repoPath; } async function getComponentSourceLocal(componentName: string): Promise<string> { if (!localRepoPath) return null; const componentPath = path.join(localRepoPath, LOCAL_COMPONENTS_PATH, componentName, `${componentName}.tsx`); try { return fs.readFileSync(componentPath, 'utf8'); } catch (error) { return null; // Fall back to GitHub API } } ``` ### Help Text Updates ```text Options: --github-api-key, -g <token> GitHub Personal Access Token for API access --grafana-repo-path, -l <path> Path to local Grafana repository (takes precedence over GitHub API) --help, -h Show this help message --version, -v Show version information Environment Variables: GITHUB_PERSONAL_ACCESS_TOKEN Alternative way to provide GitHub token GITHUB_TOKEN Alternative way to provide GitHub token GRAFANA_REPO_PATH Path to local Grafana repository Examples: npx @shelldandy/grafana-ui-mcp-server npx @shelldandy/grafana-ui-mcp-server --github-api-key ghp_your_token_here npx @shelldandy/grafana-ui-mcp-server --grafana-repo-path /path/to/grafana npx @shelldandy/grafana-ui-mcp-server -l /path/to/grafana ``` ## Testing Strategy 1. **Unit Testing**: Test filesystem functions with mock filesystem 2. **Integration Testing**: Test with actual local Grafana repository 3. **Fallback Testing**: Verify GitHub API fallback when local files missing 4. **Error Handling**: Test invalid paths and missing files 5. **Backward Compatibility**: Ensure existing GitHub workflow unaffected

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/grafana/grafana-ui-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server