octocode-mcp
Version:
Model Context Protocol (MCP) server for advanced GitHub repository analysis and code discovery. Provides AI assistants with powerful tools to search, analyze, and understand codebases across GitHub.
586 lines (583 loc) • 15.5 kB
TypeScript
import { McpServer, RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
//#region src/types/metadata.d.ts
/**
* Hint status types for determining which hints to return
* - 'hasResults': Tool returned results successfully
* - 'empty': Tool returned no results (but no error)
* - 'error': Tool encountered an error
*/
type HintStatus = 'hasResults' | 'empty' | 'error';
/**
* Context that tools can provide to generate smarter, context-aware hints.
* Used by dynamic hint generators to provide intelligent guidance.
*/
interface HintContext {
/** File size in KB */
fileSize?: number;
/** Result size in characters */
resultSize?: number;
/** Estimated token count */
tokenEstimate?: number;
/** Number of entries/files in result */
entryCount?: number;
/** Number of matches found */
matchCount?: number;
/** Number of files containing matches */
fileCount?: number;
/** Whether result/file is considered large */
isLarge?: boolean;
/** Type of error encountered */
errorType?: 'size_limit' | 'not_found' | 'permission' | 'pattern_too_broad' | 'symbol_not_found' | 'file_not_found' | 'timeout' | 'not_a_function';
/** Original error message */
originalError?: string;
/** Whether matchString/pattern was used */
hasPattern?: boolean;
/** Whether pagination (charLength) was used */
hasPagination?: boolean;
/** Path being searched/accessed */
path?: string;
/** Whether owner/repo context was provided (GitHub tools) */
hasOwnerRepo?: boolean;
/** GitHub code search match mode */
match?: 'file' | 'path';
/** Which search engine was used (local tools) */
searchEngine?: 'rg' | 'grep';
/** Number of definition/reference locations found */
locationCount?: number;
/** Whether definition is from an external package */
hasExternalPackage?: boolean;
/** Whether using text-based fallback instead of LSP */
isFallback?: boolean;
/** Search radius in lines from lineHint */
searchRadius?: number;
/** Line hint provided for symbol lookup */
lineHint?: number;
/** Symbol name being looked up */
symbolName?: string;
/** File URI/path for LSP operations */
uri?: string;
/** Whether references span multiple files */
hasMultipleFiles?: boolean;
/** Whether there are more pages of results */
hasMorePages?: boolean;
/** Current page number (1-indexed) */
currentPage?: number;
/** Total number of pages */
totalPages?: number;
/** Call hierarchy direction */
direction?: 'incoming' | 'outgoing';
/** Number of callers/callees found */
callCount?: number;
/** Call hierarchy depth */
depth?: number;
/** Whether there is more content available (pagination) */
hasMoreContent?: boolean;
}
/**
* Hint generator function signature for dynamic hints.
* Returns an array that may contain undefined values (filtered out later).
*/
type HintGenerator = (context: HintContext) => (string | undefined)[];
/**
* Structure for tool-specific hint generators by status.
*/
interface ToolHintGenerators {
hasResults: HintGenerator;
empty: HintGenerator;
error: HintGenerator;
}
interface ToolMetadata {
name: string;
description: string;
schema: Record<string, string>;
hints: {
hasResults: readonly string[];
empty: readonly string[];
dynamic?: Record<string, string[] | undefined>;
};
}
interface PromptArgument {
name: string;
description: string;
required?: boolean;
}
interface PromptMetadata {
name: string;
description: string;
content: string;
args?: PromptArgument[];
}
interface ToolNames {
GITHUB_FETCH_CONTENT: 'githubGetFileContent';
GITHUB_SEARCH_CODE: 'githubSearchCode';
GITHUB_SEARCH_PULL_REQUESTS: 'githubSearchPullRequests';
GITHUB_SEARCH_REPOSITORIES: 'githubSearchRepositories';
GITHUB_VIEW_REPO_STRUCTURE: 'githubViewRepoStructure';
PACKAGE_SEARCH: 'packageSearch';
LOCAL_RIPGREP: 'localSearchCode';
LOCAL_FETCH_CONTENT: 'localGetFileContent';
LOCAL_FIND_FILES: 'localFindFiles';
LOCAL_VIEW_STRUCTURE: 'localViewStructure';
LSP_GOTO_DEFINITION: 'lspGotoDefinition';
LSP_FIND_REFERENCES: 'lspFindReferences';
LSP_CALL_HIERARCHY: 'lspCallHierarchy';
}
interface BaseSchema {
mainResearchGoal: string;
researchGoal: string;
reasoning: string;
bulkQueryTemplate: string;
}
interface CompleteMetadata {
instructions: string;
prompts: Record<string, PromptMetadata>;
toolNames: ToolNames;
baseSchema: {
mainResearchGoal: string;
researchGoal: string;
reasoning: string;
bulkQuery: (toolName: string) => string;
};
tools: Record<string, ToolMetadata>;
baseHints: {
hasResults: readonly string[];
empty: readonly string[];
};
genericErrorHints: readonly string[];
bulkOperations?: {
instructions?: {
base?: string;
hasResults?: string;
empty?: string;
error?: string;
};
};
}
interface RawCompleteMetadata {
instructions: string;
prompts: Record<string, PromptMetadata>;
toolNames: ToolNames;
baseSchema: BaseSchema;
tools: Record<string, ToolMetadata>;
baseHints: {
hasResults: readonly string[];
empty: readonly string[];
};
genericErrorHints: readonly string[];
bulkOperations?: {
instructions?: {
base?: string;
hasResults?: string;
empty?: string;
error?: string;
};
};
}
//#endregion
//#region src/tools/toolNames.d.ts
/**
* Static tool name constants - use for computed property keys
* The Proxy TOOL_NAMES should only be used for runtime access, not object literals
*/
declare const STATIC_TOOL_NAMES: {
readonly GITHUB_FETCH_CONTENT: "githubGetFileContent";
readonly GITHUB_SEARCH_CODE: "githubSearchCode";
readonly GITHUB_SEARCH_PULL_REQUESTS: "githubSearchPullRequests";
readonly GITHUB_SEARCH_REPOSITORIES: "githubSearchRepositories";
readonly GITHUB_VIEW_REPO_STRUCTURE: "githubViewRepoStructure";
readonly PACKAGE_SEARCH: "packageSearch";
readonly LOCAL_RIPGREP: "localSearchCode";
readonly LOCAL_FETCH_CONTENT: "localGetFileContent";
readonly LOCAL_FIND_FILES: "localFindFiles";
readonly LOCAL_VIEW_STRUCTURE: "localViewStructure";
readonly LSP_GOTO_DEFINITION: "lspGotoDefinition";
readonly LSP_FIND_REFERENCES: "lspFindReferences";
readonly LSP_CALL_HIERARCHY: "lspCallHierarchy";
};
//#endregion
//#region src/tools/toolMetadata.d.ts
type ToolNamesValue = ToolNames[keyof ToolNames];
type ToolName = ToolNamesValue;
declare function initializeToolMetadata(): Promise<void>;
declare function loadToolContent(): Promise<CompleteMetadata>;
declare const TOOL_NAMES: CompleteMetadata["toolNames"];
declare const BASE_SCHEMA: CompleteMetadata["baseSchema"];
declare const GENERIC_ERROR_HINTS: readonly string[];
declare function isToolInMetadata(toolName: string): boolean;
declare function getToolHintsSync(toolName: string, resultType: 'hasResults' | 'empty'): readonly string[];
declare function getGenericErrorHintsSync(): readonly string[];
declare function getDynamicHints(toolName: string, hintType: string): readonly string[];
declare const DESCRIPTIONS: Record<string, string>;
declare const TOOL_HINTS: Record<string, {
hasResults: readonly string[];
empty: readonly string[];
}> & {
base: {
hasResults: readonly string[];
empty: readonly string[];
};
};
declare const GITHUB_FETCH_CONTENT: {
scope: {
owner: string;
repo: string;
branch: string;
path: string;
};
processing: {
sanitize: string;
};
range: {
startLine: string;
endLine: string;
fullContent: string;
matchString: string;
matchStringContextLines: string;
};
pagination: {
charOffset: string;
charLength: string;
};
validation: {
parameterConflict: string;
};
};
declare const GITHUB_SEARCH_CODE: {
search: {
keywordsToSearch: string;
};
scope: {
owner: string;
repo: string;
};
filters: {
extension: string;
filename: string;
path: string;
match: string;
};
resultLimit: {
limit: string;
};
pagination: {
page: string;
};
processing: {
sanitize: string;
};
};
declare const GITHUB_SEARCH_REPOS: {
search: {
keywordsToSearch: string;
topicsToSearch: string;
};
scope: {
owner: string;
repo: string;
};
filters: {
stars: string;
size: string;
created: string;
updated: string;
match: string;
};
sorting: {
sort: string;
};
resultLimit: {
limit: string;
};
pagination: {
page: string;
};
};
declare const GITHUB_SEARCH_PULL_REQUESTS: {
search: {
query: string;
};
scope: {
prNumber: string;
owner: string;
repo: string;
};
filters: {
match: string;
created: string;
updated: string;
state: string;
assignee: string;
author: string;
commenter: string;
involves: string;
mentions: string;
"review-requested": string;
"reviewed-by": string;
label: string;
"no-label": string;
"no-milestone": string;
"no-project": string;
"no-assignee": string;
head: string;
base: string;
closed: string;
"merged-at": string;
comments: string;
reactions: string;
interactions: string;
merged: string;
draft: string;
};
sorting: {
sort: string;
order: string;
};
resultLimit: {
limit: string;
};
pagination: {
page: string;
};
outputShaping: {
withComments: string;
withCommits: string;
type: string;
partialContentMetadata: string;
};
};
declare const GITHUB_VIEW_REPO_STRUCTURE: {
scope: {
owner: string;
repo: string;
branch: string;
path: string;
};
range: {
depth: string;
};
pagination: {
entriesPerPage: string;
entryPageNumber: string;
};
};
declare const PACKAGE_SEARCH: {
search: {
ecosystem: string;
name: string;
};
options: {
searchLimit: string;
npmFetchMetadata: string;
pythonFetchMetadata: string;
};
};
declare const LOCAL_RIPGREP: {
search: {
pattern: string;
path: string;
mode: string;
};
filters: {
type: string;
include: string;
exclude: string;
excludeDir: string;
binaryFiles: string;
noIgnore: string;
hidden: string;
followSymlinks: string;
};
options: {
smartCase: string;
caseInsensitive: string;
caseSensitive: string;
fixedString: string;
perlRegex: string;
wholeWord: string;
invertMatch: string;
multiline: string;
multilineDotall: string;
};
output: {
filesOnly: string;
filesWithoutMatch: string;
count: string;
countMatches: string;
jsonOutput: string;
vimgrepFormat: string;
includeStats: string;
includeDistribution: string;
};
context: {
contextLines: string;
beforeContext: string;
afterContext: string;
matchContentLength: string;
lineNumbers: string;
column: string;
};
pagination: {
filesPerPage: string;
filePageNumber: string;
matchesPerPage: string;
maxFiles: string;
maxMatchesPerFile: string;
};
advanced: {
threads: string;
mmap: string;
noUnicode: string;
encoding: string;
sort: string;
sortReverse: string;
noMessages: string;
lineRegexp: string;
passthru: string;
debug: string;
showFileLastModified: string;
};
};
declare const LOCAL_FETCH_CONTENT: {
scope: {
path: string;
};
range: {
startLine: string;
endLine: string;
};
options: {
fullContent: string;
matchString: string;
matchStringContextLines: string;
matchStringIsRegex: string;
matchStringCaseSensitive: string;
minified: string;
};
pagination: {
charOffset: string;
charLength: string;
};
};
declare const LOCAL_FIND_FILES: {
scope: {
path: string;
};
filters: {
name: string;
iname: string;
names: string;
pathPattern: string;
regex: string;
regexType: string;
type: string;
empty: string;
executable: string;
readable: string;
writable: string;
excludeDir: string;
};
time: {
modifiedWithin: string;
modifiedBefore: string;
accessedWithin: string;
};
size: {
sizeGreater: string;
sizeLess: string;
};
pagination: {
limit: string;
filesPerPage: string;
filePageNumber: string;
charOffset: string;
charLength: string;
};
options: {
maxDepth: string;
minDepth: string;
details: string;
permissions: string;
showFileLastModified: string;
};
};
declare const LOCAL_VIEW_STRUCTURE: {
scope: {
path: string;
};
filters: {
pattern: string;
directoriesOnly: string;
filesOnly: string;
extension: string;
extensions: string;
hidden: string;
};
options: {
depth: string;
recursive: string;
details: string;
humanReadable: string;
summary: string;
showFileLastModified: string;
};
sorting: {
sortBy: string;
reverse: string;
};
pagination: {
limit: string;
entriesPerPage: string;
entryPageNumber: string;
charOffset: string;
charLength: string;
};
};
//#endregion
//#region src/types.d.ts
/**
* Optional callback invoked when a tool is called with queries
* @param toolName - The name of the tool being invoked
* @param queries - Array of query objects passed to the tool
*/
type ToolInvocationCallback = (toolName: string, queries: unknown[]) => Promise<void>;
//#endregion
//#region src/tools/toolsManager.d.ts
/**
* Register all tools from ALL_TOOLS (single source of truth in toolConfig.ts).
*
* Flow:
* 1. Check if tool should be enabled (config filtering)
* 2. Check if tool exists in metadata
* 3. Register the tool
*/
declare function registerTools(server: McpServer, callback?: ToolInvocationCallback): Promise<{
successCount: number;
failedTools: string[];
}>;
//#endregion
//#region src/prompts/prompts.d.ts
/**
* Register all prompts with the MCP server
* Iterates over the prompts defined in the metadata and registers them dynamically
*/
declare function registerPrompts(server: McpServer, content: CompleteMetadata): void;
//#endregion
//#region src/tools/toolConfig.d.ts
interface ToolConfig {
name: string;
description: string;
isDefault: boolean;
isLocal: boolean;
type: 'search' | 'content' | 'history' | 'debug';
fn: (server: McpServer, callback?: ToolInvocationCallback) => RegisteredTool | Promise<RegisteredTool | null>;
}
/**
* All tools in ONE place - the single source of truth for tool registration.
* GitHub tools first, then local tools.
*
* Local tools (isLocal: true) are only registered when ENABLE_LOCAL config is true.
*/
declare const ALL_TOOLS: ToolConfig[];
//#endregion
export { ALL_TOOLS, BASE_SCHEMA, type BaseSchema, type CompleteMetadata, DESCRIPTIONS, GENERIC_ERROR_HINTS, GITHUB_FETCH_CONTENT, GITHUB_SEARCH_CODE, GITHUB_SEARCH_PULL_REQUESTS, GITHUB_SEARCH_REPOS, GITHUB_VIEW_REPO_STRUCTURE, type HintContext, type HintGenerator, type HintStatus, LOCAL_FETCH_CONTENT, LOCAL_FIND_FILES, LOCAL_RIPGREP, LOCAL_VIEW_STRUCTURE, PACKAGE_SEARCH, type PromptArgument, type PromptMetadata, type RawCompleteMetadata, STATIC_TOOL_NAMES, TOOL_HINTS, TOOL_NAMES, type ToolConfig, type ToolHintGenerators, type ToolMetadata, type ToolName, type ToolNames, getDynamicHints, getGenericErrorHintsSync, getToolHintsSync, initializeToolMetadata, isToolInMetadata, loadToolContent, registerPrompts, registerTools };
//# sourceMappingURL=public.d.ts.map