octocode-mcp 2.3.10 → 2.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +71 -173
  2. package/build/index.js +211 -166
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  **The Perfect AI Code Assistant - Advanced Search & Discovery Across GitHub & NPM**
4
4
 
5
5
  <div>
6
- <img src="./assets/logo.png">
6
+ <img src="./assets/logo.png" width="400px">
7
7
 
8
8
  [![Version](https://img.shields.io/badge/version-2.3.2-blue.svg)](./package.json)
9
9
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](./package.json)
@@ -13,44 +13,25 @@
13
13
 
14
14
  ## What is Octocode? 🐙
15
15
 
16
- **The perfect code assistant that can help understand anything.** Octocode was built to understand connections between repositories and NPM packages under any privilege level you have. With **AI-powered advanced search**, heuristic discovery, and smart fallbacks, it makes GitHub's vast repository of knowledge truly searchable and analyzable.
17
-
18
- Instead of manually browsing repositories, you can ask questions like:
16
+ **The perfect code assistant that can help understand anything.** Octocode provides AI-powered advanced search with heuristic discovery and smart fallbacks to understand connections between repositories and NPM packages across any privilege level you have.
19
17
 
18
+ Instead of manually browsing repositories, ask questions like:
20
19
  - *"How did React implement concurrent rendering?"*
21
20
  - *"Show me authentication patterns in Next.js applications"*
22
21
  - *"Find examples of how to use this specific API"*
23
22
  - *"What's the architecture of this library?"*
24
23
  - *"How do I use this MCP tool effectively?"*
25
24
 
26
- ## Recommended Use Cases
27
-
28
- **Use Octocode when you need to:**
29
-
30
- - **🔍 Understand implementations** - See how features work across different repositories
31
- - **📚 Find real code examples** - Discover patterns and best practices from production code
32
- - **🏗️ Analyze architecture** - Explore how systems are designed and structured
33
- - **🔬 Research approaches** - Compare different implementation strategies
34
- - **💡 Learn from code** - Deep-dive into technical details and understand "how does this work?"
35
-
36
25
  ## Unique Value Proposition
37
26
 
38
27
  **The most advanced AI-powered code assistant for understanding connections across the entire GitHub & NPM ecosystem.** While other GitHub MCPs focus on project management or basic operations, Octocode provides unparalleled depth for code discovery and technical research.
39
28
 
40
- **🚀 Out-of-the-Box Advanced Search (Powered by AI):**
41
- - **🧠 Heuristic Search** - Intelligent pattern recognition that finds relevant code even with vague queries
42
- - **🔄 Smart Fallbacks** - Automatic retry with alternative search strategies when initial searches fail
43
- - **🎯 Smart Discovery** - AI-guided exploration that uncovers hidden connections and patterns
44
- - **🔗 Connection Intelligence** - Understands relationships between repositories, packages, and dependencies
45
- - **📊 Multi-dimensional Analysis** - Combines code, commits, issues, discussions, and package data
46
-
47
29
  **Key Differentiators:**
48
- - **🧠 Advanced AI Search** - Heuristic algorithms that understand code context and connections
49
- - **🔐 Secure & Simple** - No personal access tokens needed, uses [GitHub CLI](https://cli.github.com/) authentication
50
- - **🔗 Connected Discovery** - Maps NPM packages to repositories, traces dependencies, finds related code
51
- - **🌐 Cross-Ecosystem Understanding** - Works across any privilege level you have (public, private, organization)
52
-
53
- It's the tool you reach for when you need to understand *"how does this work?"* rather than *"how do I manage this project?"*
30
+ - **🧠 AI-Powered Search** - Heuristic algorithms with smart fallbacks that understand code context and find relevant code even with vague queries
31
+ - **🔐 Zero-Config Security** - Uses GitHub CLI authentication - no personal access tokens needed
32
+ - **🔗 Connection Intelligence** - Maps NPM packages to repositories, traces dependencies, finds related implementations
33
+ - **🌐 Universal Access** - Works seamlessly with public, private, and organization repositories
34
+ - **⚡ LLM Optimized** - Advanced content minification and partial fetching reduces token usage by 80-90%
54
35
 
55
36
  ## Quick Start 🚀
56
37
 
@@ -74,13 +55,11 @@ gh auth login
74
55
  npm login
75
56
  ```
76
57
 
77
- **🔐 GitHub Authentication via CLI:**
78
- - ✅ **No personal access tokens needed** - Uses [GitHub CLI](https://cli.github.com/) behind the scenes
79
- - ✅ **Secure OAuth flow** - Browser-based authentication, no tokens to store
58
+ **🔐 Authentication Benefits:**
59
+ - ✅ **No personal access tokens** - Uses GitHub CLI OAuth flow
80
60
  - ✅ **Enterprise ready** - Works with SSO, 2FA, and organization access
81
- - ✅ **Private repository access** - Automatically detects your organizations and accesses private repos
82
- - ✅ **Zero configuration** - Uses your existing `gh` CLI permissions
83
-
61
+ - ✅ **Automatic organization detection** - Instantly accesses your private repositories
62
+ - ✅ **Zero configuration** - Uses existing `gh` CLI permissions
84
63
 
85
64
  ### 3. Add to MCP Configuration
86
65
  ```json
@@ -92,157 +71,95 @@ npm login
92
71
  }
93
72
  ```
94
73
 
95
- **That's it!** No personal access tokens, no config files, no complex setup. Octocode leverages [GitHub CLI](https://cli.github.com/) authentication behind the scenes and **automatically works with your organization's private repositories**.
74
+ **That's it!** Octocode automatically works with your organization's private repositories.
96
75
 
97
- ## How Octocode Works 🔄
76
+ ## How It Works 🔄
98
77
 
99
78
  **Smart Discovery Flow:**
100
- 1. **🔍 Query Analysis** → AI determines the best search strategy based on your question
101
- 2. **⚡ Multi-Tool Orchestration** → Intelligently combines 10 specialized tools across GitHub + NPM
102
- 3. **🔄 Smart Fallbacks** → Automatically retries with different approaches if initial search fails
103
- 4. **🔗 Cross-Reference Discovery** → Links packages to repositories, finds related implementations with commit SHA integration
104
- 5. **🎯 Context Synthesis** → Provides comprehensive understanding across multiple sources
79
+ 1. **🔍 Query Analysis** → AI determines the best search strategy
80
+ 2. **⚡ Multi-Tool Orchestration** → Intelligently combines 10 specialized tools
81
+ 3. **🔄 Smart Fallbacks** → Automatically retries with different approaches
82
+ 4. **🔗 Cross-Reference Discovery** → Links packages to repositories with commit SHA integration
83
+ 5. **🎯 Context Synthesis** → Provides comprehensive understanding
105
84
 
106
85
  ## Example Flows
107
86
 
108
87
  ### Example 1: LangGraph Node.js Implementation Tutorial
109
88
  **Query:** "Show implementations of langgraph in node js. Make a tutorial for how to implement a simple agent using OpenAI API."
110
89
 
111
- [![LangGraph Node.js Tutorial](assets/langchainTutorial.gif)](https://youtu.be/E5HUlRckpvg?si=XXLle59C92esDscS)
90
+ <a href="https://youtu.be/E5HUlRckpvg?si=XXLle59C92esDscS"><img src="assets/langchainTutorial.gif" alt="LangGraph Node.js Tutorial" width="50%"></a>
112
91
 
113
92
  ### Example 2: Zustand React State Management
114
93
  **Query:** "Show me how to add zustand to react application. Show examples and best practices"
115
94
 
116
- [![Zustand React State Management](assets/reactZustand.gif)](https://youtu.be/EgYbsuWmqsI?si=CN_KwCPgwprImynU)
95
+ <a href="https://youtu.be/EgYbsuWmqsI?si=CN_KwCPgwprImynU"><img src="assets/reactZustand.gif" alt="Zustand React State Management" width="50%"></a>
117
96
 
118
97
  ### Example 3: React vs Vue.js Rendering Comparison
119
98
  **Query:** "How did React implement their concurrent rendering flows? How is it different from Vue.js rendering mechanism? Which is better?"
120
99
 
121
- [![React vs Vue.js Rendering Comparison](assets/reactVSVueJS.gif)](https://youtu.be/-_pbCbLXKDc?si=KiPeGCzmwWtb6G3r)
100
+ <a href="https://youtu.be/-_pbCbLXKDc?si=KiPeGCzmwWtb6G3r"><img src="assets/reactVSVueJS.gif" alt="React vs Vue.js Rendering Comparison" width="50%"></a>
122
101
 
123
102
  ## Core Features 🛠️
124
103
 
125
- ### 🧠 AI-Powered Advanced Search
126
- - **Heuristic Pattern Recognition** - Finds relevant code even with vague or incomplete queries
127
- - **Smart Fallback Strategies** - Automatically tries alternative approaches when searches fail with actionable suggestions
128
- - **Boolean Search Intelligence** - Automatic query optimization with smart boolean operators (3-5x performance improvement)
129
- - **Context-Aware Discovery** - Understands code relationships and suggests related implementations
130
- - **Multi-Strategy Search** - Combines semantic, syntactic, and dependency-based search methods
131
- - **Graceful Error Recovery** - Comprehensive error handling with intelligent retry mechanisms
132
-
133
- ### 🔗 Connection Intelligence
134
- - **Repository-Package Mapping** - Automatically links NPM packages to their GitHub repositories
135
- - **Dependency Tracing** - Follows dependency chains across the entire ecosystem
136
- - **Cross-Reference Analysis** - Finds how different projects implement similar patterns
137
- - **Ecosystem Understanding** - Maps relationships between libraries, frameworks, and tools
138
-
139
- ### 🌐 Universal Access & Discovery
140
- - **Cross-Privilege Search** - Works with any access level you have (public, private, organization)
141
- - **Organization-Aware** - Automatically detects and uses your GitHub organization memberships
142
- - **Smart Repository Discovery** - Finds relevant repositories even when you don't know they exist
143
- - **Progressive Refinement** - AI-guided search that gets more precise with each iteration
144
-
145
- ### 📊 Multi-Dimensional Analysis
146
- - **Code + Context** - Combines source code with commits, issues, discussions, and documentation
147
- - **Historical Understanding** - Tracks how implementations evolved over time
148
- - **Community Insights** - Discovers patterns from real-world usage and discussions
149
- - **Quality Signals** - Uses NPM publication and GitHub activity as quality indicators
104
+ ### 🧠 AI-Powered Intelligence
105
+ - **Advanced Search** - Heuristic pattern recognition with automatic fallback strategies
106
+ - **Connection Mapping** - Automatically links NPM packages to GitHub repositories
107
+ - **Cross-Reference Analysis** - Discovers how different projects implement similar patterns
108
+ - **Progressive Refinement** - AI-guided search that improves with each iteration
109
+ - **Context-Aware Discovery** - Understands relationships between code, commits, issues, and discussions
150
110
 
151
111
  ### 🔗 Commit SHA Integration
152
- - **Time Travel Code Viewing** - View files from specific commits and pull requests using commit SHAs
153
- - **PR Code Analysis** - Automatically fetch commit SHAs from pull requests for precise code comparison
154
- - **Historical Implementation** - Compare how code evolved across different commits and versions
155
- - **Cross-Reference Discovery** - Link commits, pull requests, and current implementations seamlessly
156
-
157
- ### ⚡ LLM Content Optimization
158
- - **Intelligent Content Selection** - Automatically identifies and extracts only relevant code sections for research
159
- - **Smart Minification** - Advanced content compression that preserves meaning while reducing tokens by 80-90%
160
- - **Partial File Access** - Fetches targeted line ranges from search results, avoiding full file downloads
161
- - **Context-Aware Processing** - Indentation-aware minification for 15+ programming languages
162
- - **Binary Detection & Filtering** - Automatically skips non-text files and suggests alternatives
163
- - **Token Efficiency** - Optimizes content for maximum LLM comprehension with minimal token usage
164
- - **Line Number Preservation** - Maintains precise line references for code navigation and debugging
165
-
166
- **Optimization Workflow:**
167
- 1. **🎯 Smart Targeting** → Extract specific line ranges from search results
168
- 2. **🧹 Content Filtering** → Remove comments, whitespace, and non-essential elements
169
- 3. **🗜️ Intelligent Compression** → Language-aware minification preserving code structure
170
- 4. **📍 Context Preservation** → Keep essential context and line number references
171
- 5. **⚡ Token Optimization** → Deliver maximum code insight with minimal LLM token consumption
112
+ - **Time Travel Code Viewing** - View files from specific commits and pull requests
113
+ - **PR Code Analysis** - Automatically fetch commit SHAs for precise code comparison
114
+ - **Historical Implementation** - Compare code evolution across versions
172
115
 
173
- ## Available Tools 🛠️
116
+ ### Performance Optimization
117
+ - **Smart Content Selection** - Extracts only relevant code sections
118
+ - **Advanced Minification** - Language-aware compression preserving meaning
119
+ - **Partial File Access** - Fetches targeted line ranges
120
+ - **Token Efficiency** - 80-90% reduction in LLM token usage
174
121
 
175
- Octocode provides **10 specialized tools** that work together intelligently:
122
+ ## Available Tools
176
123
 
177
- **🔍 Discovery Tools:**
178
- - **Repository Search** - Find repositories by topic, language, stars, and organization
179
- - **Package Search** - Discover NPM packages by functionality and keywords
124
+ **10 specialized tools** working together intelligently:
180
125
 
181
- **📊 Analysis Tools:**
182
- - **Code Search** - Smart search across GitHub repositories with heuristic pattern recognition
183
- - **Package Analysis** - Detailed NPM package analysis with repository linking
184
- - **Repository Structure** - Explore directory structures and file organization
126
+ **Discovery:** Repository Search, Package Search
127
+ **Analysis:** Code Search, Package Analysis, Repository Structure
128
+ **Activity:** Commit Search, Pull Request Search, Issue Search
129
+ **Content:** File Content Fetching, API Status Check
185
130
 
186
- **📈 Activity Tools:**
187
- - **Commit Search** - Find commits by message, author, and date with SHA integration
188
- - **Pull Request Search** - Discover PRs with automatic commit SHA extraction
189
- - **Issue Search** - Find bug reports, feature requests, and discussions
131
+ All tools feature automatic cross-referencing and intelligent fallbacks.
190
132
 
191
- **📁 Content Tools:**
192
- - **File Content Fetching** - Read files from any commit, branch, or PR using commit SHAs
193
- - **API Status Check** - Verify authentication and discover organization access
194
-
195
- **Smart Integration:** All tools work together through intelligent workflows - from package discovery → repository analysis → commit history → file content, with automatic fallbacks and cross-referencing.
196
-
197
- ## Privacy & Security 🛡️
133
+ ## Security & Privacy 🛡️
198
134
 
135
+ ### Local-First Architecture
199
136
  - **🏠 100% Local** - Runs entirely on your machine
200
- - **🚫 Zero Data Collection** - No telemetry, logging, or data transmission
201
- - **🔑 No Token Management** - Uses [GitHub CLI](https://cli.github.com/) authentication, no personal access tokens needed
202
- - **🛡️ Privacy by Design** - All API calls use your existing `gh` CLI permissions directly
203
-
204
- ### Command Execution Security 🔒
205
-
206
- **Robust protection against prompt injections and malicious command execution:**
207
-
208
- - **⚪ Allowlisted Commands Only** - Only pre-approved, safe NPM and GitHub CLI commands are executable
209
- - NPM: `view`, `search`, `config`, `whoami`
210
- - GitHub CLI: `search`, `api`, `auth`, `org`, `pr`
211
- - **🛡️ Argument Sanitization** - All command arguments are properly escaped to prevent shell injection attacks
212
- - **✅ Pre-execution Validation** - Every command is validated against allowed lists before execution
213
- - **🔧 Controlled Environment** - Commands run in a secure, cross-platform shell environment with controlled variables
214
- - **Cross-platform shells**: Uses `/bin/sh` on Unix/macOS, `cmd.exe` or `powershell.exe` on Windows - minimal, standard shells
215
- - **PowerShell support**: Modern Windows environments can optionally use PowerShell with enhanced security
216
- - **Why minimal shells are safe**: Avoids user's potentially customized shells with aliases, functions, plugins, or advanced features
217
- - **Controlled variables**: Only essential environment variables (`PATH`, `SHELL`) are passed, preventing environment-based attacks
218
- - **Platform-specific escaping**: Uses appropriate argument escaping for each platform (single quotes on Unix, double quotes for CMD, single quotes for PowerShell)
219
- - **🚫 No Arbitrary Execution** - System cannot execute arbitrary shell commands or scripts
220
- - **⏱️ Timeout Protection** - All commands have execution timeouts to prevent resource exhaustion
137
+ - **🚫 Zero Data Collection** - No telemetry or data transmission
138
+ - **🔑 No Token Management** - Uses GitHub CLI authentication
221
139
 
222
- ## Best Practices 💡
140
+ ### Command Execution Security
141
+ - **⚪ Allowlisted Commands Only** - Pre-approved safe commands
142
+ - **🛡️ Argument Sanitization** - Prevents shell injection attacks
143
+ - **✅ Pre-execution Validation** - Every command is validated
144
+ - **🔧 Controlled Environment** - Cross-platform secure shell execution
145
+ - **⏱️ Timeout Protection** - Prevents resource exhaustion
223
146
 
224
- **AI-Powered Search Tips:**
225
- - **Let AI guide you** - Start with natural language questions, the heuristic search will find relevant code
226
- - **Trust the smart fallbacks** - If initial search doesn't work, AI automatically tries alternative strategies
227
- - **Explore connections** - Ask about relationships between packages, libraries, and implementations
228
- - **Use any privilege level** - Works seamlessly across public repos, private repos, and organization repositories
229
- - **Keep research along the MCP** - Build upon previous searches and maintain context across multiple queries for deeper exploration
147
+ ## Best Practices 💡
230
148
 
231
149
  **Effective Questions:**
232
- - **Vague is OK** - "How does authentication work?" → AI finds relevant patterns across repositories
233
- - **Ask for connections** - "What libraries use this pattern?" → Discovers related implementations
234
- - **Cross-ecosystem queries** - "NPM packages that implement X" → Links packages to their repositories
235
- - **Evolution questions** - "How has this approach changed?" → Traces implementation history
150
+ - Start with natural language - "How does authentication work?"
151
+ - Ask for connections - "What libraries use this pattern?"
152
+ - Cross-ecosystem queries - "NPM packages that implement X"
153
+ - Evolution questions - "How has this approach changed?"
236
154
 
237
- **Advanced Search Features:**
238
- - **Automatic fallbacks** - No need to retry failed searches, AI handles it automatically
239
- - **Smart discovery** - Finds repositories and packages you didn't know existed
240
- - **Connection mapping** - Understands relationships between different codebases
241
- - **Context preservation** - Maintains search context across multiple queries
155
+ **Pro Tips:**
156
+ - Let AI guide discovery - vague queries work great
157
+ - Trust smart fallbacks - automatic retry with alternatives
158
+ - Build on previous searches - maintain context for deeper exploration
159
+ - Works everywhere - public, private, and organization repositories
242
160
 
243
161
  ## Troubleshooting 🔧
244
162
 
245
- **Authentication Issues:**
246
163
  ```bash
247
164
  # Check GitHub CLI status
248
165
  gh auth status
@@ -252,43 +169,24 @@ gh auth logout && gh auth login
252
169
 
253
170
  # Check NPM access
254
171
  npm whoami
172
+
173
+ # Clear NPX cache if needed
174
+ rm -rf ~/.npm/_npx
255
175
  ```
256
176
 
257
177
  **Common Solutions:**
258
178
  - No results? Try broader search terms
259
- - Private repos not found? Check organization membership with `gh auth status`
260
- - NPX issues? Clear cache: `rm -rf ~/.npm/_npx`
261
-
262
- **🏢 Organization & Private Repository Access:**
263
- - **Automatic detection** - Octocode automatically discovers your GitHub organizations
264
- - **No additional setup** - If you have access to private repos through your organization, they work immediately
265
- - **Verify access** - Run `gh auth status` to see your organization memberships
266
-
267
- **💻 Windows PowerShell Support:**
268
- - **Modern shell support** - Optionally use PowerShell instead of cmd.exe on Windows
269
- - **Enhanced security** - PowerShell provides better argument escaping and modern features
270
- - **Automatic detection** - The system automatically detects Windows and applies appropriate shell configurations
271
- - **Zero configuration** - Works seamlessly with existing setups, no additional configuration needed
272
-
273
- **Why GitHub CLI Authentication?**
274
- - ✅ **No token creation** - GitHub CLI handles OAuth flow automatically
275
- - ✅ **Enterprise compatible** - Works with SSO, SAML, and 2FA out of the box
276
- - ✅ **Organization auto-detection** - Automatically discovers your GitHub organizations and private repo access
277
- - ✅ **Works out of the box** - If you work for an organization, private repositories are immediately accessible
278
- - ❌ **vs Personal Access Tokens** - No manual creation, rotation, or security risks
179
+ - Private repos not found? Check `gh auth status` for organization membership
180
+ - Windows users? PowerShell is automatically supported
279
181
 
280
182
  ## Background 💭
281
183
 
282
- This project started as a personal tool while working at Wix, born from the challenge of navigating large codebases and keeping up with rapidly evolving technology landscapes. What began as a side project to solve daily development challenges evolved into **the perfect code assistant that can help understand anything**.
283
-
284
- The goal was simple: **make code exploration as intelligent as having a senior developer guide you through any codebase.** Built specifically to understand connections between many repositories and NPM packages under any privilege the user has, with AI-powered heuristic search, smart fallbacks, and intelligent discovery.
184
+ This project started as a personal tool while working at Wix, born from the challenge of navigating large codebases and keeping up with rapidly evolving technology landscapes. What began as a side project evolved into **the perfect code assistant that can help understand anything**.
285
185
 
186
+ The goal: **make code exploration as intelligent as having a senior developer guide you through any codebase.**
286
187
 
287
188
  ## License 📄
288
189
 
289
190
  MIT License - See [LICENSE](./LICENSE.md) for details.
290
191
 
291
- ---
292
-
293
-
294
-
192
+ ---
package/build/index.js CHANGED
@@ -112050,15 +112050,44 @@ async function fetchGitHubFileContent(params) {
112050
112050
  });
112051
112051
  }
112052
112052
  }
112053
- // Try fallback branches if original branch fails
112054
- if (errorMsg.includes('404') &&
112055
- branch !== 'main' &&
112056
- branch !== 'master') {
112057
- const fallbackBranches = ['main', 'master'];
112053
+ // Enhanced fallback strategy for 404 errors
112054
+ if (errorMsg.includes('404')) {
112055
+ // Get the actual default branch from the repo info we already fetched
112056
+ let defaultBranch = 'main';
112057
+ let repoDefaultBranchFound = false;
112058
+ if (!repoCheckResult.isError) {
112059
+ try {
112060
+ const repoData = JSON.parse(repoCheckResult.content[0].text);
112061
+ defaultBranch = repoData.default_branch || 'main';
112062
+ repoDefaultBranchFound = true;
112063
+ }
112064
+ catch (e) {
112065
+ // Keep default as 'main' if parsing fails
112066
+ }
112067
+ }
112068
+ // If we found the actual default branch, try it first
112069
+ if (repoDefaultBranchFound && defaultBranch !== branch) {
112070
+ const defaultBranchPath = `/repos/${owner}/${repo}/contents/${filePath}?ref=${defaultBranch}`;
112071
+ const defaultBranchResult = await executeGitHubCommand('api', [defaultBranchPath], {
112072
+ cache: false,
112073
+ });
112074
+ if (!defaultBranchResult.isError) {
112075
+ return await processFileContent(defaultBranchResult, owner, repo, defaultBranch, filePath, params.minified, params.startLine, params.endLine, params.contextLines);
112076
+ }
112077
+ }
112078
+ // Comprehensive fallback list (excluding default branch since we tried it)
112079
+ const fallbackBranches = [
112080
+ 'main',
112081
+ 'master',
112082
+ 'develop',
112083
+ 'dev',
112084
+ 'trunk',
112085
+ ].filter(b => b !== defaultBranch && b !== branch);
112058
112086
  const triedBranches = [branch];
112087
+ if (repoDefaultBranchFound && defaultBranch !== branch) {
112088
+ triedBranches.push(`${defaultBranch} (default)`);
112089
+ }
112059
112090
  for (const fallbackBranch of fallbackBranches) {
112060
- if (triedBranches.includes(fallbackBranch))
112061
- continue;
112062
112091
  triedBranches.push(fallbackBranch);
112063
112092
  const fallbackPath = `/repos/${owner}/${repo}/contents/${filePath}?ref=${fallbackBranch}`;
112064
112093
  const fallbackResult = await executeGitHubCommand('api', [fallbackPath], {
@@ -112068,8 +112097,19 @@ async function fetchGitHubFileContent(params) {
112068
112097
  return await processFileContent(fallbackResult, owner, repo, fallbackBranch, filePath, params.minified, params.startLine, params.endLine, params.contextLines);
112069
112098
  }
112070
112099
  }
112100
+ const defaultBranchInfo = repoDefaultBranchFound
112101
+ ? `\nRepository default branch: "${defaultBranch}"`
112102
+ : `\nCould not determine default branch - repository info unavailable`;
112071
112103
  return createResult({
112072
- error: `File not found in any common branches (tried: ${triedBranches.join(', ')}). File might have been moved or deleted. Use github_search_code to find current location.`,
112104
+ error: `File not found in any common branches (tried: ${triedBranches.join(', ')}).${defaultBranchInfo}
112105
+
112106
+ Quick solution: Use the correct branch name:
112107
+ {"owner": "${owner}", "repo": "${repo}", "branch": "${defaultBranch}", "filePath": "${filePath}"}
112108
+
112109
+ Alternative solutions:
112110
+ • Check repository structure: github_view_repo_structure with {"owner": "${owner}", "repo": "${repo}", "branch": "main", "path": ""}
112111
+ • Search for file: github_search_code with query="filename:${filePath.split('/').pop()}" owner="${owner}"
112112
+ • Find file path: github_search_code with query="path:${filePath}"`,
112073
112113
  });
112074
112114
  }
112075
112115
  // Handle common errors with more context
@@ -113754,125 +113794,78 @@ async function viewRepositoryStructure(params) {
113754
113794
  try {
113755
113795
  // Clean up path
113756
113796
  const cleanPath = path.startsWith('/') ? path.substring(1) : path;
113757
- // Try the requested branch first, then fallback to main/master
113758
- const branchesToTry = await getSmartBranchFallback(owner, repo, branch);
113759
- let items = [];
113760
- let usedBranch = branch;
113761
- let lastError = null;
113762
- let attemptCount = 0;
113763
- const maxAttempts = branchesToTry.length;
113764
- const triedBranches = [];
113765
- for (const tryBranch of branchesToTry) {
113766
- if (attemptCount >= maxAttempts)
113767
- break;
113768
- attemptCount++;
113769
- triedBranches.push(tryBranch);
113797
+ // Try the requested branch first
113798
+ const apiPath = `/repos/${owner}/${repo}/contents/${cleanPath}?ref=${branch}`;
113799
+ const result = await executeGitHubCommand('api', [apiPath], {
113800
+ cache: false,
113801
+ });
113802
+ if (!result.isError) {
113803
+ const execResult = JSON.parse(result.content[0].text);
113804
+ const apiItems = execResult.result;
113805
+ const items = Array.isArray(apiItems) ? apiItems : [apiItems];
113806
+ return formatRepositoryStructure(owner, repo, branch, cleanPath, items);
113807
+ }
113808
+ // If initial request failed, start enhanced fallback mechanism
113809
+ const errorMsg = result.content[0].text;
113810
+ // Check repository existence first
113811
+ const repoCheckResult = await executeGitHubCommand('api', [`/repos/${owner}/${repo}`], {
113812
+ cache: false,
113813
+ });
113814
+ if (repoCheckResult.isError) {
113815
+ return handleRepositoryNotFound(owner, repo, repoCheckResult.content[0].text);
113816
+ }
113817
+ // Enhanced fallback strategy for branch/path errors
113818
+ if (errorMsg.includes('404')) {
113819
+ // Get the actual default branch from the repo info we already fetched
113820
+ let defaultBranch = 'main';
113821
+ let repoDefaultBranchFound = false;
113770
113822
  try {
113771
- const apiPath = `/repos/${owner}/${repo}/contents/${cleanPath}?ref=${tryBranch}`;
113772
- const result = await executeGitHubCommand('api', [apiPath], {
113823
+ const repoData = JSON.parse(repoCheckResult.content[0].text);
113824
+ defaultBranch = repoData.default_branch || 'main';
113825
+ repoDefaultBranchFound = true;
113826
+ }
113827
+ catch (e) {
113828
+ // Keep default as 'main' if parsing fails
113829
+ }
113830
+ // If we found the actual default branch, try it first
113831
+ if (repoDefaultBranchFound && defaultBranch !== branch) {
113832
+ const defaultBranchPath = `/repos/${owner}/${repo}/contents/${cleanPath}?ref=${defaultBranch}`;
113833
+ const defaultBranchResult = await executeGitHubCommand('api', [defaultBranchPath], {
113773
113834
  cache: false,
113774
113835
  });
113775
- if (!result.isError) {
113776
- const execResult = JSON.parse(result.content[0].text);
113836
+ if (!defaultBranchResult.isError) {
113837
+ const execResult = JSON.parse(defaultBranchResult.content[0].text);
113777
113838
  const apiItems = execResult.result;
113778
- items = Array.isArray(apiItems) ? apiItems : [apiItems];
113779
- usedBranch = tryBranch;
113780
- break;
113781
- }
113782
- else {
113783
- lastError = new Error(result.content[0].text);
113784
- }
113785
- }
113786
- catch (error) {
113787
- lastError = error instanceof Error ? error : new Error(String(error));
113788
- continue;
113789
- }
113790
- }
113791
- if (items.length === 0) {
113792
- // Check repository existence only after content fetch fails
113793
- const repoCheckResult = await executeGitHubCommand('api', [`/repos/${owner}/${repo}`], {
113794
- cache: false,
113795
- });
113796
- if (repoCheckResult.isError) {
113797
- const repoErrorMsg = repoCheckResult.content[0].text;
113798
- if (repoErrorMsg.includes('404')) {
113799
- return createResult({
113800
- error: `Repository "${owner}/${repo}" not found. It might have been deleted, renamed, or made private. Use github_search_code to find current location.`,
113801
- });
113802
- }
113803
- else if (repoErrorMsg.includes('403')) {
113804
- return createResult({
113805
- error: `Repository "${owner}/${repo}" exists but access is denied. Repository might be private or archived. Use api_status_check to verify permissions.`,
113806
- });
113839
+ const items = Array.isArray(apiItems) ? apiItems : [apiItems];
113840
+ return formatRepositoryStructure(owner, repo, defaultBranch, cleanPath, items);
113807
113841
  }
113808
113842
  }
113809
- const errorMsg = lastError?.message || 'Unknown error';
113810
- if (errorMsg.includes('404') || errorMsg.includes('Not Found')) {
113811
- if (path) {
113812
- const searchSuggestion = await suggestPathSearchFallback(owner, path);
113813
- return createResult({
113814
- error: `Path "${path}" not found in any branch (tried: ${triedBranches.join(', ')}).${searchSuggestion}`,
113815
- });
113816
- }
113817
- else {
113818
- return createResult({
113819
- error: `Repository "${owner}/${repo}" structure not accessible. Repository might be empty, private, or you might not have sufficient permissions. Use github_search_code with owner="${owner}" to find accessible repositories.`,
113820
- });
113821
- }
113843
+ // Try additional common branches
113844
+ const commonBranches = ['main', 'master', 'develop'];
113845
+ const triedBranches = [branch];
113846
+ if (repoDefaultBranchFound) {
113847
+ triedBranches.push(defaultBranch);
113822
113848
  }
113823
- else if (errorMsg.includes('403') || errorMsg.includes('Forbidden')) {
113824
- return createResult({
113825
- error: `Access denied to "${owner}/${repo}". Repository exists but might be private/archived. Use api_status_check to verify permissions, or github_search_code with owner="${owner}" to find accessible repositories.`,
113826
- });
113827
- }
113828
- else {
113829
- const searchSuggestion = path
113830
- ? await suggestPathSearchFallback(owner, path)
113831
- : '';
113832
- return createResult({
113833
- error: `Failed to access "${owner}/${repo}": ${errorMsg}. Check network connection and repository permissions.${searchSuggestion}`,
113849
+ for (const tryBranch of commonBranches) {
113850
+ if (triedBranches.includes(tryBranch))
113851
+ continue;
113852
+ const tryBranchPath = `/repos/${owner}/${repo}/contents/${cleanPath}?ref=${tryBranch}`;
113853
+ const tryBranchResult = await executeGitHubCommand('api', [tryBranchPath], {
113854
+ cache: false,
113834
113855
  });
113856
+ triedBranches.push(tryBranch);
113857
+ if (!tryBranchResult.isError) {
113858
+ const execResult = JSON.parse(tryBranchResult.content[0].text);
113859
+ const apiItems = execResult.result;
113860
+ const items = Array.isArray(apiItems) ? apiItems : [apiItems];
113861
+ return formatRepositoryStructure(owner, repo, tryBranch, cleanPath, items);
113862
+ }
113835
113863
  }
113864
+ // All branches failed - return helpful error
113865
+ return handlePathNotFound(owner, repo, cleanPath, triedBranches, defaultBranch, repoDefaultBranchFound);
113836
113866
  }
113837
- // Limit total items to 100 for efficiency
113838
- const limitedItems = items.slice(0, 100);
113839
- // Sort: directories first, then alphabetically
113840
- limitedItems.sort((a, b) => {
113841
- if (a.type !== b.type) {
113842
- return a.type === 'dir' ? -1 : 1;
113843
- }
113844
- return a.name.localeCompare(b.name);
113845
- });
113846
- // Create simplified, token-efficient structure
113847
- const files = limitedItems
113848
- .filter(item => item.type === 'file')
113849
- .map(item => ({
113850
- name: item.name,
113851
- size: item.size,
113852
- url: item.path, // Use path for fetching
113853
- }));
113854
- const folders = limitedItems
113855
- .filter(item => item.type === 'dir')
113856
- .map(item => ({
113857
- name: item.name,
113858
- url: item.path, // Use path for browsing
113859
- }));
113860
- return createResult({
113861
- data: {
113862
- repository: `${owner}/${repo}`,
113863
- branch: usedBranch,
113864
- path: cleanPath || '/',
113865
- githubBasePath: `https://api.github.com/repos/${owner}/${repo}/contents/`,
113866
- files: {
113867
- count: files.length,
113868
- files: files,
113869
- },
113870
- folders: {
113871
- count: folders.length,
113872
- folders: folders,
113873
- },
113874
- },
113875
- });
113867
+ // Handle other errors (403, etc.)
113868
+ return handleOtherErrors(owner, repo, errorMsg);
113876
113869
  }
113877
113870
  catch (error) {
113878
113871
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -113883,62 +113876,114 @@ async function viewRepositoryStructure(params) {
113883
113876
  });
113884
113877
  }
113885
113878
  /**
113886
- * Smart branch detection with automatic fallback to common branch names.
113887
- * Now includes more comprehensive branch detection and better error handling.
113879
+ * Format the repository structure response
113888
113880
  */
113889
- async function getSmartBranchFallback(owner, repo, requestedBranch) {
113890
- const branches = new Set([requestedBranch]);
113891
- try {
113892
- // Try to get repository info to find default branch
113893
- const repoInfoResult = await executeGitHubCommand('api', [`/repos/${owner}/${repo}`], {
113894
- cache: false,
113881
+ function formatRepositoryStructure(owner, repo, branch, path, items) {
113882
+ // Limit total items to 100 for efficiency
113883
+ const limitedItems = items.slice(0, 100);
113884
+ // Sort: directories first, then alphabetically
113885
+ limitedItems.sort((a, b) => {
113886
+ if (a.type !== b.type) {
113887
+ return a.type === 'dir' ? -1 : 1;
113888
+ }
113889
+ return a.name.localeCompare(b.name);
113890
+ });
113891
+ // Create simplified, token-efficient structure
113892
+ const files = limitedItems
113893
+ .filter(item => item.type === 'file')
113894
+ .map(item => ({
113895
+ name: item.name,
113896
+ size: item.size,
113897
+ url: item.path, // Use path for fetching
113898
+ }));
113899
+ const folders = limitedItems
113900
+ .filter(item => item.type === 'dir')
113901
+ .map(item => ({
113902
+ name: item.name,
113903
+ url: item.path, // Use path for browsing
113904
+ }));
113905
+ return createResult({
113906
+ data: {
113907
+ repository: `${owner}/${repo}`,
113908
+ branch: branch,
113909
+ path: path || '/',
113910
+ githubBasePath: `https://api.github.com/repos/${owner}/${repo}/contents/`,
113911
+ files: {
113912
+ count: files.length,
113913
+ files: files,
113914
+ },
113915
+ folders: {
113916
+ count: folders.length,
113917
+ folders: folders,
113918
+ },
113919
+ },
113920
+ });
113921
+ }
113922
+ /**
113923
+ * Handle repository not found errors
113924
+ */
113925
+ function handleRepositoryNotFound(owner, repo, errorMsg) {
113926
+ if (errorMsg.includes('404')) {
113927
+ return createResult({
113928
+ error: `Repository "${owner}/${repo}" not found. It might have been deleted, renamed, or made private. Use github_search_code to find current location.`,
113895
113929
  });
113896
- if (!repoInfoResult.isError) {
113897
- const execResult = JSON.parse(repoInfoResult.content[0].text);
113898
- const repoData = execResult.result;
113899
- const defaultBranch = repoData.default_branch;
113900
- if (defaultBranch) {
113901
- branches.add(defaultBranch);
113902
- }
113903
- }
113904
113930
  }
113905
- catch {
113906
- // If we can't get repo info, proceed with standard fallbacks
113907
- }
113908
- // Add only main/master as fallback branches
113909
- const commonBranches = ['main', 'master'];
113910
- commonBranches.forEach(branch => branches.add(branch));
113911
- // Convert Set back to array, with requested branch first
113912
- const branchesArray = Array.from(branches);
113913
- branchesArray.sort((a, b) => {
113914
- if (a === requestedBranch)
113915
- return -1;
113916
- if (b === requestedBranch)
113917
- return 1;
113918
- return 0;
113931
+ else if (errorMsg.includes('403')) {
113932
+ return createResult({
113933
+ error: `Repository "${owner}/${repo}" exists but access is denied. Repository might be private or archived. Use api_status_check to verify permissions.`,
113934
+ });
113935
+ }
113936
+ return createResult({
113937
+ error: `Failed to access repository "${owner}/${repo}": ${errorMsg}. Verify repository exists and is accessible.`,
113919
113938
  });
113920
- return branchesArray;
113921
113939
  }
113922
- // Helper function to suggest path search strategy
113923
- async function suggestPathSearchFallback(owner, path) {
113924
- try {
113925
- // Extract last path segment and try to find in same organization
113926
- const pathSegment = path.split('/').pop() || path;
113927
- const searchResult = await executeGitHubCommand('api', [
113928
- `/search/code?q=${encodeURIComponent(pathSegment)}+in:path+org:${owner}`,
113929
- ], { cache: false });
113930
- if (!searchResult.isError) {
113931
- const results = JSON.parse(searchResult.content[0].text);
113932
- if (results.total_count > 0) {
113933
- const firstMatch = results.items[0];
113934
- return ` Directory might be in ${firstMatch.repository.full_name}. Try these searches:\n1. github_search_code with query="${pathSegment}" owner="${owner}"\n2. github_search_code with query="path:${path}" owner="${owner}"`;
113935
- }
113936
- }
113940
+ /**
113941
+ * Handle path not found errors with helpful suggestions
113942
+ */
113943
+ function handlePathNotFound(owner, repo, path, triedBranches, defaultBranch, repoDefaultBranchFound) {
113944
+ const defaultBranchInfo = repoDefaultBranchFound
113945
+ ? `\nRepository default branch: "${defaultBranch}"`
113946
+ : `\nCould not determine default branch - repository info unavailable`;
113947
+ if (path) {
113948
+ return createResult({
113949
+ error: `Path "${path}" not found in any branch (tried: ${triedBranches.join(', ')}).${defaultBranchInfo}
113950
+
113951
+ Quick solution: Use the correct branch name:
113952
+ {"owner": "${owner}", "repo": "${repo}", "branch": "${defaultBranch}", "path": "${path}"}
113953
+
113954
+ Alternative solutions:
113955
+ • Search for path: github_search_code with query="path:${path}" owner="${owner}"
113956
+ • Search for directory: github_search_code with query="${path.split('/').pop()}" owner="${owner}"
113957
+ • Check root structure: github_view_repo_structure with {"owner": "${owner}", "repo": "${repo}", "branch": "${defaultBranch}", "path": ""}`,
113958
+ });
113937
113959
  }
113938
- catch {
113939
- // Fallback to generic message if search fails
113960
+ else {
113961
+ return createResult({
113962
+ error: `Repository "${owner}/${repo}" structure not accessible in any branch (tried: ${triedBranches.join(', ')}).${defaultBranchInfo}
113963
+
113964
+ Repository might be empty, private, or you might not have sufficient permissions.
113965
+
113966
+ Alternative solutions:
113967
+ • Verify permissions: api_status_check
113968
+ • Search accessible repos: github_search_code with owner="${owner}"
113969
+ • Try different branch: github_view_repo_structure with {"owner": "${owner}", "repo": "${repo}", "branch": "${defaultBranch}", "path": ""}`,
113970
+ });
113971
+ }
113972
+ }
113973
+ /**
113974
+ * Handle other types of errors (403, rate limits, etc.)
113975
+ */
113976
+ function handleOtherErrors(owner, repo, errorMsg) {
113977
+ if (errorMsg.includes('403') || errorMsg.includes('Forbidden')) {
113978
+ return createResult({
113979
+ error: `Access denied to "${owner}/${repo}". Repository exists but might be private/archived. Use api_status_check to verify permissions, or github_search_code with owner="${owner}" to find accessible repositories.`,
113980
+ });
113981
+ }
113982
+ else {
113983
+ return createResult({
113984
+ error: `Failed to access "${owner}/${repo}": ${errorMsg}. Check network connection and repository permissions.`,
113985
+ });
113940
113986
  }
113941
- return ` Try these searches:\n1. github_search_code with query="${path.split('/').pop()}" owner="${owner}"\n2. github_search_code with query="path:${path}"`;
113942
113987
  }
113943
113988
 
113944
113989
  const GITHUB_SEARCH_ISSUES_TOOL_NAME = 'githubSearchIssues';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "octocode-mcp",
3
- "version": "2.3.10",
3
+ "version": "2.3.11",
4
4
  "description": "Model Context Protocol (MCP) server for advanced GitHub repository analysis, code discovery, and npm package exploration. Provides AI assistants with powerful tools to search, analyze, and understand codebases across GitHub and npm ecosystems.",
5
5
  "author": "Guy Bary <guybary@gmail.com>",
6
6
  "homepage": "https://octocode.ai",