Project Knowledge MCP Server
Allows querying and analyzing projects within a GitLab group, including project purposes, I/O, dependencies, and purpose conflicts.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Project Knowledge MCP Serverlist all projects and their purposes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Project Knowledge MCP Server
An MCP server that builds and serves structured knowledge about projects in a GitLab group.
It runs in a single OS process and exposes two surfaces:
MCP over stdio — eight tools that an MCP client can call to query projects and trigger refreshes.
Read-only HTML visualization on
http://127.0.0.1:{port}— diagrams of project profiles, shared dependencies, and purpose conflicts.
Both surfaces read from the same Knowledge_Store (a single SQLite file with snapshot-based atomic-pointer-swap semantics) so readers always see a consistent view, even while a refresh is in flight.
What does the analysis? Static inspection in Python (no LLM). For every project, four sub-analyzers run: purpose (READMEs, GitLab description, manifests, top-level docstrings), I/O extractor (HTTP routes, scheduled tasks, message consumers/publishers, file I/O, CLI entrypoints), external services (HTTP clients, brokers, object stores), and database tables (SQL/ORM references, read/write modes). Source code is fetched at the configured
Analysis_Branch(defaultuat).
Go analyzer support
Go repositories are analyzed in-process with the same depth as Python, JavaScript/TypeScript, and Java repositories. No Go toolchain is invoked at runtime; a hand-written Python tokenizer reads .go source directly. The Go layer activates automatically when a RepositoryContents snapshot contains at least one .go file or a repo-root go.mod — there is no configuration to enable.
What gets detected
Sub-analyzer | Go patterns recognized |
Purpose |
|
I/O extractor |
|
External services |
|
Database tables | SQL extracted from |
What gets excluded
Vendor directories. Any
.gofile whose path contains a directory segment namedvendoris skipped end-to-end. The Go scanners reject vendored paths at the parser boundary, and the language-agnostic detectors are also handed a vendor-aware view so vendored Go source's embedded string literals cannot leak into SQL, URL, or SDK-pattern detections.Build-constraint-gated files. A file with a non-trivial
//go:buildor// +buildline (e.g.linux && amd64,darwin,!cgo) is wholesale skipped because honoring the constraint requires a Go toolchain. Skipped files are surfaced indegraded_sectionsas"<section>: skipped <path> (build constraint requires toolchain)".cgo files. A file containing
import "C"is skipped for the same reason and surfaced under the samedegraded_sectionsshape with reasoncgo directive requires toolchain.Tokenization errors. Unterminated strings, raw strings, block comments, and invalid escape sequences are contained per file: the affected file contributes zero detections and is surfaced with reason
tokenization failed: <detail>.DI and config noise.
fx.New/fx.Provide/fx.Invoke/fx.Module/fx.Hook/*fx.Lifecyclecalls describe internal wiring and never produce HTTP, scheduler, ActiveMQ, file-I/O, CLI, or external-service detections by themselves.viperconfiguration reads (*viper.Viper.GetString,SetConfigName,AddConfigPath, etc.) never contribute to the purpose summary or any detection.
Triggering Go analysis
No flag, no environment variable, no client opt-in. Run the server as documented above against a GitLab group containing Go projects — every refresh that fetches a snapshot with .go files or a go.mod automatically routes through the Go sub-analyzers. The result is observable through the same MCP tools and visualization routes as any other project:
get_project_purposereturns a summary derived fromgo.mod/ package doc when no README is present.get_project_iolists HTTP routes, cron schedules, ActiveMQ destinations, file I/O, and binary entry points found in the Go source.get_project_dependencieslistsfec_pool_service(when reached via eitherpbordbadapter), ActiveMQ brokers, and any URL-literal-derived service, plus the database tables extracted from in-process SQL.
When a Go file is skipped for any reason listed above, the affected section name appears in the profile's degraded_sections list with a structured "<section>: skipped <path> (<reason>)" entry so the operator can see exactly which files the analyzer could not reach.
Related MCP server: ontomics
Requirements
Python 3.11+
A GitLab access token with
read_apiandread_repositoryscopes for the target group.
Install
From this repository:
pip install -e ".[dev]"The install registers a console script:
project-knowledge-mcp = project_knowledge_mcp.main:mainConfiguration
Configuration is read from environment variables. On any missing or invalid value the server prints a single line to stderr that names the offending key and exits non-zero before either surface accepts traffic.
Variable | Required | Default | Notes |
| yes | — | e.g. |
| yes | — | Top-level group path (e.g. |
| yes | — | Token with |
| no |
| Whether outbound HTTPS calls to |
| no |
| Branch fetched per project, regardless of GitLab default branch. |
| no | none | When set (e.g. |
| no |
| Loopback-only TCP port ( |
| no |
| SQLite database path. The parent directory is created if missing. |
| no |
| Root logging level for stderr output. The application's operationally important lines (visualization "ready" banner, refresh-progress per-project lines, refresh-complete summary) are emitted at |
The store persists across restarts: on reopen, readers immediately serve the last successfully committed snapshot, and an in-flight job aborted at shutdown does not affect that pointer.
Run
GITLAB_BASE_URL=https://gitlab.example.com \
GITLAB_GROUP_PATH=acme/platform \
GITLAB_ACCESS_TOKEN=glpat-... \
project-knowledge-mcpOn startup you will see a single log line:
Visualization_Server ready at http://127.0.0.1:7345The MCP server simultaneously speaks JSON-RPC over stdin/stdout, so this command is normally launched by an MCP client rather than run interactively.
Use from an MCP client
Configure your MCP-aware tool (Claude Desktop, an editor MCP integration, etc.) to spawn the server. Example config:
{
"mcpServers": {
"project-knowledge": {
"command": "project-knowledge-mcp",
"env": {
"GITLAB_BASE_URL": "https://gitlab.example.com",
"GITLAB_GROUP_PATH": "acme/platform",
"GITLAB_ACCESS_TOKEN": "glpat-...",
"ANALYSIS_BRANCH": "uat",
"REFRESH_INTERVAL": "1h"
}
}
}
}Available MCP tools
Eight tools are registered. The first six are read-only; the last two trigger ingestion.
Tool | Arguments | Purpose |
| — | List in-scope projects from the current |
|
| Purpose summary + reason. |
|
| Abstract inputs and outputs. |
|
| External services + database tables. |
|
| The complete |
| — | Pairs of projects with overlapping or contradictory primary responsibilities. |
| — | Start a full refresh of every in-scope project. |
|
| Re-analyze a single project, copying every other profile from the parent snapshot. |
Refresh tools enforce a single-flight rule: while one ingestion job is running, additional refresh requests (from any source — tool call or scheduler) are rejected with the message Ingestion_Job is already in progress. The Knowledge_Store is unchanged.
Out-of-scope project ids return a tool result with isError: true and the message project {id} is not in scope.
Visualization
Browse http://127.0.0.1:7345/ (or your configured port). All routes serve text/html; charset=utf-8:
Route | Shows |
| Index of in-scope projects, sorted by id. Empty catalog → |
| Single project: purpose summary; abstract inputs grouped by category; abstract outputs grouped by category; external services labeled by kind; database tables labeled by access mode. Each empty section shows a section-specific empty-state message. |
| Mermaid graph: nodes = in-scope projects, edges = shared database tables. |
| Static file mount serving the package's |
Enable graph rendering
The /dependencies page renders an interactive knowledge graph using Cytoscape.js. Drop the bundle at src/project_knowledge_mcp/static/cytoscape.min.js:
curl -L -o src/project_knowledge_mcp/static/cytoscape.min.js \
https://cdn.jsdelivr.net/npm/cytoscape@3/dist/cytoscape.min.jsWhen Cytoscape is loaded the page emits an interactive node-and-edge graph with zoom, pan, drag, and hover tooltips. The same diagram is also emitted as a Mermaid <pre class="mermaid"> block; when cytoscape.min.js is absent the page falls back to Mermaid by dropping a Mermaid bundle at src/project_knowledge_mcp/static/mermaid.min.js:
curl -L -o src/project_knowledge_mcp/static/mermaid.min.js \
https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.jsFor air-gapped networks, fetch either file from any machine that can reach the CDN and copy it into the same path. See src/project_knowledge_mcp/static/README.md for details. When both files are missing the pages still load — graphs degrade to the raw graph LR ... text.
Behavior pinned by the spec:
Reads happen at request time — no in-memory caching of profiles.
Non-matching paths → 404 with the requested path echoed in the body.
Non-
GETmethods → 405 withAllow: GET.Knowledge_Storefailures → 503 with no profile-derived content.Every successful response begins within 5 seconds.
Typical workflow
Start the server with
REFRESH_INTERVAL=1h(or trigger refreshes manually).After the first ingestion completes, the visualization populates and the MCP query tools start returning data.
Iterate: as code in your GitLab projects evolves on
Analysis_Branch, each refresh produces a new snapshot. Readers atomically switch to the new snapshot only when the ingestion commits.
Operations
Skipped projects. When a project has no
Analysis_Branch, the ingestion records a skip with reasonanalysis_branch_missingand continues with the rest. NoProject_Profileis produced for skipped projects; they still appear in the catalog so you can tell "in scope but not yet analyzed" from "out of scope".Auth failures. A
401/403from GitLab aborts the in-flight job and surfaces the status code; the previous snapshot remains current. A404for the configured group raisesGitLabGroupNotFoundError(group_path).Shutdown. SIGTERM/SIGINT triggers a documented shutdown ordering: stop accepting new HTTP connections → close MCP stdio → mark any in-flight snapshot
failed(thecurrent_snapshotpointer is unchanged) → flush and close the SQLite store → exit.Port already in use. Startup prints
startup error: visualization.port {port} is already in useand exits non-zero.
Tests
pytest -m unit # ~3s
pytest -m property # Hypothesis, max_examples=100, ~30s
pytest -m integration # subprocess + HTTP + SQLite, ~15sOr all of them:
pytestProject layout
src/project_knowledge_mcp/
config.py # env loader + validator (single termination path)
errors.py # error type hierarchy
models.py # Project_Profile, EnumeratedProject, ConflictResult, ...
knowledge_store.py # SQLite + snapshot pointer + WAL
project_catalog.py # snapshot-scoped in-scope set
gitlab_connector.py # paginated GitLab API client
project_analyzer/ # purpose, io_extractor, external_services, db_tables
conflict_detector.py # classify_pair + find_all_conflicts
ingestion_coordinator.py # single-flight state machine
scheduler.py # periodic refresh
mcp_server.py # MCP over stdio + 8 tools
visualization_server.py # Starlette + Uvicorn (loopback only)
diagram_renderer.py # Jinja2 + inline Mermaid
main.py # wiring, startup, shutdown orderingThe full specification (requirements, design, and the 30 correctness properties the implementation is verified against) lives under .kiro/specs/project-knowledge-mcp/.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/nampd3/gitlab-knowledege'
If you have feedback or need assistance with the MCP directory API, please join our Discord server