Skip to content

Instantly share code, notes, and snippets.

@szymdzum
Last active August 24, 2025 17:39
Show Gist options
  • Select an option

  • Save szymdzum/6085e1a40de3712834e159ed592af305 to your computer and use it in GitHub Desktop.

Select an option

Save szymdzum/6085e1a40de3712834e159ed592af305 to your computer and use it in GitHub Desktop.
boltzmann-opus
#!/usr/bin/env node
/**
* Developer Hub MCP Server
*
* THE SCIENCE: Why This Works
*
* 1. SEMANTIC MEMORY ARCHITECTURE
* Human brains have two memory systems:
* - Episodic (specific events)
* - Semantic (general knowledge)
*
* This MCP server acts as the semantic memory for your AI assistant.
* Instead of Claude trying to remember "that time you told me about your project structure",
* it has constant access to the actual structure itself.
*
* 2. ATTENTION MECHANISM
* Transformer models (like Claude) use attention to focus on relevant information.
* By exposing your entire Developer structure, we're giving the attention mechanism
* more signal to work with. It's like the difference between searching in a
* well-organized library vs a pile of books on the floor.
*
* 3. GRAPH TOPOLOGY
* Code isn't linear - it's a graph. Projects depend on each other,
* scripts reference knowledge, knowledge links to projects.
* This server exposes that graph structure, allowing the AI to traverse
* relationships instead of treating everything as isolated files.
*/
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
ListToolsRequestSchema,
CallToolRequestSchema,
ListResourcesRequestSchema,
ReadResourceRequestSchema,
Tool,
Resource,
TextContent,
CallToolRequest,
ListToolsRequest,
ListResourcesRequest,
ReadResourceRequest
} from "@modelcontextprotocol/sdk/types.js";
import fs from 'fs/promises';
import path from 'path';
import { glob } from 'glob';
import matter from 'gray-matter';
import chokidar from 'chokidar';
import type { FSWatcher } from 'chokidar';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Your Developer hub root - this is the context window into your entire setup
const DEVELOPER_ROOT = path.resolve(process.env.HOME!, 'Developer');
/**
* INFORMATION THEORY PRINCIPLE:
* We're reducing entropy (uncertainty) by providing structure.
* Without this, Claude has to guess what projects exist, where knowledge lives, etc.
* With this, it KNOWS the exact topology of your development environment.
*/
// Primary focus is the Knowledge vault - everything else is secondary
const HUB_STRUCTURE = {
knowledge: path.join(DEVELOPER_ROOT, 'Knowledge'),
projects: path.join(DEVELOPER_ROOT, 'Knowledge/Projects'), // Project notes in Obsidian
scripts: path.join(DEVELOPER_ROOT, 'Scripts'),
configs: path.join(DEVELOPER_ROOT, 'Configs'),
tools: path.join(DEVELOPER_ROOT, 'Tools'),
resources: path.join(DEVELOPER_ROOT, 'Knowledge/Resources'), // Resource docs
archive: path.join(DEVELOPER_ROOT, 'Archive'),
ai: path.join(DEVELOPER_ROOT, '.ai')
} as const;
// Type definitions for our domain
interface KnowledgeNode {
frontmatter: Record<string, any>;
links: string[];
path: string;
type: KnowledgeType;
}
interface ProjectInfo {
path: string;
dependencies: string[];
hasAIContext: boolean;
type: ProjectType;
}
interface SearchResult {
type: 'knowledge' | 'project' | 'script' | 'config';
path: string;
score?: number;
metadata?: Record<string, any>;
connections?: number;
name?: string;
projectType?: ProjectType;
hasAIContext?: boolean;
dependencies?: string[];
}
interface GraphNode {
id: string;
type: ProjectType;
hasAIContext: boolean;
}
interface Graph {
nodes: GraphNode[];
edges: Array<{ from: string; to: string }>;
}
interface RelatedKnowledge {
file: string;
level: number;
type: KnowledgeType;
frontmatter: Record<string, any>;
}
interface WorkspaceAnalysis {
timestamp: string;
focus: AnalysisFocus;
findings: Array<{
type: string;
[key: string]: any;
}>;
}
type KnowledgeType = 'project-doc' | 'code-snippet' | 'daily-note' | 'learning' | 'resource' | 'general';
type ProjectType = 'node' | 'python' | 'rust' | 'go' | 'unknown';
type ResourceType = 'all' | 'knowledge' | 'projects' | 'scripts' | 'configs';
type AnalysisFocus = 'dependencies' | 'documentation' | 'structure' | 'duplication';
// Tool argument types
interface ExploreHubArgs {
query: string;
type?: ResourceType;
}
interface GetProjectGraphArgs {
project?: string;
}
interface FindRelatedKnowledgeArgs {
topic: string;
depth?: number;
}
interface GenerateFromTemplateArgs {
template: string;
name: string;
variables?: Record<string, any>;
}
interface AnalyzeWorkspaceArgs {
focus: AnalysisFocus;
}
class KnowledgeGraphServer {
private server: Server;
private watcher: FSWatcher | null = null;
private knowledgeGraph: Map<string, KnowledgeNode> = new Map();
private projectDependencies: Map<string, ProjectInfo> = new Map();
constructor() {
this.server = new Server({
name: "knowledge-graph",
version: "1.0.0",
}, {
capabilities: {
tools: {},
resources: {}
},
});
this.setupHandlers();
this.initializeKnowledgeGraph();
}
/**
* GRAPH THEORY APPLICATION:
* Build an in-memory graph of all relationships in your Developer hub.
* This allows O(1) lookups instead of O(n) file system traversals.
*/
private async initializeKnowledgeGraph(): Promise<void> {
console.error("Building knowledge graph...");
try {
// Index Obsidian vault (Knowledge/)
const knowledgeFiles = await glob('**/*.md', {
cwd: HUB_STRUCTURE.knowledge,
ignore: ['.obsidian/**', '.trash/**']
});
for (const file of knowledgeFiles) {
const fullPath = path.join(HUB_STRUCTURE.knowledge, file);
const content = await fs.readFile(fullPath, 'utf-8');
const { data, content: body } = matter(content);
// Extract wiki-links [[]] to build connection graph
const links = (body.match(/\[\[([^\]]+)\]\]/g) || [])
.map(link => link.slice(2, -2));
this.knowledgeGraph.set(file, {
frontmatter: data,
links,
path: fullPath,
type: this.categorizeKnowledge(file)
});
}
} catch (e) {
console.error("Knowledge folder not found or empty:", e);
}
try {
// Index Projects and their dependencies
const projectDirs = await fs.readdir(HUB_STRUCTURE.projects);
for (const project of projectDirs) {
const projectPath = path.join(HUB_STRUCTURE.projects, project);
const stat = await fs.stat(projectPath);
if (stat.isDirectory()) {
await this.indexProject(project, projectPath);
}
}
} catch (e) {
console.error("Projects folder not found or empty:", e);
}
console.error(`Knowledge graph built: ${this.knowledgeGraph.size} nodes`);
}
private async indexProject(name: string, projectPath: string): Promise<void> {
const dependencies = new Set<string>();
// Check for package.json dependencies
try {
const pkgPath = path.join(projectPath, 'package.json');
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf-8'));
// Internal workspace dependencies
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
for (const [dep, version] of Object.entries(deps)) {
if (typeof version === 'string' &&
(version.startsWith('file:') || version.startsWith('workspace:'))) {
dependencies.add(dep);
}
}
} catch (e) {
// Not a Node project, check for other patterns
}
// Check for Claude.md or .claude directory (AI context)
const hasClaudeContext = await this.fileExists(path.join(projectPath, 'Claude.md')) ||
await this.fileExists(path.join(projectPath, '.claude'));
this.projectDependencies.set(name, {
path: projectPath,
dependencies: Array.from(dependencies),
hasAIContext: hasClaudeContext,
type: await this.detectProjectType(projectPath)
});
}
private async detectProjectType(projectPath: string): Promise<ProjectType> {
// PATTERN RECOGNITION: Like how humans categorize, we use heuristics
if (await this.fileExists(path.join(projectPath, 'package.json'))) return 'node';
if (await this.fileExists(path.join(projectPath, 'requirements.txt'))) return 'python';
if (await this.fileExists(path.join(projectPath, 'Cargo.toml'))) return 'rust';
if (await this.fileExists(path.join(projectPath, 'go.mod'))) return 'go';
return 'unknown';
}
private categorizeKnowledge(filePath: string): KnowledgeType {
// HIERARCHICAL CATEGORIZATION: Mimics how human brain organizes information
if (filePath.includes('Projects/')) return 'project-doc';
if (filePath.includes('Snippets/')) return 'code-snippet';
if (filePath.includes('Notes/daily/')) return 'daily-note';
if (filePath.includes('Learning/')) return 'learning';
if (filePath.includes('Resources/')) return 'resource';
return 'general';
}
private async fileExists(filePath: string): Promise<boolean> {
try {
await fs.access(filePath);
return true;
} catch {
return false;
}
}
private setupHandlers(): void {
// List available tools
this.server.setRequestHandler(ListToolsRequestSchema, async (): Promise<{ tools: Tool[] }> => ({
tools: [
{
name: "explore_hub",
description: "Explore the Developer hub structure and find relevant resources",
inputSchema: {
type: "object",
properties: {
query: {
type: "string",
description: "What to search for (project, knowledge, script, etc.)"
},
type: {
type: "string",
enum: ["all", "knowledge", "projects", "scripts", "configs"],
description: "Type of resource to search"
}
},
required: ["query"]
},
},
{
name: "get_project_graph",
description: "Get the dependency graph of all projects",
inputSchema: {
type: "object",
properties: {
project: {
type: "string",
description: "Specific project to focus on (optional)"
}
}
},
},
{
name: "find_related_knowledge",
description: "Find knowledge documents related to a topic using the knowledge graph",
inputSchema: {
type: "object",
properties: {
topic: {
type: "string",
description: "Topic to find related knowledge about"
},
depth: {
type: "number",
description: "How many levels of relationships to traverse (default: 2)"
}
},
required: ["topic"]
},
},
{
name: "generate_from_template",
description: "Generate new project/component from templates",
inputSchema: {
type: "object",
properties: {
template: {
type: "string",
description: "Template name or path"
},
name: {
type: "string",
description: "Name for the new project/component"
},
variables: {
type: "object",
description: "Variables to inject into template"
}
},
required: ["template", "name"]
},
},
{
name: "analyze_workspace",
description: "Analyze the entire workspace for patterns, issues, or improvements",
inputSchema: {
type: "object",
properties: {
focus: {
type: "string",
enum: ["dependencies", "documentation", "structure", "duplication"],
description: "What aspect to analyze"
}
},
required: ["focus"]
},
}
],
}));
// Handle tool calls
this.server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => {
const { name, arguments: args } = request.params;
switch (name) {
case "explore_hub": {
const exploreArgs = args as unknown as ExploreHubArgs;
return await this.exploreHub(exploreArgs);
}
case "get_project_graph": {
const graphArgs = args as unknown as GetProjectGraphArgs;
return await this.getProjectGraph(graphArgs);
}
case "find_related_knowledge": {
const knowledgeArgs = args as unknown as FindRelatedKnowledgeArgs;
return await this.findRelatedKnowledge(knowledgeArgs);
}
case "generate_from_template": {
const templateArgs = args as unknown as GenerateFromTemplateArgs;
return await this.generateFromTemplate(templateArgs);
}
case "analyze_workspace": {
const analyzeArgs = args as unknown as AnalyzeWorkspaceArgs;
return await this.analyzeWorkspace(analyzeArgs);
}
default:
throw new Error(`Unknown tool: ${name}`);
}
});
// List available resources (files, documents)
this.server.setRequestHandler(ListResourcesRequestSchema, async (): Promise<{ resources: Resource[] }> => {
const resources: Resource[] = [];
// Add key configuration files
try {
await fs.access(path.join(DEVELOPER_ROOT, 'README.md'));
resources.push({
uri: `file://${DEVELOPER_ROOT}/README.md`,
mimeType: "text/markdown",
name: "Developer Hub README"
});
} catch {
// README doesn't exist
}
// Add recent projects with AI context
for (const [name, info] of this.projectDependencies.entries()) {
if (info.hasAIContext) {
resources.push({
uri: `file://${info.path}`,
mimeType: "text/directory",
name: `Project: ${name}`
});
}
}
return { resources };
});
// Read specific resources
this.server.setRequestHandler(ReadResourceRequestSchema, async (request: ReadResourceRequest) => {
const { uri } = request.params;
const filePath = uri.replace('file://', '');
const content = await fs.readFile(filePath, 'utf-8');
return {
contents: [{
uri,
mimeType: "text/plain",
text: content
}]
};
});
}
/**
* SEARCH ALGORITHM: Combines multiple ranking signals
* Similar to PageRank but for your personal knowledge base
*/
private async exploreHub({ query, type = "all" }: ExploreHubArgs): Promise<{ content: TextContent[] }> {
const results: SearchResult[] = [];
const queryLower = query.toLowerCase();
// Search knowledge documents
if (type === "all" || type === "knowledge") {
for (const [file, info] of this.knowledgeGraph.entries()) {
const score = this.calculateRelevance(file, info, queryLower);
if (score > 0) {
results.push({
type: 'knowledge',
path: file,
score,
metadata: info.frontmatter,
connections: info.links.length
});
}
}
}
// Search projects
if (type === "all" || type === "projects") {
for (const [name, info] of this.projectDependencies.entries()) {
if (name.toLowerCase().includes(queryLower)) {
results.push({
type: 'project',
name,
path: info.path,
projectType: info.type,
hasAIContext: info.hasAIContext,
dependencies: info.dependencies
});
}
}
}
// Sort by relevance
results.sort((a, b) => (b.score || 0) - (a.score || 0));
return {
content: [{
type: "text",
text: JSON.stringify(results.slice(0, 20), null, 2)
}]
};
}
private calculateRelevance(file: string, info: KnowledgeNode, query: string): number {
let score = 0;
// Title match (highest weight)
if (file.toLowerCase().includes(query)) score += 10;
// Frontmatter tags match
if (info.frontmatter.tags) {
const tags = Array.isArray(info.frontmatter.tags)
? info.frontmatter.tags
: [info.frontmatter.tags];
if (tags.some((tag: string) => tag.toLowerCase().includes(query))) score += 5;
}
// Number of connections (PageRank-style)
score += Math.log(info.links.length + 1);
return score;
}
/**
* GRAPH TRAVERSAL: Breadth-first search through knowledge connections
* This mimics how human memory works - activating related concepts
*/
private async findRelatedKnowledge({ topic, depth = 2 }: FindRelatedKnowledgeArgs): Promise<{ content: TextContent[] }> {
const visited = new Set<string>();
const queue: Array<{ file: string; info: KnowledgeNode; level: number }> = [];
const results: RelatedKnowledge[] = [];
// Find starting nodes
for (const [file, info] of this.knowledgeGraph.entries()) {
if (file.toLowerCase().includes(topic.toLowerCase())) {
queue.push({ file, info, level: 0 });
visited.add(file);
}
}
// BFS through the knowledge graph
while (queue.length > 0) {
const item = queue.shift();
if (!item) continue;
const { file, info, level } = item;
results.push({
file,
level,
type: info.type,
frontmatter: info.frontmatter
});
if (level < depth) {
// Follow links
for (const link of info.links) {
const linkedFile = this.findFileByName(link);
if (linkedFile && !visited.has(linkedFile)) {
visited.add(linkedFile);
const linkedInfo = this.knowledgeGraph.get(linkedFile);
if (linkedInfo) {
queue.push({
file: linkedFile,
info: linkedInfo,
level: level + 1
});
}
}
}
}
}
return {
content: [{
type: "text",
text: JSON.stringify({
root: topic,
nodes: results,
totalConnections: results.reduce((sum, r) =>
sum + (this.knowledgeGraph.get(r.file)?.links.length || 0), 0
)
}, null, 2)
}]
};
}
private findFileByName(name: string): string | null {
// Handle [[file#section]] format
const cleanName = name.split('#')[0];
for (const file of this.knowledgeGraph.keys()) {
const basename = path.basename(file, '.md');
if (basename === cleanName) return file;
}
return null;
}
private async getProjectGraph({ project }: GetProjectGraphArgs): Promise<{ content: TextContent[] }> {
const graph: Graph = {
nodes: [],
edges: []
};
for (const [name, info] of this.projectDependencies.entries()) {
if (!project || name === project || info.dependencies.includes(project)) {
graph.nodes.push({
id: name,
type: info.type,
hasAIContext: info.hasAIContext
});
for (const dep of info.dependencies) {
graph.edges.push({
from: name,
to: dep
});
}
}
}
return {
content: [{
type: "text",
text: JSON.stringify(graph, null, 2)
}]
};
}
private async generateFromTemplate({ template, name, variables = {} }: GenerateFromTemplateArgs): Promise<{ content: TextContent[] }> {
// This is where you'd implement template generation
// For now, returning a structured plan
const templatePath = path.join(DEVELOPER_ROOT, 'Resources/Templates', template);
const targetPath = path.join(DEVELOPER_ROOT, 'Projects', name);
return {
content: [{
type: "text",
text: JSON.stringify({
action: "generate",
template: templatePath,
target: targetPath,
variables,
steps: [
"1. Copy template structure",
"2. Replace variables in files",
"3. Initialize git repository",
"4. Create Claude.md context file",
"5. Link to Knowledge base",
"6. Update project graph"
]
}, null, 2)
}]
};
}
private async analyzeWorkspace({ focus }: AnalyzeWorkspaceArgs): Promise<{ content: TextContent[] }> {
const analysis: WorkspaceAnalysis = {
timestamp: new Date().toISOString(),
focus,
findings: []
};
switch (focus) {
case "dependencies":
// Find circular dependencies
for (const [name, info] of this.projectDependencies.entries()) {
for (const dep of info.dependencies) {
const depInfo = this.projectDependencies.get(dep);
if (depInfo?.dependencies.includes(name)) {
analysis.findings.push({
type: 'circular_dependency',
projects: [name, dep]
});
}
}
}
break;
case "documentation":
// Find projects without AI context
for (const [name, info] of this.projectDependencies.entries()) {
if (!info.hasAIContext) {
analysis.findings.push({
type: 'missing_ai_context',
project: name,
suggestion: 'Add Claude.md or .claude/README.md'
});
}
}
break;
case "structure":
// Analyze folder structure consistency
const structures = new Map<string, string[]>();
for (const [name, info] of this.projectDependencies.entries()) {
const structure = await this.getProjectStructure(info.path);
structures.set(name, structure);
}
// Find outliers - TODO: implement outlier detection
analysis.findings.push({
type: 'structure_analysis',
projectCount: structures.size,
message: 'Structure analysis complete'
});
break;
case "duplication":
// Find similar code patterns across projects
// This would need more sophisticated analysis
analysis.findings.push({
type: 'duplication_analysis',
message: 'Duplication detection not yet implemented'
});
break;
}
return {
content: [{
type: "text",
text: JSON.stringify(analysis, null, 2)
}]
};
}
private async getProjectStructure(projectPath: string): Promise<string[]> {
const structure: string[] = [];
const entries = await fs.readdir(projectPath, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory() && !entry.name.startsWith('.') &&
!['node_modules', 'target', 'dist', 'build'].includes(entry.name)) {
structure.push(entry.name);
}
}
return structure.sort();
}
async run(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Knowledge Graph MCP Server running");
}
}
// Start the server
const server = new KnowledgeGraphServer();
server.run().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment