bgts-context-engine 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bgts_context_engine-0.2.1/CHANGELOG.md +92 -0
- {bgts_context_engine-0.2.0/src/bgts_context_engine.egg-info → bgts_context_engine-0.2.1}/PKG-INFO +45 -24
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/README.md +43 -22
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/README.tr.md +45 -23
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/pyproject.toml +3 -1
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/__init__.py +1 -1
- bgts_context_engine-0.2.1/src/bce/api/mcp/server.py +123 -0
- bgts_context_engine-0.2.1/src/bce/api/mcp/tools.py +286 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/cli.py +34 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/config.py +21 -1
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/logging.py +11 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/jobs/store.py +18 -5
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/jobs/worker.py +11 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1/src/bgts_context_engine.egg-info}/PKG-INFO +45 -24
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bgts_context_engine.egg-info/requires.txt +1 -1
- bgts_context_engine-0.2.0/CHANGELOG.md +0 -49
- bgts_context_engine-0.2.0/src/bce/api/mcp/server.py +0 -61
- bgts_context_engine-0.2.0/src/bce/api/mcp/tools.py +0 -262
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/LICENSE +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/MANIFEST.in +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/setup.cfg +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/mcp/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/app.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/deps.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/routes.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/schemas.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/static/assets/index-Cc4pUpSE.js +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/static/assets/index-DrLRaTMU.css +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/static/favicon.svg +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/static/index.html +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/ui/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/ui/queries.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/ui/router.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/ui/schemas.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/api/rest/ui/trace.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/bench/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/bench/runner.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/assembler/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/assembler/assembler.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/auth/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/auth/scope.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/coverage/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/coverage/confidence.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/i18n/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/i18n/catalogs/en.json +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/i18n/catalogs/tr.json +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/i18n/locale.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/i18n/translator.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/orchestrator/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/orchestrator/anchors.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/orchestrator/expand.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/orchestrator/orchestrator.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/scoring/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/core/scoring/engine.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/domain/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/domain/enums.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/domain/models.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/embedder/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/embedder/embedder.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/embedder/encoder.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/extractor/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/extractor/bridges.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/extractor/designnote.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/extractor/extractor.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/extractor/routes.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/gitsync/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/gitsync/bitbucket.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/gitsync/local.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/gitsync/remote.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/indexer.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/linker/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/linker/linker.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/_treesitter.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/base.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/languages/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/languages/csharp_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/languages/go_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/languages/java_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/languages/jsts_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/languages/python_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/registry.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/scip/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/scip/resolver.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/parser/symbol_id.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/upserter/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/indexing/upserter/upserter.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/jobs/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/graph/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/graph/client.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/graph/repository.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/db.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrations/0001_extensions_graph.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrations/0002_relational.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrations/0003_vector.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrations/0004_rls.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrations/0005_embeddings_dim.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrations/0006_fts.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrations/0007_jobs.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/migrator.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/relational/queries.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/vector/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/storage/vector/store.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/tools/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/tools/layer1/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/tools/layer1/primitives.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/tools/layer2/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/tools/layer2/search.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/tools/layer3/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bce/tools/layer3/orchestration.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bgts_context_engine.egg-info/SOURCES.txt +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bgts_context_engine.egg-info/dependency_links.txt +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bgts_context_engine.egg-info/entry_points.txt +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.1}/src/bgts_context_engine.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
|
6
|
+
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.1] - 2026-09-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Indexing over MCP: `index_repo` and `reindex_repo`, plus the read-only `get_index_job` and
|
|
15
|
+
`list_index_jobs`. Both write tools take a local working tree and enqueue a job rather than
|
|
16
|
+
indexing inline, because a full index outlives any agent's tool-call timeout. They are gated
|
|
17
|
+
behind `BCE_MCP_ALLOW_WRITE` (default off) and are neither advertised nor dispatchable while
|
|
18
|
+
it is off. With it on, the MCP process also runs job workers, so queued indexing progresses
|
|
19
|
+
without a separate `bce serve`; the pool claims `index` and `reindex` only, so a clone that
|
|
20
|
+
REST enqueued is not run inside an editor-spawned process. Cloning a remote repository is
|
|
21
|
+
deliberately not exposed over MCP: it carries its own credentials and stays on REST and the CLI.
|
|
22
|
+
- `JobWorkerPool(job_types=...)` and `claim_next_job(job_types=...)` restrict a pool to a subset
|
|
23
|
+
of the queue.
|
|
24
|
+
- `bce --env-file PATH` and `BCE_ENV_FILE` load configuration from an explicit `.env`. Editors
|
|
25
|
+
spawn `bce serve-mcp` from their own working directory, so a bare `.env` was never found and the
|
|
26
|
+
MCP server silently ran on defaults — no Voyage key, no database password. `serve` and
|
|
27
|
+
`serve-mcp` accept the option after the command name as well as before it, because that is how
|
|
28
|
+
an MCP config or a service definition is written.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- The MCP catalog is now eight read-only tools instead of fourteen. Removed `semantic_search`,
|
|
33
|
+
`find_similar_code`, `find_implementers`, `get_type_hierarchy`, `get_dependencies`,
|
|
34
|
+
`suggest_change_sites`, `select_repos` and `assemble_context`: an agent picks worse when
|
|
35
|
+
handed a dozen overlapping retrieval tools, and `hybrid_search` and `get_context_for_task`
|
|
36
|
+
already cover what they did. All of them remain available over REST.
|
|
37
|
+
- The optional `mcp` extra is now `mcp>=1.0,<2`. SDK 2.x dropped `Server.list_tools` /
|
|
38
|
+
`Server.call_tool`, so `bce serve-mcp` failed on a default `pip install` of 2.x.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- The first search on an MCP server no longer hangs. Building the embedding encoder imports
|
|
43
|
+
numpy, and loading that extension lazily from inside a tool call stalled for over three
|
|
44
|
+
minutes on Windows while the same import costs seconds at process start, so the encoder is
|
|
45
|
+
now built during startup. Tool dispatch also moved off the event loop onto a worker thread,
|
|
46
|
+
since its database and HTTP calls are synchronous.
|
|
47
|
+
- The MCP server configures logging, against stderr because stdout carries the protocol. Its job
|
|
48
|
+
worker's failures previously fell through to Python's last-resort handler and surfaced in editor
|
|
49
|
+
logs as bare tracebacks; they are now the same JSON lines the API server emits, and they reach
|
|
50
|
+
the log file too. `setup_logging(stream=...)` makes the console destination overridable.
|
|
51
|
+
|
|
52
|
+
## [0.2.0] - 2026-09-10
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Both READMEs now reference images, videos and sibling documents by absolute URL. PyPI
|
|
57
|
+
renders the long description outside the repository, so relative paths resolved to
|
|
58
|
+
nothing there: the banner was a broken image and every documentation link a dead one.
|
|
59
|
+
- Selecting `BCE_EMBEDDING_PROVIDER=voyage` without its API key no longer falls back to the
|
|
60
|
+
hashing encoder. Both that case and a missing `voyageai` package now raise
|
|
61
|
+
`EncoderConfigError`, which the CLI reports as a single line and the REST API as `503`.
|
|
62
|
+
A substituted encoder is not detectable by nearest-neighbour search, so it returned bad
|
|
63
|
+
anchors instead of an error. An unrecognised provider name is rejected the same way.
|
|
64
|
+
- Removed `Settings.voyage_ready`, whose "ready" no longer matched how the encoder is
|
|
65
|
+
chosen.
|
|
66
|
+
|
|
67
|
+
## [0.1.0] - 2026-09-08
|
|
68
|
+
|
|
69
|
+
First public release.
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- Deterministic retrieval pipeline: anchor discovery, graph expansion, scoring, narrowing
|
|
74
|
+
and context assembly, with coverage and confidence reporting.
|
|
75
|
+
- Code graph over PostgreSQL with Apache AGE and pgvector in a single database. Layer-3
|
|
76
|
+
results are filtered per user against the `scopes` table, resolved from the
|
|
77
|
+
`X-BCE-User` header.
|
|
78
|
+
- Tree-sitter indexing for Python, JavaScript and TypeScript, with optional grammars for
|
|
79
|
+
Java, C# and Go. Incremental re-indexing driven by `git diff`.
|
|
80
|
+
- Layer 1, 2 and 3 tool surfaces exposed over both REST and MCP.
|
|
81
|
+
- Web interface at `/ui`: a graph explorer and a player that replays each pipeline stage
|
|
82
|
+
for a given task. Ships inside the wheel; English by default with a Turkish catalog.
|
|
83
|
+
- `bce` command line interface: `migrate`, `index`, `index-remote`, `reindex`, `bench`,
|
|
84
|
+
`resolve-symbol`, `find-references`, `languages`, `serve` and `serve-mcp`.
|
|
85
|
+
- Benchmark harness reporting latency, recall, precision and determinism.
|
|
86
|
+
- Docker Compose deployment with PostgreSQL, Apache AGE and pgvector preconfigured.
|
|
87
|
+
- `server.json` manifest describing the stdio server for the official MCP registry.
|
|
88
|
+
|
|
89
|
+
[Unreleased]: https://github.com/bgts-ai-org/bgts-context-engine/compare/v0.2.1...HEAD
|
|
90
|
+
[0.2.1]: https://github.com/bgts-ai-org/bgts-context-engine/compare/v0.2.0...v0.2.1
|
|
91
|
+
[0.2.0]: https://github.com/bgts-ai-org/bgts-context-engine/compare/v0.1.0...v0.2.0
|
|
92
|
+
[0.1.0]: https://github.com/bgts-ai-org/bgts-context-engine/releases/tag/v0.1.0
|
{bgts_context_engine-0.2.0/src/bgts_context_engine.egg-info → bgts_context_engine-0.2.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bgts-context-engine
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Deterministic code-graph context engine for AI coding agents - PostgreSQL, Apache AGE and pgvector, over MCP and REST
|
|
5
5
|
Author: Oğuz Öztürk, Enes İyidil
|
|
6
6
|
Maintainer: BGTS
|
|
@@ -42,7 +42,7 @@ Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
|
42
42
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
43
43
|
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
44
44
|
Provides-Extra: mcp
|
|
45
|
-
Requires-Dist: mcp
|
|
45
|
+
Requires-Dist: mcp<2,>=1.0; extra == "mcp"
|
|
46
46
|
Provides-Extra: embed
|
|
47
47
|
Requires-Dist: voyageai>=0.3; extra == "embed"
|
|
48
48
|
Provides-Extra: langs
|
|
@@ -132,16 +132,30 @@ Then serve it:
|
|
|
132
132
|
|
|
133
133
|
```bash
|
|
134
134
|
bce serve # REST at :8000/docs, web UI at :8000/ui/
|
|
135
|
-
bce serve-mcp # MCP over stdio, for agents
|
|
135
|
+
bce serve-mcp # MCP over stdio, for agents (install the [mcp] extra; see below)
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
## Use it from your agent
|
|
139
139
|
|
|
140
|
-
The MCP surface is behind the `mcp` extra: `
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
The MCP surface is behind the `mcp` extra (Python MCP SDK 1.x: `mcp>=1.0,<2`). Install it
|
|
141
|
+
so `bce` is on the **user PATH**, not only inside a project `.venv`. Cursor and VS Code
|
|
142
|
+
spawn `bce serve-mcp` themselves and do not activate the venv:
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
```bash
|
|
145
|
+
pip install "bgts-context-engine[mcp]"
|
|
146
|
+
bce --version # must work in a new terminal, with no venv activated
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Every MCP client uses the same stdio command plus the database in the environment. Do not
|
|
150
|
+
leave `bce serve-mcp` running in a terminal for the editor: stdout is the protocol, so the
|
|
151
|
+
process stays silent, and the IDE starts its own copy.
|
|
152
|
+
|
|
153
|
+
After you add or change the MCP config, **restart Cursor or VS Code** (or Command Palette
|
|
154
|
+
→ “Developer: Reload Window”). The server should then show as enabled with eight tools (ten with indexing enabled).
|
|
155
|
+
Setup detail: [docs/mcp.md](docs/mcp.md).
|
|
156
|
+
|
|
157
|
+
**Cursor** — user config `~/.cursor/mcp.json` (applies to every project), or a project
|
|
158
|
+
`.cursor/mcp.json` that stays local (the directory is gitignored):
|
|
145
159
|
|
|
146
160
|
```json
|
|
147
161
|
{
|
|
@@ -155,31 +169,41 @@ database connection in the environment.
|
|
|
155
169
|
}
|
|
156
170
|
```
|
|
157
171
|
|
|
158
|
-
**
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**VS Code** — `.vscode/mcp.json`:
|
|
172
|
+
**VS Code** — user MCP settings, or a project `.vscode/mcp.json` (also gitignored):
|
|
165
173
|
|
|
166
174
|
```json
|
|
167
175
|
{
|
|
168
176
|
"servers": {
|
|
169
|
-
"bgts-context-engine": {
|
|
177
|
+
"bgts-context-engine": {
|
|
178
|
+
"type": "stdio",
|
|
179
|
+
"command": "bce",
|
|
180
|
+
"args": ["serve-mcp"],
|
|
181
|
+
"env": { "BCE_DB_HOST": "localhost", "BCE_DB_NAME": "bce" }
|
|
182
|
+
}
|
|
170
183
|
}
|
|
171
184
|
}
|
|
172
185
|
```
|
|
173
186
|
|
|
187
|
+
**Claude Code** — one command:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
191
|
+
```
|
|
192
|
+
|
|
174
193
|
**Claude Desktop** — same block as Cursor, in `claude_desktop_config.json`.
|
|
175
194
|
|
|
176
|
-
|
|
177
|
-
|
|
195
|
+
If `command: "bce"` stays disconnected, the editor cannot see `bce` on PATH. Install as
|
|
196
|
+
above, or skip a permanent install with `uvx`:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
"command": "uvx",
|
|
200
|
+
"args": ["--from", "bgts-context-engine[mcp]", "bce", "serve-mcp"]
|
|
201
|
+
```
|
|
178
202
|
|
|
179
203
|
Then ask your agent something that needs the repository rather than the file you have open:
|
|
180
204
|
*"what breaks if I change the session TTL?"* The agent calls `get_context_for_task`, and the
|
|
181
|
-
|
|
182
|
-
|
|
205
|
+
other tools in [docs/mcp.md](docs/mcp.md) let it drill from there — exact callers, the blast
|
|
206
|
+
radius of a change, the symbol behind a name — without guessing at file names.
|
|
183
207
|
|
|
184
208
|
## What comes back
|
|
185
209
|
|
|
@@ -265,7 +289,7 @@ The full formula, every weight, and the confidence thresholds are in
|
|
|
265
289
|
moves and reformatting, so history and embeddings stay valid.
|
|
266
290
|
- **One database.** Apache AGE and pgvector in the same PostgreSQL, so one query joins a
|
|
267
291
|
graph traversal, a vector search and a SQL filter — and one `pg_dump` backs up the index.
|
|
268
|
-
- **MCP and REST from one implementation.**
|
|
292
|
+
- **MCP and REST from one implementation.** A focused tool set over stdio, the same functions
|
|
269
293
|
over HTTP. Nothing to drift.
|
|
270
294
|
- **A UI that explains itself.** `/ui` ships in the wheel and replays a real retrieval call
|
|
271
295
|
stage by stage: anchors lighting up, expansion spreading, candidates scored and cut.
|
|
@@ -337,7 +361,7 @@ actually ask for reorders this list.
|
|
|
337
361
|
| [Architecture](docs/architecture.md) | the deterministic line, the three layers, indexing |
|
|
338
362
|
| [Retrieval](docs/retrieval.md) | anchors, expansion, every scoring weight, confidence |
|
|
339
363
|
| [Data model](docs/data-model.md) | node labels, edge types, tables, symbol identity |
|
|
340
|
-
| [MCP and API](docs/mcp.md) |
|
|
364
|
+
| [MCP and API](docs/mcp.md) | every tool and endpoint, MCP configuration, the CLI |
|
|
341
365
|
| [Languages](docs/languages.md) | what each parser extracts, and how to add one |
|
|
342
366
|
| [Deployment](docs/deployment.md) | configuration reference, jobs, backup, benchmarking |
|
|
343
367
|
| [Web interface](web/README.md) | developing the frontend |
|
|
@@ -368,6 +392,3 @@ rather than in an issue.
|
|
|
368
392
|
## License
|
|
369
393
|
|
|
370
394
|
[MIT](LICENSE) © BGTS.
|
|
371
|
-
|
|
372
|
-
Built by [Oğuz Öztürk](https://github.com/oztrkoguz) and
|
|
373
|
-
[Enes İyidil](https://github.com/enesiyidil).
|
|
@@ -79,16 +79,30 @@ Then serve it:
|
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
bce serve # REST at :8000/docs, web UI at :8000/ui/
|
|
82
|
-
bce serve-mcp # MCP over stdio, for agents
|
|
82
|
+
bce serve-mcp # MCP over stdio, for agents (install the [mcp] extra; see below)
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
## Use it from your agent
|
|
86
86
|
|
|
87
|
-
The MCP surface is behind the `mcp` extra: `
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
The MCP surface is behind the `mcp` extra (Python MCP SDK 1.x: `mcp>=1.0,<2`). Install it
|
|
88
|
+
so `bce` is on the **user PATH**, not only inside a project `.venv`. Cursor and VS Code
|
|
89
|
+
spawn `bce serve-mcp` themselves and do not activate the venv:
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
```bash
|
|
92
|
+
pip install "bgts-context-engine[mcp]"
|
|
93
|
+
bce --version # must work in a new terminal, with no venv activated
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Every MCP client uses the same stdio command plus the database in the environment. Do not
|
|
97
|
+
leave `bce serve-mcp` running in a terminal for the editor: stdout is the protocol, so the
|
|
98
|
+
process stays silent, and the IDE starts its own copy.
|
|
99
|
+
|
|
100
|
+
After you add or change the MCP config, **restart Cursor or VS Code** (or Command Palette
|
|
101
|
+
→ “Developer: Reload Window”). The server should then show as enabled with eight tools (ten with indexing enabled).
|
|
102
|
+
Setup detail: [docs/mcp.md](docs/mcp.md).
|
|
103
|
+
|
|
104
|
+
**Cursor** — user config `~/.cursor/mcp.json` (applies to every project), or a project
|
|
105
|
+
`.cursor/mcp.json` that stays local (the directory is gitignored):
|
|
92
106
|
|
|
93
107
|
```json
|
|
94
108
|
{
|
|
@@ -102,31 +116,41 @@ database connection in the environment.
|
|
|
102
116
|
}
|
|
103
117
|
```
|
|
104
118
|
|
|
105
|
-
**
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**VS Code** — `.vscode/mcp.json`:
|
|
119
|
+
**VS Code** — user MCP settings, or a project `.vscode/mcp.json` (also gitignored):
|
|
112
120
|
|
|
113
121
|
```json
|
|
114
122
|
{
|
|
115
123
|
"servers": {
|
|
116
|
-
"bgts-context-engine": {
|
|
124
|
+
"bgts-context-engine": {
|
|
125
|
+
"type": "stdio",
|
|
126
|
+
"command": "bce",
|
|
127
|
+
"args": ["serve-mcp"],
|
|
128
|
+
"env": { "BCE_DB_HOST": "localhost", "BCE_DB_NAME": "bce" }
|
|
129
|
+
}
|
|
117
130
|
}
|
|
118
131
|
}
|
|
119
132
|
```
|
|
120
133
|
|
|
134
|
+
**Claude Code** — one command:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
138
|
+
```
|
|
139
|
+
|
|
121
140
|
**Claude Desktop** — same block as Cursor, in `claude_desktop_config.json`.
|
|
122
141
|
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
If `command: "bce"` stays disconnected, the editor cannot see `bce` on PATH. Install as
|
|
143
|
+
above, or skip a permanent install with `uvx`:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
"command": "uvx",
|
|
147
|
+
"args": ["--from", "bgts-context-engine[mcp]", "bce", "serve-mcp"]
|
|
148
|
+
```
|
|
125
149
|
|
|
126
150
|
Then ask your agent something that needs the repository rather than the file you have open:
|
|
127
151
|
*"what breaks if I change the session TTL?"* The agent calls `get_context_for_task`, and the
|
|
128
|
-
|
|
129
|
-
|
|
152
|
+
other tools in [docs/mcp.md](docs/mcp.md) let it drill from there — exact callers, the blast
|
|
153
|
+
radius of a change, the symbol behind a name — without guessing at file names.
|
|
130
154
|
|
|
131
155
|
## What comes back
|
|
132
156
|
|
|
@@ -212,7 +236,7 @@ The full formula, every weight, and the confidence thresholds are in
|
|
|
212
236
|
moves and reformatting, so history and embeddings stay valid.
|
|
213
237
|
- **One database.** Apache AGE and pgvector in the same PostgreSQL, so one query joins a
|
|
214
238
|
graph traversal, a vector search and a SQL filter — and one `pg_dump` backs up the index.
|
|
215
|
-
- **MCP and REST from one implementation.**
|
|
239
|
+
- **MCP and REST from one implementation.** A focused tool set over stdio, the same functions
|
|
216
240
|
over HTTP. Nothing to drift.
|
|
217
241
|
- **A UI that explains itself.** `/ui` ships in the wheel and replays a real retrieval call
|
|
218
242
|
stage by stage: anchors lighting up, expansion spreading, candidates scored and cut.
|
|
@@ -284,7 +308,7 @@ actually ask for reorders this list.
|
|
|
284
308
|
| [Architecture](docs/architecture.md) | the deterministic line, the three layers, indexing |
|
|
285
309
|
| [Retrieval](docs/retrieval.md) | anchors, expansion, every scoring weight, confidence |
|
|
286
310
|
| [Data model](docs/data-model.md) | node labels, edge types, tables, symbol identity |
|
|
287
|
-
| [MCP and API](docs/mcp.md) |
|
|
311
|
+
| [MCP and API](docs/mcp.md) | every tool and endpoint, MCP configuration, the CLI |
|
|
288
312
|
| [Languages](docs/languages.md) | what each parser extracts, and how to add one |
|
|
289
313
|
| [Deployment](docs/deployment.md) | configuration reference, jobs, backup, benchmarking |
|
|
290
314
|
| [Web interface](web/README.md) | developing the frontend |
|
|
@@ -315,6 +339,3 @@ rather than in an issue.
|
|
|
315
339
|
## License
|
|
316
340
|
|
|
317
341
|
[MIT](LICENSE) © BGTS.
|
|
318
|
-
|
|
319
|
-
Built by [Oğuz Öztürk](https://github.com/oztrkoguz) and
|
|
320
|
-
[Enes İyidil](https://github.com/enesiyidil).
|
|
@@ -79,16 +79,30 @@ Ardından servis edin:
|
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
bce serve # :8000/docs adresinde REST, :8000/ui/ adresinde web arayüzü
|
|
82
|
-
bce serve-mcp # ajanlar için stdio üzerinden MCP
|
|
82
|
+
bce serve-mcp # ajanlar için stdio üzerinden MCP ([mcp] eki gerekir; aşağıya bakın)
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
## Ajanınızdan kullanma
|
|
86
86
|
|
|
87
|
-
MCP yüzeyi `mcp` ekinin arkasındadır: `
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
MCP yüzeyi `mcp` ekinin arkasındadır (Python MCP SDK 1.x: `mcp>=1.0,<2`). `bce` komutunu
|
|
88
|
+
yalnızca proje `.venv` içine değil, **kullanıcı PATH'ine** kurun. Cursor ve VS Code
|
|
89
|
+
`bce serve-mcp` sürecini kendileri başlatır; sanal ortamı etkinleştirmezler:
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
```bash
|
|
92
|
+
pip install "bgts-context-engine[mcp]"
|
|
93
|
+
bce --version # venv kapalı, yeni bir terminalde çalışmalı
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Her MCP istemcisi aynı stdio komutunu ve ortamındaki veritabanı bağlantısını kullanır.
|
|
97
|
+
Editör için terminalde `bce serve-mcp` açık bırakmayın: stdout protokoldür, bu yüzden
|
|
98
|
+
süreç sessiz kalır; IDE kendi kopyasını başlatır.
|
|
99
|
+
|
|
100
|
+
MCP yapılandırmasını ekledikten veya değiştirdikten sonra **Cursor veya VS Code'u
|
|
101
|
+
yeniden başlatın** (veya Komut Paleti → “Developer: Reload Window”). Sunucu sekiz araçla
|
|
102
|
+
(indeksleme açıkken on araçla) etkin görünmelidir. Ayrıntı: [docs/mcp.md](docs/mcp.md).
|
|
103
|
+
|
|
104
|
+
**Cursor** — her proje için kullanıcı yapılandırması `~/.cursor/mcp.json`, ya da yerelde
|
|
105
|
+
kalan bir proje `.cursor/mcp.json` (dizin gitignore'dadır):
|
|
92
106
|
|
|
93
107
|
```json
|
|
94
108
|
{
|
|
@@ -102,31 +116,42 @@ veritabanı bağlantısı.
|
|
|
102
116
|
}
|
|
103
117
|
```
|
|
104
118
|
|
|
105
|
-
**
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**VS Code** — `.vscode/mcp.json`:
|
|
119
|
+
**VS Code** — kullanıcı MCP ayarları, ya da proje `.vscode/mcp.json` (o da gitignore'dadır):
|
|
112
120
|
|
|
113
121
|
```json
|
|
114
122
|
{
|
|
115
123
|
"servers": {
|
|
116
|
-
"bgts-context-engine": {
|
|
124
|
+
"bgts-context-engine": {
|
|
125
|
+
"type": "stdio",
|
|
126
|
+
"command": "bce",
|
|
127
|
+
"args": ["serve-mcp"],
|
|
128
|
+
"env": { "BCE_DB_HOST": "localhost", "BCE_DB_NAME": "bce" }
|
|
129
|
+
}
|
|
117
130
|
}
|
|
118
131
|
}
|
|
119
132
|
```
|
|
120
133
|
|
|
134
|
+
**Claude Code** — tek komut:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
138
|
+
```
|
|
139
|
+
|
|
121
140
|
**Claude Desktop** — `claude_desktop_config.json` içinde Cursor ile aynı blok.
|
|
122
141
|
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
`"command": "bce"` bağlı kalmazsa editör PATH'te `bce` görmüyordur. Yukarıdaki gibi
|
|
143
|
+
kurun, ya da kalıcı kurulum olmadan `uvx` kullanın:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
"command": "uvx",
|
|
147
|
+
"args": ["--from", "bgts-context-engine[mcp]", "bce", "serve-mcp"]
|
|
148
|
+
```
|
|
125
149
|
|
|
126
150
|
Sonra ajanınıza, açık olan dosyayı değil deponun tamamını gerektiren bir şey sorun:
|
|
127
151
|
*"session TTL'i değiştirirsem ne bozulur?"* Ajan `get_context_for_task`'ı çağırır;
|
|
128
|
-
[docs/mcp.md](docs/mcp.md) içindeki
|
|
129
|
-
çağıranlar,
|
|
152
|
+
[docs/mcp.md](docs/mcp.md) içindeki diğer araçlar ise oradan devam etmesini sağlar — kesin
|
|
153
|
+
çağıranlar, bir değişikliğin etki alanı, bir adın arkasındaki sembol — dosya adlarını tahmin
|
|
154
|
+
etmeden.
|
|
130
155
|
|
|
131
156
|
## Ne döner
|
|
132
157
|
|
|
@@ -214,8 +239,8 @@ Formülün tamamı, her ağırlık ve güven eşikleri
|
|
|
214
239
|
Sembol kimlikleri dosya taşımalarından ve yeniden biçimlendirmeden sağ çıkar.
|
|
215
240
|
- **Tek veritabanı.** Apache AGE ve pgvector aynı PostgreSQL içinde; tek sorgu bir graf
|
|
216
241
|
gezinmesini, bir vektör aramasını ve bir SQL filtresini birleştirir.
|
|
217
|
-
- **Tek gerçeklemeden MCP ve REST.** stdio üzerinden
|
|
218
|
-
fonksiyonlar. Aralarında kayma olacak bir şey yok.
|
|
242
|
+
- **Tek gerçeklemeden MCP ve REST.** stdio üzerinden odaklı bir araç kümesi, HTTP üzerinden
|
|
243
|
+
aynı fonksiyonlar. Aralarında kayma olacak bir şey yok.
|
|
219
244
|
- **Kendini açıklayan bir arayüz.** `/ui` wheel içinde gelir ve gerçek bir getirme çağrısını
|
|
220
245
|
aşama aşama oynatır: çapaların yanması, genişlemenin yayılması, adayların skorlanıp
|
|
221
246
|
kesilmesi.
|
|
@@ -290,7 +315,7 @@ Tümü İngilizcedir.
|
|
|
290
315
|
| [Architecture](docs/architecture.md) | deterministik hat, üç katman, indeksleme |
|
|
291
316
|
| [Retrieval](docs/retrieval.md) | çapalar, genişletme, her skorlama ağırlığı, güven |
|
|
292
317
|
| [Data model](docs/data-model.md) | düğüm etiketleri, kenar tipleri, tablolar, sembol kimliği |
|
|
293
|
-
| [MCP and API](docs/mcp.md) |
|
|
318
|
+
| [MCP and API](docs/mcp.md) | her araç ve uç nokta, MCP yapılandırması, CLI |
|
|
294
319
|
| [Languages](docs/languages.md) | her parser'ın çıkardıkları ve yeni dil ekleme |
|
|
295
320
|
| [Deployment](docs/deployment.md) | yapılandırma referansı, işler, yedekleme, ölçüm |
|
|
296
321
|
| [Web interface](web/README.md) | arayüz geliştirme |
|
|
@@ -324,6 +349,3 @@ issue olarak değil, özel kanaldan bildirin.
|
|
|
324
349
|
## Lisans
|
|
325
350
|
|
|
326
351
|
[MIT](LICENSE) © BGTS.
|
|
327
|
-
|
|
328
|
-
[Oğuz Öztürk](https://github.com/oztrkoguz) ve
|
|
329
|
-
[Enes İyidil](https://github.com/enesiyidil) tarafından geliştirildi.
|
|
@@ -69,8 +69,10 @@ dev = [
|
|
|
69
69
|
"httpx>=0.27",
|
|
70
70
|
]
|
|
71
71
|
# Agent-native MCP surface (spec section 7). Optional: the REST API works without it.
|
|
72
|
+
# Pin below 2.x: the Python SDK 2.x removed Server.list_tools / Server.call_tool, which
|
|
73
|
+
# bce serve-mcp still uses.
|
|
72
74
|
mcp = [
|
|
73
|
-
"mcp>=1.0",
|
|
75
|
+
"mcp>=1.0,<2",
|
|
74
76
|
]
|
|
75
77
|
# Voyage AI embeddings (Phase 2). Optional: the hashing fallback works without it.
|
|
76
78
|
embed = [
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""MCP server wiring (optional ``mcp`` SDK).
|
|
2
|
+
|
|
3
|
+
Binds the SDK-independent tool catalog (:mod:`bce.api.mcp.tools`) to a real MCP server. The ``mcp``
|
|
4
|
+
package is an optional dependency; importing this module without it raises a clear error only when
|
|
5
|
+
you actually try to build/run the server, so the rest of the package (and tests) stay importable.
|
|
6
|
+
|
|
7
|
+
Each tool call opens a fresh database connection (single DB: graph + vector, P5), dispatches to the
|
|
8
|
+
core, and returns the deterministic envelope as JSON text content. Read tools roll back; the indexing
|
|
9
|
+
tools enqueue a job and commit.
|
|
10
|
+
|
|
11
|
+
Dispatch is synchronous (psycopg queries, and an HTTP call to the embedding provider), so it runs on a
|
|
12
|
+
worker thread rather than on the event loop that drives the stdio transport.
|
|
13
|
+
|
|
14
|
+
Indexing over MCP is opt-in via ``BCE_MCP_ALLOW_WRITE``. When it is on, this process also runs a job
|
|
15
|
+
worker pool, so queued indexing progresses without a separate ``bce serve``; the queue claims rows
|
|
16
|
+
with ``FOR UPDATE SKIP LOCKED``, so running both is safe. The pool claims only the job types the MCP
|
|
17
|
+
tools can enqueue, leaving remote clones to the API server.
|
|
18
|
+
|
|
19
|
+
Logging is configured against stderr. Without it the worker's failures fell back to Python's
|
|
20
|
+
last-resort handler, which prints a bare traceback; with it they are the same JSON lines the API
|
|
21
|
+
server emits, and they reach the log file too.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import json
|
|
27
|
+
import logging
|
|
28
|
+
import sys
|
|
29
|
+
from typing import Any
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def build_server(name: str = "bgts-context-engine") -> Any:
|
|
33
|
+
"""Construct an MCP ``Server`` exposing the BCE tool catalog. Requires the ``mcp`` package."""
|
|
34
|
+
try:
|
|
35
|
+
import anyio.to_thread # installed with mcp
|
|
36
|
+
from mcp.server import Server
|
|
37
|
+
from mcp.types import TextContent, Tool
|
|
38
|
+
except ModuleNotFoundError as exc: # pragma: no cover - depends on optional dep
|
|
39
|
+
raise RuntimeError(
|
|
40
|
+
"The 'mcp' package is required for the MCP server. Install it with: pip install mcp"
|
|
41
|
+
) from exc
|
|
42
|
+
|
|
43
|
+
from bce.api.mcp.tools import WRITE_TOOLS, available_tool_specs, dispatch_tool
|
|
44
|
+
from bce.config import get_settings
|
|
45
|
+
from bce.storage.relational.db import connection
|
|
46
|
+
|
|
47
|
+
allow_write = get_settings().mcp_allow_write
|
|
48
|
+
specs = available_tool_specs(allow_write=allow_write)
|
|
49
|
+
server = Server(name)
|
|
50
|
+
|
|
51
|
+
@server.list_tools()
|
|
52
|
+
async def _list_tools() -> list[Tool]: # pragma: no cover - requires SDK runtime
|
|
53
|
+
return [
|
|
54
|
+
Tool(name=tool, description=spec["description"], inputSchema=spec["schema"])
|
|
55
|
+
for tool, spec in specs.items()
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
def _dispatch_blocking(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
59
|
+
with connection() as conn:
|
|
60
|
+
try:
|
|
61
|
+
result = dispatch_tool(conn, name, arguments, allow_write=allow_write)
|
|
62
|
+
if name in WRITE_TOOLS:
|
|
63
|
+
conn.commit() # persist the queued job
|
|
64
|
+
else:
|
|
65
|
+
conn.rollback() # read-only tools never persist
|
|
66
|
+
except Exception:
|
|
67
|
+
conn.rollback()
|
|
68
|
+
raise
|
|
69
|
+
return result
|
|
70
|
+
|
|
71
|
+
@server.call_tool()
|
|
72
|
+
async def _call_tool(
|
|
73
|
+
name: str, arguments: dict[str, Any]
|
|
74
|
+
) -> list[TextContent]: # pragma: no cover
|
|
75
|
+
result = await anyio.to_thread.run_sync(_dispatch_blocking, name, arguments)
|
|
76
|
+
return [TextContent(type="text", text=json.dumps(result, ensure_ascii=False, default=str))]
|
|
77
|
+
|
|
78
|
+
return server
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _warm_encoder() -> None: # pragma: no cover - SDK runtime
|
|
82
|
+
"""Build the embedding encoder once, before serving, so no tool call pays for it.
|
|
83
|
+
|
|
84
|
+
The Voyage SDK imports numpy, and loading that extension lazily from inside a tool call stalls
|
|
85
|
+
for minutes on Windows, where the same import costs seconds at process start. A provider that is
|
|
86
|
+
misconfigured is not fatal: only the search tools need an encoder, and they already raise a clear
|
|
87
|
+
error per call, so the graph tools stay usable.
|
|
88
|
+
"""
|
|
89
|
+
from bce.indexing.embedder.encoder import build_default_encoder
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
build_default_encoder()
|
|
93
|
+
except Exception as exc:
|
|
94
|
+
logging.getLogger("bce.api.mcp").warning(
|
|
95
|
+
"embedding encoder unavailable; search tools will fail", extra={"detail": str(exc)}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def run_stdio(name: str = "bgts-context-engine") -> None: # pragma: no cover - SDK runtime
|
|
100
|
+
"""Run the MCP server over stdio (the common agent transport)."""
|
|
101
|
+
from mcp.server.stdio import stdio_server
|
|
102
|
+
|
|
103
|
+
from bce.api.mcp.tools import MCP_JOB_TYPES
|
|
104
|
+
from bce.config import get_settings
|
|
105
|
+
from bce.core.logging import setup_logging
|
|
106
|
+
|
|
107
|
+
# stdout carries the protocol, so logs go to stderr, which editors surface as server logs.
|
|
108
|
+
setup_logging(stream=sys.stderr)
|
|
109
|
+
|
|
110
|
+
server = build_server(name)
|
|
111
|
+
_warm_encoder()
|
|
112
|
+
pool = None
|
|
113
|
+
if get_settings().mcp_allow_write:
|
|
114
|
+
from bce.jobs.worker import JobWorkerPool
|
|
115
|
+
|
|
116
|
+
pool = JobWorkerPool(job_types=MCP_JOB_TYPES)
|
|
117
|
+
pool.start()
|
|
118
|
+
try:
|
|
119
|
+
async with stdio_server() as (read, write):
|
|
120
|
+
await server.run(read, write, server.create_initialization_options())
|
|
121
|
+
finally:
|
|
122
|
+
if pool is not None:
|
|
123
|
+
pool.stop()
|