Semcode について
Semcode は、複数の GitHub リポジトリを検索する開発者や AI クライアント向けのハイブリッド検索サーバーです。Tree-sitter でコードシンボルを解析し、ベクトル検索と BM25 を組み合わせます。Git のコミット履歴も任意でインデックス化できます。
主な機能
- 01GitHub リポジトリ横断のコード検索
- 02Tree-sitter によるコードシンボル解析
- 03セマンティックベクトルと BM25 の併用
- 04差分インデックスと古い項目の削除
- 05Git コミット履歴の任意インデックス化
活用シーン
- 01自然言語でコード実装を探す
- 02関数名やクラス名からコードを特定
- 03コミット記録や変更ファイルを検索
MCP 対応
MCP サーバーとして、検索とインデックス作成のツールをクライアントに公開し、小規模な HTTP API も提供します。HTTP、stdio、旧式の SSE 接続に対応します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
http://localhost:8090/mcpclaude mcp add --transport http semcode http://localhost:8090/mcp{"mcpServers":{"semcode":{"type":"http","url":"http://localhost:8090/mcp"}}}Cursor で開く{"servers":{"semcode":{"type":"http","url":"http://localhost:8090/mcp"}}}VS Code で開く{"mcpServers":{"semcode":{"type":"http","url":"http://localhost:8090/mcp"}}}{"mcpServers":{"semcode":{"serverUrl":"http://localhost:8090/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
semcode
config.yaml に記載した一連の GitHub リポジトリを対象に、コードのハイブリッドなセマンティック検索を提供する MCP(Model Context Protocol)サーバーです。Tree-sitter でシンボルを解析し、コードと git のコミット履歴の両方をインデックス化するため、AI クライアントは自然言語やシンボル名で検索できます。
ハイブリッド検索では、密な埋め込みと BM25 を組み合わせます。そのため、自然言語のクエリ(「注文イベントはどこで発行されますか?」)でも、シンボル名の検索(PlaceOrderRequest)でも、適切な結果を得られます。
掲載先:
仕組み
- 設定された GitHub リポジトリからソースファイルを取得します
- Tree-sitter を使ってコードシンボル(関数、クラス、メソッド、コンポーネント)を解析します
- シンボルごとに2 つの埋め込みを生成します。密なセマンティックベクトル(プラグイン可能なプロバイダー:デフォルトは Jina Code V2、または Voyage / OpenAI / Ollama)と、コード識別子のトークン(camelCase / snake_case をサブワードに分割)をキーとする BM25 の疎ベクトルです
- 両方を Qdrant に保存し、ハイブリッド検索で取得します。密な検索結果と疎な検索結果に Reciprocal Rank Fusion(RRF)を適用するため、自然言語のクエリでもシンボル名の検索でも、適切な結果を得られます
- オプションでコミット履歴を別の Qdrant コレクションにインデックス化します(密ベクトルのみ)
- MCP プロトコル(および小規模な HTTP API)を通じて、検索とインデックス化のツールを公開します
インデックス化は増分方式です。Git blob SHA が最後にインデックス化したバージョンと一致するファイルはスキップされます。存在しなくなったファイル(または解析結果がシンボル数 0 件のファイル)は自動的に削除されます。すべてを再度埋め込み化するには、force: true を渡してください。
詳しく知りたいですか?ブログをご覧ください!
ドキュメント
RAG システムの内部構造について詳しくは、 goodbyeplanet.github.io/semcode をご覧ください。
- 取り込みパイプライン — コードの検出、解析、埋め込み生成、保存の方法
- 密ベクトル — 埋め込みプロバイダーとテキストの方針
- 疎ベクトル — BM25 とコードトークナイザー
- RRF による検索 — ハイブリッド検索と MCP ツール
- 設定 — すべての環境変数と config.yaml
- 変更履歴 — コミットメッセージから生成されるリリース履歴
対応言語
ファイル拡張子またはファイル名から言語が自動検出されるため、設定は不要です。
Go、Java、Python、TypeScript / JavaScript(React)、Rust、C#、C、C++、Ruby、PHP、Kotlin、Scala、Swift、Dart、Bash、SQL、 Lua、R、Dockerfile、Docker Compose、Markdown、JSON、HTML、CSS、XML。
多くのパーサーは、必要に応じてフレームワークを認識します。Java/Kotlin の Spring ステレオタイプと HTTP ルート、Python の FastAPI/Pydantic、
C# の ASP.NET、Ruby の Rails、PHP の Laravel/Symfony、React/SwiftUI/Flutter のウィジェットなどに対応します。言語ごとの抽出処理の詳細は
server/parser/ をご覧ください。
セットアップ
前提条件: Python 3.12 以降、Docker、GitHub トークン
# Install dependencies
uv sync
# Copy environment file, then edit .env to set GITHUB_TOKEN
# (a fine-grained PAT with Contents: read on the target repos is sufficient)
cp .env.example .env
# Optional — only if you want curated/static services (see below for the alternative):
# copy the services config, then list the repositories you want indexed
cp config.example.yaml config.yaml
config.yaml でインデックスを作成するリポジトリを設定します。
services:
- name: my-service
github_repo: owner/repo
github_ref: main # optional, defaults to "main" — branch, tag, or commit SHA
root: src/main/java # optional — limit indexing to this subdirectory (useful for monorepos)
exclude: # optional — skip matching paths
- "**/vendor/**"
- "**/node_modules/**"
インデクサーは、認識される拡張子を持つすべてのファイルを自動的に検出してインデックスを作成します。root を使うと、共有リポジトリ内のサブディレクトリにサービスの対象を限定できます。また、exclude を使うと、インデックスの対象から除外するパス(テスト、ビルド成果物、生成コードなど)を指定できます。
数個を超えるリポジトリに拡張する場合: config.yaml は厳選された静的リストです。少数のサービスには適していますが、この方法で数百のリポジトリにインデックスを作成するには、数百件のエントリーを手作業で管理することになります。代替手段(または併用手段)として、POST /reindex はリポジトリの定義をインラインで受け取り、その場で登録できます。config.yaml へのエントリー追加は不要です。リポジトリを自動登録し、マージのたびにインデックスを再作成する、そのまま使えるワークフローについては、examples/github-actions/reindex-on-merge.yml を参照してください。詳細は、以下の HTTP API セクションをご覧ください。両方で名前が重複する場合は、常に config.yaml のエントリーが優先されます。
この方法で実行する場合、config.yaml は必要ありません。ファイルがない場合はエラーではなく、設定済みサービスがゼロとして扱われます。docker-compose.yaml もこの仕様に対応しています。デフォルトでは config.yaml をマウントしないため、make docker-up/make docker-up-jina は、アドホック登録のみのセットアップでもそのまま動作します。厳選したサービスも使いたい場合は、上記の手順で config.example.yaml を config.yaml にコピーし、代わりに -with-config ターゲットを使ってください。これらは docker-compose.config-yaml.yml を重ねてマウントを追加します。コマンドは make docker-up-with-config/make docker-up-jina-with-config です(または docker compose -f docker-compose.yaml -f docker-compose.config-yaml.yml up -d を直接実行してください)。docker-compose.yaml 自体のボリューム行は手動で編集しないでください。ホスト上に存在しない config.yaml をバインドマウントすると、パスが存在しない状態のままになるのではなく、そこに空のディレクトリが暗黙的に作成され、サーバーが動作しなくなります。これが発生した場合は、明確なエラーとして通知されます:CONFIG_PATH (...) is a directory, not a file。
1 つの GITHUB_TOKEN で、この方法でインデックスを作成するすべてのリポジトリを読み取れます。 config.yaml のエントリーが数個であれば、それらのリポジトリだけを対象とするきめ細かな PAT で問題ありません。しかし、組織全体での自己登録では、リポジトリはワークフローを追加するだけで登録できるため、新しいリポジトリが使い始めるたびに、PAT のリポジトリアクセスリストを別途更新する必要があります。組織全体(すべてのリポジトリ、Contents: read)にインストールした GitHub App なら、新しいリポジトリも自動的に対象となり、登録のたびにトークンを管理する必要はありません。
実行
埋め込みをローカルコンテナから取得するか、ホスト型プロバイダーから取得するかに応じて、2 通りの実行方法があります。どちらかを選んでください。
パス A — TEI 経由のローカル Jina(デフォルト、API キー不要):
make docker-up-jina
# or: docker-compose --profile jina up
パス B — ホスト型プロバイダー(Voyage / OpenAI)またはローカル Ollama:
# 1. In .env, set EMBEDDINGS_PROVIDER=voyage|openai|ollama and the relevant API key.
# 2. Then start without the jina profile:
make docker-up
# or: docker-compose up
厳選したサービスに config.yaml を使用していますか?該当する上記ターゲットの -with-config 版(make docker-up-with-config / make docker-up-jina-with-config)を使用してください。詳しくはセットアップセクションを参照してください。
⚠ デフォルトの
EMBEDDINGS_PROVIDERはjinaです。--profile jinaを指定せずに起動し、プロバイダーをデフォルトのままにすると、semcode は起動します(compose では Jina はrequired: falseです)が、最初の埋め込み呼び出しは接続エラーで失敗します。自動フォールバックはありません。
ヘルスチェックと永続ボリュームを有効にして起動するサービス:
| サービス | プロファイル | ポート | ボリューム | 用途 |
|---|---|---|---|---|
| Qdrant | 常時 | 6333(HTTP)、6334(gRPC) | qdrant_data | ベクトル DB |
| Jina Embeddings(TEI) | jina | 8087 | embeddings_cache | 埋め込みモデルサーバー |
| semcode MCP | 常時 | 8090 | -with-config 使用時に ./config.yaml を読み取り専用でマウント | MCP + HTTP サーバー |
MCP サーバーは空のコレクションで起動します。reindex MCP ツールを呼び出すか、POST /reindex を実行して初期インデックスを作成してください(以下を参照)。
AI クライアントの接続
サーバーの起動後、AI クライアントの接続先を http://localhost:8090/mcp に設定してください。
Claude Code(CLI)
claude mcp add --transport http semcode http://localhost:8090/mcp
その他の MCP クライアント(Claude Desktop、Cursor など) — クライアントの MCP 設定にエントリーを追加してください。
{
"mcpServers": {
"semcode": {
"transport": "http",
"url": "http://localhost:8090/mcp"
}
}
}
stdio 経由での接続
稼働中の HTTP サーバーを接続先に指定する代わりに、クライアントからサーバープロセスを直接起動し、stdin/stdout 経由で通信できます。この場合も、Qdrant に接続できること(例:docker-compose up qdrant)と、依存関係をインストールしたローカル Python 環境(uv sync)が必要です。
Claude Code(CLI)
claude mcp add semcode --transport stdio --env MCP_TRANSPORT=stdio -- uv run --directory /path/to/semcode python -m server.main
その他の MCP クライアント — クライアントの MCP 設定にエントリーを追加してください。
{
"mcpServers": {
"semcode": {
"command": "uv",
"args": ["run", "--directory", "/path/to/semcode", "python", "-m", "server.main"],
"env": {
"MCP_TRANSPORT": "stdio"
}
}
}
}
GITHUB_TOKEN、QDRANT_URL、埋め込みプロバイダーの変数は、引き続きプロジェクトディレクトリの .env から読み込まれます。uv run が自動的に読み込みます。
SSE 経由での接続
SSE は従来の MCP HTTP トランスポートであり、現在は
streamable-httpに置き換えられています。streamable-httpにまだ対応していないクライアントでのみ使用してください。新しいセットアップでは 上記のstreamable-httpのセットアップを使用してください。
.env(または環境変数)に MCP_TRANSPORT=sse を設定し、streamable-http と同じ方法でサーバーを起動します(make docker-up / make docker-up-jina、またはローカルで uv run python -m server.main)。サーバーは http://localhost:8090/sse に SSE エンドポイントを公開します。
Claude Code(CLI)
claude mcp add --transport sse semcode http://localhost:8090/sse
その他の MCP クライアント — クライアントの MCP 設定にエントリーを追加してください。
{
"mcpServers": {
"semcode": {
"transport": "sse",
"url": "http://localhost:8090/sse"
}
}
}
インデックス作成
インデックス作成パイプラインはシンボル指向です。各関数、クラス、メソッド、コンポーネントが、それぞれベクトル埋め込みと豊富なペイロードを持つ独立したチャンクになります。
- 検出 —
rootとexcludeのフィルターを適用して、github_refにあるリポジトリ内のすべてのファイルを一覧表示します - 変更検出 — ファイルの Git blob SHA を前回のインデックス値と比較し、変更されていないファイルはスキップします
- 解析 — Tree-sitter が AST を走査し、言語ごとに
CodeSymbolオブジェクトを出力します - 密ベクトル埋め込み用テキスト — 言語ラベル、シンボルの種類、親クラス、パッケージ、フレームワーク固有の追加情報(Spring のステレオタイプ、HTTP ルート、Lombok、React memo)、ドキュメンテーション文字列、シグネチャ、ソースコード(ソースコードは
EMBEDDING_MAX_CHARSで切り詰めます。プロバイダーに応じたデフォルト値については、docs/configuration.md を参照してください) - スパース(BM25)埋め込み用テキスト — シグネチャ、ドキュメンテーション文字列、ソースコード。トークン化の前にコード識別子をサブワード(camelCase、snake_case)に分割するため、
getUserByIdは全体のトークンに加えて、get、user、by、idとしてもインデックス化されます - バッチ処理 — 密ベクトルのプロバイダーは 32 件(Jina/TEI、Ollama)または 128 件(Voyage、OpenAI)単位でバッチ処理します。BM25 はプロセス内で実行されます
- アップサート — 両方のベクトルを Qdrant の 1 つのポイントに格納します。決定論的な UUID(サービス/ファイル/シンボル/行ごと)をキーとして使用します
- クリーンアップ — リポジトリに存在しなくなったファイル(または解析結果のシンボル数が 0 になったファイル)のエントリを削除します
Git 履歴のインデックス作成は独立したオプションのパイプラインで、コミットメッセージと変更されたファイルパスを埋め込み、git_commits コレクションに格納します。完全な統合差分はペイロードに保存され、get_commit ツールで取得できます。サービスごとのコミット数は GIT_HISTORY_MAX_COMMITS によって制限されます(デフォルトは 500)。
テスト
uv sync --group dev
uv run pytest
テストは tests/ 配下にあります。
tests/parser/test_*.py— 言語ごとに 1 ファイルを用意し、tests/fixtures/<language>/の標準フィクスチャを使ってパーサーの動作をスナップショットテストしますtests/test_pipeline.py、tests/test_store.py、tests/test_git_history.py— インデックス作成パイプラインと Qdrant ストアの統合テストtests/test_reindex_route.py— HTTP ルートのテスト
MCP ツール
| ツール | 説明 |
|---|---|
search_code | クエリによるハイブリッド検索(高密度検索+BM25)。言語、サービス、シンボルの種類で任意に絞り込めます |
find_symbol | 名前でシンボルを検索します。完全一致、または exact=false の場合は大文字と小文字を区別しないトークン一致で検索します |
find_usages | 指定したシンボル名を参照するコードを検索します(セマンティック検索後、定義自体を除外します) |
get_code_context | GitHub からファイル全体、またはファイル内の特定のシンボルのソースを直接取得します |
reindex | 1 つまたはすべてのサービスのコードインデックス作成を開始します(デフォルトでは差分更新。再埋め込みには force を指定します) |
index_history | Git のコミット履歴をインデックス化します。不足しているコミットの差分は自動的に取得します |
search_commits | 自然言語で Git のコミット履歴を検索します |
get_commit | 変更されたファイルや差分を含む、特定のコミットの詳細を取得します |
list_indexed_services | インデックス化されたサービスについて、チャンク数、ファイル数、言語、最終インデックス作成時刻を一覧表示します |
index_stats | Qdrant コレクションの統計情報と設定済みのサービスを表示します |
find_symbol(exact=false) は、シンボル名の camelCase/snake_case トークンを対象にした全文検索インデックスを照合するため、
order または ord を使えば、コレクションのサイズに関係なく約 2 ms で placeOrderRequest が見つかります。トークンの途中の文字列(rder)でも
一致しますが、その場合はクライアント側でコレクションのサイズに比例する線形スキャンにフォールバックします。このフィールドが存在する前にインデックス化されたコレクションは、
再インデックス化されるまで同じフォールバックを使います。また、変更検出では変更のないファイルをスキップするため、このフィールドを
設定するには force 再インデックス化(POST /reindex {"force": true})が必要です。これにより、すべてのシンボルが再埋め込みされます。docs/retrieval-rrf.md を参照してください。
MCP プロンプト
| プロンプト | 引数 | 説明 |
|---|---|---|
service_overview | service | クライアントがサービスのアーキテクチャ概要を作成できるように案内します。HTTP エントリーポイント、ドメイン型、特筆すべきフレームワークの規約を取り上げます |
system_design_overview | (なし) | クライアントがシステム設計の全体概要を作成できるように案内します。サービス一覧、通信トポロジー、共有データストア、横断的な関心事を取り上げ、Mermaid 図も含みます |
HTTP API
MCP ツールに加えて、サーバーは CI/CD や外部スケジューラーからインデックス作成を開始するための HTTP エンドポイントを 2 つ公開しています。
| エンドポイント | 本文 | 説明 |
|---|---|---|
POST /reindex | {"service": "<name>"?, "force": <bool>?, "github_repo": "<owner/repo>"?, "github_ref": "<ref>"?, "root": "<path>"?, "exclude": [<glob>, ...]?} | 1 つまたはすべてのサービスのインデックスを再作成します — NDJSON を返します |
POST /reindex-history | {"service": "<name>"?, "force": <bool>?} | Git のコミット履歴をインデックス化します — NDJSON を返します |
すべての本文は省略可能です。すべてのサービスを対象にするには service を省略し、差分インデックスを行うには force を省略します。
どちらのエンドポイントも 改行区切り JSON(1 行につき 1 フレーム)をストリーミングするため、CI/CD パイプラインやその他のクライアントから進捗をリアルタイムで取得できます。
config.yaml を使わずにリポジトリを登録する場合: POST /reindex の本文に github_repo が含まれていると、インデックス作成の実行前に、そのリポジトリ定義で service 名が登録されます(登録内容は永続化されるため、再起動後も保持され、以降は config.yaml のサービスと同様に動作します)。この場合、service は必須です。
github_ref のデフォルトは main です。root/exclude は config.yaml の同じフィールドに対応します。config.yaml ですでに定義されている service 名は、この方法で登録したものより常に優先されます。このエンドポイントには認証がありません(ほかの /reindex と同様です)。公開する前に、独自のネットワーク境界の内側に配置してください。すぐに使えるワークフローについては、
examples/github-actions/reindex-on-merge.yml を参照してください。
フレームの形式:
// in-flight progress
{"type": "progress", "phase": "discovery|upserting|cleanup", "current": 12, "total": 200, "percentage": 6.0, "service": "my-service"}
// final summary (one per request)
{"type": "done", "result": {"files": 42, "chunks": 318, "skipped": 5}}
// emitted instead of "done" on failure
{"type": "error", "message": "..."}
/reindex では、upserting フレームの current は、解決済みファイル数(インデックス化、変更なしのためスキップ、またはフェッチ/解析エラーによる除外)を単調増加する値として示すため、最終的に必ず total に達します。ファイルは並行してインデックス化されるため、フレームはファイルごとではなくバッチごとに出力されます。
/reindex-history では、phase の値は discovery|embedding|upserting で、done の結果は {"new": int, "skipped": int, "diff_updated": int} です。
環境変数
| 変数 | デフォルト値 | 説明 |
|---|---|---|
GITHUB_TOKEN | (必須) | リポジトリの読み取りアクセス権を持つ GitHub トークン |
GITHUB_API_URL | https://api.github.com | GitHub API のルート。GitHub Enterprise Server では https://<host>/api/v3 を使用します |
QDRANT_URL | http://localhost:6333 | Qdrant 接続 URL |
QDRANT_COLLECTION | code_symbols | コードシンボルベクトルのコレクション名 |
QDRANT_COMMITS_COLLECTION | git_commits | コミットメッセージベクトルのコレクション名 |
EMBEDDINGS_PROVIDER | jina | jina、jina-api、voyage、openai、ollama のいずれかです。下記の 埋め込みプロバイダー を参照してください |
GIT_HISTORY_MAX_COMMITS | 500 | サービスごとにインデックス化するコミットの最大数 |
CODE_CONTEXT_CACHE_SIZE | 128 | get_code_context 用にメモリにキャッシュするファイル数(blob SHA をキーにします)。0 で無効になります |
CODE_CONTEXT_CACHE_TTL | 900 | キャッシュされたファイルの内容が有効な状態を保つ秒数 |
MCP_TRANSPORT | streamable-http | streamable-http、sse、stdio のいずれかです |
MCP_HOST / MCP_PORT | 127.0.0.1 / 8090 | サーバーのバインドアドレス |
MCP_STATELESS_HTTP | true | セッション追跡なしで streamable-http を提供します(スティッキーセッションは不要です)。false にすると、クライアントごとの MCP セッションが復元されます。streamable-http のみ |
CONFIG_PATH | ./config.yaml | サービス設定ファイルのパス |
埋め込みプロバイダー
埋め込みバックエンドは EMBEDDINGS_PROVIDER で選択できます。デフォルトは jina で、既存のデプロイメントは変更なしで引き続き動作します。各プロバイダーは設定されたモデルに基づいて独自にベクトルの次元数を決定するため、手動で次元数を設定する必要はありません。ただし、上書きする場合は設定できます。
| 変数 | デフォルト | 適用対象 | 説明 |
|---|---|---|---|
JINA_URL | http://localhost:8087 | jina | TEI のベース URL |
JINA_MODEL | jinaai/jina-embeddings-v2-base-code | jina | 情報表示用のみです。実際に読み込まれるモデルは、TEI コンテナーの --model-id フラグで指定します。モデルを変更するには docker-compose.yaml を編集してください。 |
JINA_DIMENSIONS | 768 | jina | TEI モデルのベクトル次元数 |
JINA_API_KEY | (required if provider=jina-api) | jina-api | Jina AI API キー(api.jina.ai のホスト型エンドポイント) |
JINA_API_MODEL | jina-embeddings-v2-base-code | jina-api | ホスト型 Jina モデル。jina-code-embeddings-0.5b、jina-code-embeddings-1.5b もサポートしています |
JINA_API_DIMENSIONS | (native) | jina-api | Matryoshka の任意の上書き設定(code-embeddings モデルは縮小をサポート)。ネイティブのデフォルト値がないモデルでは必須です |
VOYAGE_API_KEY | (required if provider=voyage) | voyage | Voyage AI API キー |
VOYAGE_URL | https://api.voyageai.com/v1/embeddings | voyage | Embeddings エンドポイントの上書き設定(Voyage プロトコルに準拠する必要があります) |
VOYAGE_MODEL | voyage-code-3 | voyage | Voyage の埋め込みモデル |
VOYAGE_DIMENSIONS | (native) | voyage | 任意の上書き設定。Voyage code-3 は 256 / 512 / 1024 / 2048 をサポートしています |
OPENAI_API_KEY | (required if provider=openai) | openai | OpenAI API キー |
OPENAI_URL | https://api.openai.com/v1/embeddings | openai | Embeddings エンドポイントの上書き設定(OpenAI プロトコルに準拠する必要があります) |
OPENAI_EMBEDDING_MODEL | text-embedding-3-large | openai | OpenAI の埋め込みモデル |
OPENAI_DIMENSIONS | (native) | openai | 任意の上書き設定(text-embedding-3-* モデルは縮小をサポート) |
OLLAMA_URL | http://localhost:11434 | ollama | Ollama のベース URL |
OLLAMA_MODEL | nomic-embed-text | ollama | Ollama の埋め込みモデル |
OLLAMA_DIMENSIONS | (native) | ollama | 組み込みの次元数テーブルにないモデルを使用する場合は必須です |
voyage-code-3 はほとんどのコード検索ベンチマークで jinaai/jina-embeddings-v2-base-code を上回っているため、Voyage への切り替えは柔軟性だけでなく、品質を高める手段でもあります。 |
既存のインデックスでプロバイダーを切り替える場合: 新しいプロバイダーのベクトルサイズが既存の Qdrant コレクションと異なると、起動時にサーバーがすぐにエラーを返し、問題のあるコレクションを明示します。切り替えるには、Qdrant の UI または API から両方のコレクション(code_symbols と git_commits)を削除してから、再インデックスしてください。自動移行には対応していません。
ホステッド環境のみでのセットアップ(ローカル TEI コンテナなし): .env で EMBEDDINGS_PROVIDER と該当する API キーを設定し、jina プロファイルを指定せずに起動します(docker-compose up / make docker-up)。jina-embeddings コンテナは起動しません。
Qdrant コレクション
code_symbols — パースされたシンボルごとに 1 つのポイントがあり、名前付きベクトルを2 つ持ちます。
text-dense— コサイン距離、HNSW(m=16、ef_construct=128)、サイズは埋め込みプロバイダーによって決まりますtext-sparse— コード識別子のサブワードトークンに対する BM25、インメモリのスパースインデックス
search_code は Qdrant の query_points 呼び出しと FusionQuery(fusion=RRF) を使用して、両方を検索します。インデックス化されたペイロードフィールド(language、service、symbol_type、chunk_tier、parent_name、file_path)はフィルターとして使用できます。search_code と find_symbol では chunk_tier("method" または "class")を直接指定できるため、クエリの対象をクラスまたはメソッドのみに絞り込めます。ペイロード全体には、signature、docstring、annotations、package、start_line、end_line、file_hash、indexed_at に加えて、言語固有の追加フィールド(http_method、http_route、spring_stereotype、lombok_annotations、is_async、uses_memo など)も含まれます。
git_commits — コミットごとに密ベクトルのみを 1 つ持ちます(コサイン距離、HNSW m=16 / ef_construct=128)。ペイロードには sha、service、message、author_name、author_email、committed_at、indexed_at、has_diff、diff_truncated、および files(変更されたファイルの配列。filename、status、additions、deletions、patch を含む)が含まれます。sha、service、author_name、has_diff はインデックス化されたペイロードフィールドです。
バージョン管理とリリース
バージョンの定義は1 か所のみです。pyproject.toml の version です。server/main.py は importlib.metadata.version("semcode") を通じてその値を読み取り、MCP の serverInfo.version として報告します。そのため、クライアントには常に実際に実行中のパッケージのバージョンが表示されます。
このバージョンを手動で編集しないでください。 リリースは release-please(.github/workflows/release.yml)で自動化されています。
- Conventional Commits に従ってコミットを
mainに反映します。 - release-please が
chore(main): release X.Y.Zという PR を作成(または更新)し、pyproject.tomlのバージョンを更新して、コミットメッセージからCHANGELOG.mdを生成します。 - その PR をマージすると、コミットに
vX.Y.Zのタグが付けられ、GitHub Release が作成されます。人間がマージするまでリリースされることはありません。
現在、リリースで作成されるのはソースと生成された変更履歴を含む GitHub Releaseです。PyPI には公開されず、コンテナイメージもプッシュされません。semcode は引き続き Dockerfile からローカルでビルドされます。
コミットの種類とバージョンの更新
| コミットのプレフィックス | 更新 | 変更履歴のセクション |
|---|---|---|
feat!: / BREAKING CHANGE: | メジャー | ⚠ 破壊的変更 |
feat: | マイナー | 機能 |
fix: | パッチ | バグ修正 |
perf: | パッチ | パフォーマンスの改善 |
deps: | パッチ | 依存関係 |
refactor: | パッチ | コードのリファクタリング |
docs: test: style: chore: ci: build: | パッチ | 非表示 |
Dependabot は deps プレフィックスを使用するように設定されているため(.github/dependabot.yml)、1 週間分の依存関係の更新でもパッチリリースが作成され、どの依存関係の組み合わせがまとめてテストされたかが示されます。
メジャー更新は、MCP ツールのシグネチャまたは設定スキーマに対する破壊的変更に限られます。これらはクライアントとデプロイ環境が依存するインターフェースです。
補足
mainのコミットメッセージがすべてを決定するため、スカッシュマージのタイトルは適切な Conventional Commits 形式にする必要があります。リポジトリでは 「スカッシュマージでは PR タイトルをデフォルトにする」 を有効にしてください。- リリース PR は
GITHUB_TOKENで作成されます。仕様上、これによって他のワークフローは起動されないため、リリース PR 自体では CI は再実行されません。リリース対象のコミットは、すでにmainでテスト済みです。
プロジェクトの構成
server/
├── main.py # MCP server entry point + lifespan
├── config.py # Settings and service configuration
├── state.py # Shared store singletons
├── parser/ # Tree-sitter parsers (Go, Java, Python, TypeScript, Rust, C#, C, C++, Ruby, PHP, Kotlin, Scala, Swift, Dart, Bash, SQL, Lua, R, Dockerfile, Compose, Markdown, JSON, HTML, CSS, XML)
├── embeddings/ # Pluggable dense providers (Jina/Voyage/OpenAI/Ollama) + BM25 sparse + code identifier tokenizer
├── indexer/ # GitHub fetcher, code indexing pipeline, git history pipeline
├── store/ # Qdrant vector stores (code_symbols hybrid + git_commits dense)
├── tools/ # MCP tool implementations (search, index, history, admin)
├── prompts/ # MCP prompt templates (service_overview, system_design_overview)
└── routes/ # HTTP routes (reindex, reindex-history)
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。