kbask

kbask

Hybrid MCP server combining Graphify's structural code graphs with Understand-Anything's semantic knowledge bases for code analysis, offering tools for querying code structure, semantic explanations, and hybrid operations like trace and ask.

Category
访问服务器

README

kbask

Hybrid MCP server that combines Graphify (structural code graphs) with Understand-Anything (LLM-derived semantic knowledge bases) into a single MCP endpoint.

Graphify tells you where things are. Understand-Anything tells you why they exist. kbask joins both and exposes them as MCP tools usable from Claude Code, Codex, Gemini CLI, and any other MCP-compatible host.


Why a hybrid?

Backend Strength Weakness
Graphify Exact, cheap, deterministic AST graph (calls, imports, ownership) No semantics — doesn't know why code exists
Understand-Anything Semantic narrative, domain knowledge, onboarding context Expensive to build, fuzzy, no edge-precise lookups

kbask gives you:

  • All 7 Graphify tools (query_graph, get_node, get_neighbors, get_community, god_nodes, graph_stats, shortest_path) pass-through
  • 5 semantic tools from Understand-Anything (semantic_explain, semantic_chat, semantic_diff, semantic_onboard, semantic_domain)
  • Hybrid tools that compose both:
    • ask(question) — structural BFS then semantic narrative on top candidates
    • trace(from, to) — shortest path + per-hop semantic gloss
    • onboard(area) — community detection + domain knowledge per cluster

Install

Latest release: 0.1.0 — assets: kbask-0.1.0-py3-none-any.whl, kbask-0.1.0.tar.gz, SHA256SUMS, install.sh, tool-install.sh.

Not yet on PyPI. Install from the GitHub Release, from main, or pinned to a tag. Once on PyPI, --from kbask resolves from there with no other change.

Releases are cut as X.Y.Z git tags (the leading v is optional — both 0.1.0 and v0.1.0 are accepted). The release GitHub Action builds a wheel + sdist, attaches them (and install.sh / tool-install.sh / SHA256SUMS) to the GitHub Release, and — if PYPI_TOKEN is configured — uploads the wheel to PyPI. See Releases for the cut process.

Pick the install style that matches your workflow:

A. Persistent CLI (uv tool install) — recommended

Puts kbask on your PATH so you can type it like any other tool:

# Latest release (auto-discovers GitHub Release wheel)
curl -fsSL https://raw.githubusercontent.com/sughosh-pocketfm/kbask/main/tool-install.sh | bash

# Pin to a specific release tag
KBASK_TAG=0.1.0 \
  curl -fsSL https://raw.githubusercontent.com/sughosh-pocketfm/kbask/main/tool-install.sh | bash

The script:

  1. Installs uv if missing (Astral installer).
  2. Hits https://api.github.com/repos/sughosh-pocketfm/kbask/releases/latest to find the wheel asset. Pin a release with KBASK_TAG=X.Y.Z (e.g. KBASK_TAG=0.1.0).
  3. Falls back to git+https://github.com/sughosh-pocketfm/kbask if no release exists yet (or for main).
  4. Runs uv tool install --force so kbask lands in ~/.local/bin.

After install:

kbask install claude --repo .     # wire MCP into Claude Code
kbask update .                    # build/refresh knowledge graph
kbask doctor                      # check dependencies
kbask --help

Upgrade:

uv tool upgrade kbask
# or rerun the curl one-liner (always uses --force)

B. One-shot host installer (no persistent CLI)

Wires kbask into a single MCP host's config without leaving a global kbask binary. The MCP server itself is spawned by the host via uvx --from git+... on demand.

curl -fsSL https://raw.githubusercontent.com/sughosh-pocketfm/kbask/main/install.sh | bash -s claude
# or: bash -s codex   |   bash -s gemini

# Pin to a tag (the MCP config gets the same pin):
KBASK_SOURCE="git+https://github.com/sughosh-pocketfm/kbask@0.1.0" \
  curl -fsSL https://raw.githubusercontent.com/sughosh-pocketfm/kbask/main/install.sh | bash -s claude

C. Direct uvx (no scripts)

# Latest main
uvx --from git+https://github.com/sughosh-pocketfm/kbask kbask install claude --repo .

# Pinned tag
uvx --from "git+https://github.com/sughosh-pocketfm/kbask@0.1.0" kbask install claude --repo .

# From a downloaded wheel (verify SHA256SUMS first)
uvx --from ./kbask-0.1.0-py3-none-any.whl kbask install claude --repo .

D. After PyPI publish

Everything above keeps working, plus:

uv tool install kbask                  # persistent CLI
uvx --from kbask kbask install claude  # one-shot
uvx kbask --help                       # script + pkg share name

Verify a release artifact

# From the release page, grab SHA256SUMS + the wheel
shasum -a 256 -c SHA256SUMS

What the installer does

  1. Creates <repo>/kbask-out/ if missing.
  2. Appends kbask-out/ to <repo>/.gitignore.
  3. Writes/upserts the host's MCP server config (timestamped backup of any existing file).
  4. Writes a /kbask slash command for the host:
    • Claude Code → <repo>/.claude/commands/kbask.md
    • Codex CLI → ~/.codex/prompts/kbask.md
    • Gemini CLI → ~/.gemini/commands/kbask.toml
    • Pass --no-slash-command to skip.
  5. Runs an MCP initialize + tools/list smoke test against the configured server.

After restart, you can invoke the slash command from chat: type /kbask how does X work? (or just /kbask to see its prompt).

Dependency preflight

Both kbask install <host> and kbask update print a status report for the upstreams kbask depends on:

[ok]   graphifyy ........... 0.5.0 (importable)
[ok]   graphify CLI ........ runnable (graphify or uvx on PATH)
[warn] understand-anything . knowledge graph not built yet
       To build:
         1. /plugin marketplace add Lum1104/Understand-Anything
         2. /plugin install understand-anything    (inside Claude Code)
         3. /understand                             (from this repo, in Claude Code)
         4. kbask update .

Run it standalone any time:

kbask doctor [path/to/repo]
  • graphifyy is a hard dep — installed transitively with kbask.
  • understand-anything is built by an LLM in Claude Code (no analyzer binary). Even Codex / Gemini users build the graph via Claude Code once, then kbask mirrors it.

Pin to a fork

KBASK_SOURCE=git+https://github.com/your-fork/kbask@v0.2.0 \
  uvx --from $KBASK_SOURCE kbask install claude --repo .

Build the knowledge base

After installing, build the input artifacts inside your project repo:

cd /path/to/your/project

# 1. Structural graph (Graphify)
uvx --from graphifyy graphify update .

# 2. Semantic graph (Understand-Anything) — built by an LLM in your host.
#    In Claude Code, run /understand once and let it populate
#    .understand-anything/knowledge-graph.json.

# 3. Mirror both into kbask-out/
uvx --from git+https://github.com/sughosh-pocketfm/kbask kbask update .

Produces kbask-out/:

kbask-out/
├── graph.json              # Graphify structural graph
├── knowledge-graph.json    # Understand-Anything semantic graph (mirrored)
├── knowledge-graph.meta.json
└── meta.json               # per-file hashes, versions, last-build timestamps

First run rebuilds everything. Subsequent kbask update runs are incremental — only files whose content hash changed are re-analysed. Token cost scales with diff size, not repo size.


Use it from your agent

After restart, any MCP-compatible host can call:

kbask.ask("how does login retry work?")
kbask.trace("LoginViewModel", "AuthRepository")
kbask.query_graph("ExoPlayer initialisation")
kbask.semantic_explain("aural/player/data/.../PlayerManager.kt")

Incremental updates

kbask update is a single command. There is no --structural / --semantic split — kbask figures out what changed and only regenerates the missing slice:

kbask update .
├── 1. Run Graphify → new graph.json
├── 2. Diff per-file content hashes against meta.json
│      → dirty = added | modified
│      → preserved = unchanged
│      → removed = deleted from repo
├── 3. Mirror <repo>/.understand-anything/knowledge-graph.json → kbask-out/
├── 4. Carry forward unchanged file entries; mark dirty/removed in meta.json
└── 5. Write meta.json (new hashes, timestamps, versions)

Note on the semantic graph. Understand-Anything has no self-running analyzer — its knowledge graph is built by an LLM (Claude Code) following the upstream plugin's prompts and persisted to <repo>/.understand-anything/knowledge-graph.json. kbask update mirrors that file into kbask-out/; rebuilding the upstream graph is owned by the LLM (e.g. /understand-update in Claude Code). If <repo>/.understand-anything/ is absent, semantic tools still report a clean "not built" error and structural tools keep working.

Flags:

  • kbask update . — incremental (default)
  • kbask update . --force — full rebuild, ignore meta.json
  • kbask update . --dry-run — print planned work, no writes
  • kbask update . --structural-only — Graphify only, skip semantic mirror

Host setup

kbask follows the MCP spec strictly (JSON-RPC 2.0 over stdio, standard tool schemas). It works in any host that speaks MCP.

Claude Code

Project-scope .mcp.json at your repo root:

{
  "mcpServers": {
    "kbask": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from", "git+https://github.com/sughosh-pocketfm/kbask",
        "--with", "mcp",
        "kbask", "serve", "kbask-out/"
      ]
    }
  }
}

After PyPI publish, replace "git+https://github.com/sughosh-pocketfm/kbask" with "kbask".

Or run the installer:

uvx --from git+https://github.com/sughosh-pocketfm/kbask kbask install claude --repo .

Codex CLI

Writes to $CODEX_HOME/config.toml (default ~/.codex/config.toml):

[mcp_servers.kbask]
args = ["--from", "git+https://github.com/sughosh-pocketfm/kbask", "--with", "mcp", "kbask", "serve", "/absolute/path/to/kbask-out"]
command = "uvx"
startup_timeout_sec = 120
uvx --from git+https://github.com/sughosh-pocketfm/kbask kbask install codex --repo .

Gemini CLI

Writes mcpServers block into ~/.gemini/settings.json:

{
  "mcpServers": {
    "kbask": {
      "command": "uvx",
      "args": [
        "--from", "git+https://github.com/sughosh-pocketfm/kbask",
        "--with", "mcp",
        "kbask", "serve", "/absolute/path/to/kbask-out"
      ]
    }
  }
}
uvx --from git+https://github.com/sughosh-pocketfm/kbask kbask install gemini --repo .

AGY

Status: not yet supported. Config path / format for AGY hosts is not documented here. Open an issue if you need it — installer template is one file (scripts/install-agy.py) once the path is confirmed.

Other MCP hosts

kbask serve <kbask-out-dir> speaks stdio MCP. Wire it the same way as any stdio MCP server in your host of choice.


Tool catalogue

Tool Source Description
query_graph structural BFS/DFS keyword search over the code graph
get_node structural Look up a single node by label/ID
get_neighbors structural First-hop neighbors of a node
get_community structural Members of a Louvain community
god_nodes structural Highest-centrality nodes (hot spots)
graph_stats structural Graph counts, density, top communities
shortest_path structural Path between two nodes
semantic_explain semantic Narrative explanation of a file or symbol
semantic_chat semantic Free-form question against the knowledge graph
semantic_diff semantic Explain what a git diff changes and why
semantic_onboard semantic Onboarding guide for a module
semantic_domain semantic Business-domain mapping for an area
ask hybrid Structural candidates + semantic narrative in one call
trace hybrid Shortest path with semantic gloss per hop
onboard hybrid Community clusters + domain knowledge per cluster

All tools return structured JSON. None of them call an LLM internally — they return context bundles for the calling agent's LLM to reason over. This mirrors Graphify's token_budget discipline and keeps the MCP host-agnostic.

Token accounting

Every tool response carries a _meta block reporting the approximate token + byte cost of that single call:

{
  "...your tool payload...": "...",
  "_meta": {
    "tool": "query_graph",
    "tokens": {"input": 12, "output": 1843, "total": 1855},
    "bytes":  {"input": 47, "output": 7321},
    "encoder": "heuristic:chars/4"
  }
}

By default kbask uses a len(text) / 4 heuristic (good to ~10%). For tokenizer-accurate counts install the optional extra:

uv pip install 'kbask[tokens]'    # or: pip install 'kbask[tokens]'

That swaps the encoder to tiktoken:cl100k_base. The agent can read _meta.tokens.total per call and self-throttle (e.g. drop depth or token_budget if a sweep is going hot).


Architecture

kbask (Python, stdio MCP)
├── backends/
│   ├── graphify.py        # reuses graphify.serve internals via networkx (no subprocess)
│   └── understand.py      # reads <repo>/.understand-anything/knowledge-graph.json
├── tools/
│   ├── structural.py      # 7 pass-through wrappers around graphify
│   ├── semantic.py        # 5 wrappers reading the mirrored knowledge graph
│   └── hybrid.py          # ask / trace / onboard — compose both backends
├── installers/            # per-host config writers (Claude / Codex / Gemini / AGY)
├── update.py              # incremental orchestrator (hash diff + mirror)
├── diff.py                # per-file hash delta
├── meta.py                # meta.json IO + hash_file
├── state.py               # process-wide out_dir holder
└── serve.py               # MCP stdio entry point — registers 15 tools

Design rules:

  1. Don't fork upstreams. Graphify and Understand-Anything are pinned dependencies, never patched.
  2. Schemas stay separate. Cross-reference by (file_path, line) — the only stable join key between the two graphs.
  3. stdout is sacred. All logs to stderr. stdout is reserved for JSON-RPC frames.
  4. No host detection. Server behaves identically regardless of caller. No Claude-isms.
  5. No auto-rebuild. Host decides when to refresh — no file watchers, no background work.

Releases

Versioning

v<MAJOR>.<MINOR>.<PATCH> (SemVer). Pre-1.0 — breaking changes can land on any minor bump.

The CI release job hard-fails when the tag and the version in pyproject.toml disagree, so keep these in sync:

  • pyproject.toml → [project] version
  • src/kbask/__init__.py → __version__

Cutting a release

# 1. Bump versions (must match the tag without the `v` prefix).
#    pyproject.toml:        version = "0.1.1"
#    src/kbask/__init__.py: __version__ = "0.1.1"

# 2. Commit + tag + push.
git commit -am "Release 0.1.1"
git tag 0.1.1
git push origin main --tags

Manual run (e.g. to re-cut from a fixed branch) is also supported:

gh workflow run release.yml -f tag=0.1.1

What the release pipeline does

.github/workflows/release.yml on tag push:

  1. Checks out at the tag.
  2. Sets up uv and Python 3.11.
  3. Verifies pyproject.toml version == tag without the leading v. Aborts otherwise.
  4. uv build → dist/kbask-X.Y.Z-py3-none-any.whl and dist/kbask-X.Y.Z.tar.gz.
  5. Smoke-tests the wheel — pip install + kbask --help must succeed.
  6. Generates SHA256SUMS.
  7. Creates the GitHub Release with auto-generated changelog and the following assets attached:
    • kbask-X.Y.Z-py3-none-any.whl
    • kbask-X.Y.Z.tar.gz
    • SHA256SUMS
    • install.sh (one-shot host installer bootstrap)
    • tool-install.sh (uv tool install bootstrap)
  8. Publishes to PyPI only if the PYPI_TOKEN repo secret is configured.

Required repo secrets

Secret Purpose Optional?
PYPI_TOKEN uv publish API token Yes — release runs without it; only PyPI step is skipped.

GITHUB_TOKEN is provided automatically (used by softprops/action-gh-release for the Release write).

Consumer install paths after release

Once the release exists:

# A. Persistent CLI — auto-finds the wheel
curl -fsSL https://raw.githubusercontent.com/sughosh-pocketfm/kbask/main/tool-install.sh | bash

# B. Pinned tag
KBASK_TAG=0.1.1 curl -fsSL https://raw.githubusercontent.com/sughosh-pocketfm/kbask/main/tool-install.sh | bash

# C. Direct download
gh release download 0.1.1 --repo sughosh-pocketfm/kbask --pattern '*.whl'
shasum -a 256 -c SHA256SUMS
uv tool install ./kbask-0.1.1-py3-none-any.whl

tool-install.sh hits GET /repos/{owner}/{repo}/releases/latest to discover the newest tag and prefers the wheel asset over the git source.


Status

Capability State
MCP stdio server + 15 tools ✅
Structural tools via graphify.serve internals ✅
Semantic tools reading mirrored knowledge graph ✅
Hybrid ask / trace / onboard (3-stage cascade) ✅
Incremental kbask update ✅ structural rebuild + semantic mirror
Per-tool _meta.tokens accounting ✅ heuristic; kbask[tokens] extra for tiktoken
Tolerant node lookup (path / basename / label / id) ✅
Dependency preflight (kbask doctor) ✅
/kbask slash command writer (Claude/Codex/Gemini) ✅
Installer scripts (Claude/Codex/Gemini) ✅
tool-install.sh + install.sh curl bootstraps ✅
GitHub Release pipeline (wheel/sdist/checksums) ✅
PyPI publish ⏳ token not yet configured
AGY installer ⏳ blocked on config-path docs

This is an alpha MVP. APIs may change.


Development

git clone https://github.com/sughosh-pocketfm/kbask.git
cd kbask
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pytest

License

MIT — see LICENSE.

Built on top of graphifyy and @understand-anything/core. Their licenses apply to their respective components.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选