Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a1ce795
docs: map existing codebase
mikallojjus Feb 18, 2026
1c8f9b3
docs: initialize project
mikallojjus Feb 18, 2026
87034d8
docs: complete project research for Hypergraph MCP server
mikallojjus Feb 18, 2026
9e95332
feat(01-01): scaffold mcp-server package with config loading and vali…
mikallojjus Feb 18, 2026
01c8be4
feat(01-01): add GraphQL client, prefetch pipeline, and MCP server en…
mikallojjus Feb 18, 2026
4f165d9
feat(01-02): add store, fuzzy matching, formatters, and list_spaces tool
mikallojjus Feb 18, 2026
feceefa
feat(01-02): add get_entity_types tool and wire tools into entry point
mikallojjus Feb 18, 2026
3112c6f
fix(mcp-server): correct API endpoint and trim to single configured s…
mikallojjus Feb 18, 2026
d643342
docs(02): research phase domain for entity tools and human readability
mikallojjus Feb 18, 2026
fad2a84
feat(02-01): expand GraphQL queries, prefetch pipeline, and store for…
mikallojjus Feb 18, 2026
c8b1f7c
feat(02-01): add entity formatter and enhance types formatter with pr…
mikallojjus Feb 18, 2026
f632801
feat(02-02): add search_entities, get_entity, and list_entities tools
mikallojjus Feb 18, 2026
997d940
feat(02-02): wire all 5 tools into MCP server entry point
mikallojjus Feb 18, 2026
973f83f
ref(mcp-server): Separate properties query and handle duplicate type …
mikallojjus Feb 18, 2026
c47d928
feat: Add CSV export script for knowledge graph spaces
mikallojjus Feb 18, 2026
95e1a5b
feat(mcp-server): Add HTTP transport and Dockerfile for Railway deplo…
mikallojjus Feb 19, 2026
3e397d0
ref(mcp-server): Move Dockerfile into package directory
mikallojjus Feb 19, 2026
7b02d6a
fix(mcp-server): Remove Docker cache mounts unsupported by Railway
mikallojjus Feb 19, 2026
09a898e
ref(mcp-server): Move Dockerfile back to repo root
mikallojjus Feb 19, 2026
f1c9406
feat(mcp-server): Add get_related_entities tool for graph traversal
mikallojjus Feb 19, 2026
7855cff
ref(mcp-server): Improve tool descriptions and add server instructions
mikallojjus Feb 19, 2026
91e4d66
feat(mcp-server): Add periodic background cache refresh
mikallojjus Feb 19, 2026
b044635
chore: Remove .claude, .planning, and CLAUDE_INTEGRATION from tracking
mikallojjus Feb 19, 2026
b272b95
Merge pull request #1 from geo-explorers/feat/mcp-server
mikallojjus Feb 19, 2026
99a4152
feat: update spaces.json
mikallojjus Feb 20, 2026
7c51157
fix: fix trailing comma in spaces.json
mikallojjus Feb 20, 2026
3df4b94
feat(mcp-server): Add cross-space search, property filtering, and UX …
mikallojjus Feb 23, 2026
ecfcf78
feat(mcp-server): Add warnings for unresolved filter/sort properties
mikallojjus Feb 23, 2026
8a7a08d
feat(mcp-server): Add related_to relation filter to search and list t…
mikallojjus Feb 23, 2026
b4c01ac
feat(mcp-server): Add relation type discovery to get_entity_types
mikallojjus Feb 23, 2026
ebcc128
feat(mcp-server): Add compact output mode to entity listing tools
mikallojjus Feb 23, 2026
df1541f
feat(mcp-server): Make list_entities cross-space and strengthen prompts
mikallojjus Feb 23, 2026
71d2728
fix(mcp-server): Prevent space-narrowing bias in tool descriptions
mikallojjus Feb 23, 2026
ffb4f4d
feat: add podcast app space
mikallojjus Mar 2, 2026
004ac47
export-csv extend types
MVytautas Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions .claude/settings.local.json

This file was deleted.

5 changes: 4 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@
# Workspace package dependencies.
!packages/hypergraph
!packages/hypergraph-react
!packages/typesync-studio
!packages/typesync-studio

# MCP server.
!packages/mcp-server
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,7 @@ next-env.d.ts
.DS_Store

# tanstack router output
.tanstack
.tanstack

.claude
.planning
32 changes: 32 additions & 0 deletions Dockerfile.mcp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# syntax=docker/dockerfile:1.4

# Installation stage.
FROM node:22-alpine AS base
WORKDIR /workspace
# Install pnpm via corepack.
ADD package.json .
RUN npm install --global corepack@latest
RUN corepack enable && corepack prepare --activate
ENV CI=true
# Fetch all node modules purely based on the pnpm lock file.
COPY pnpm-lock.yaml .
RUN pnpm fetch
# Copy the entire workspace into the scope and perform the actual installation.
COPY . .
RUN pnpm install

# Build stage.
FROM base AS build
RUN \
pnpm --filter @graphprotocol/mcp-server build && \
pnpm --filter @graphprotocol/mcp-server deploy --prod deployment --legacy && \
mkdir -p deployment/out && \
mv deployment/dist deployment/node_modules deployment/package.json deployment/out && \
cp -r packages/mcp-server/config deployment/out/config

# Slim runtime image.
FROM node:22-alpine AS runtime
WORKDIR /app
COPY --from=build /workspace/deployment/out .
EXPOSE 3000
CMD ["node", "dist/http.js"]
55 changes: 55 additions & 0 deletions packages/mcp-server/config/spaces.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"endpoint": "https://testnet-api.geobrowser.io",
"spaces": [
{
"name": "Geo",
"id": "a19c345ab9866679b001d7d2138d88a1",
"description": "Geo space"
},
{
"name": "AI",
"id": "41e851610e13a19441c4d980f2f2ce6b",
"description": "AI space"
},
{
"name": "Crypto",
"id": "c9f267dcb0d270718c2a3c45a64afd32",
"description": "Crypto space"
},
{
"name": "Health",
"id": "52c7ae149838b6d47ce0f3b2a5974546",
"description": "Health space"
},
{
"name": "Industries",
"id": "d69608290513c2a91102c939b3265bd7",
"description": "Industries space"
},
{
"name": "Technology",
"id": "870e3b3068661e6280fad2ab456829bc",
"description": "Technology space"
},
{
"name": "Software",
"id": "9b611b848b12491b9b6b43f3cf019b8b",
"description": "Software space"
},
{
"name": "Geo Education",
"id": "720eb279c64d56735dccd17a2a416ba2",
"description": "Geo Education space"
},
{
"name": "Healthcare",
"id": "5d3e53b46f2dd38caa231ccc763212f5",
"description": "Healthcare space"
},
{
"name": "Podcast App",
"id": "b5a31f8182b042437ede0f84ee02f104",
"description": "Podcast App space"
}
]
}
33 changes: 33 additions & 0 deletions packages/mcp-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@graphprotocol/mcp-server",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "tsx src/index.ts",
"dev:http": "tsx src/http.ts",
"start": "node dist/http.js",
"build": "tsc -b tsconfig.build.json",
"test": "vitest",
"lint": "biome check",
"lint:fix": "biome check --write --unsafe",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.26.0",
"express": "^5.1.0",
"zod": "^3.25.0",
"graphql-request": "^7.2.0",
"graphql": "^16.10.0",
"effect": "^3.17.13",
"@geoprotocol/geo-sdk": "^0.9.0"
},
"devDependencies": {
"@types/express": "^5.0.0",
"typescript": "^5.9.2",
"tsx": "^4.20.5",
"@types/node": "^24.1.0",
"vitest": "^3.2.4",
"@effect/vitest": "^0.25.1"
}
}
34 changes: 34 additions & 0 deletions packages/mcp-server/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { Effect } from 'effect';
import { z } from 'zod';
import { ConfigError } from './errors.js';

export const SpaceConfigSchema = z.object({
name: z.string(),
id: z.string(),
description: z.string(),
});

export const ConfigSchema = z.object({
endpoint: z.string().url(),
spaces: z.array(SpaceConfigSchema).min(1),
});

export type SpacesConfig = z.infer<typeof ConfigSchema>;
export type SpaceConfig = z.infer<typeof SpaceConfigSchema>;

export const loadConfig = (
configPath: string = resolve(import.meta.dirname, '..', 'config', 'spaces.json'),
): Effect.Effect<SpacesConfig, ConfigError> =>
Effect.try({
try: () => {
const raw = readFileSync(configPath, 'utf-8');
const json: unknown = JSON.parse(raw);
return ConfigSchema.parse(json);
},
catch: () =>
new ConfigError({
message: 'Failed to load configuration. Ensure config file exists and is valid JSON.',
}),
});
15 changes: 15 additions & 0 deletions packages/mcp-server/src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Data } from 'effect';

export class ConfigError extends Data.TaggedError('ConfigError')<{
readonly message: string;
}> {}

export class PrefetchError extends Data.TaggedError('PrefetchError')<{
readonly space: string;
readonly cause: unknown;
}> {}

export class GraphQLError extends Data.TaggedError('GraphQLError')<{
readonly query: string;
readonly cause: unknown;
}> {}
Loading