---
title: "Historical Decisions"
weight: 11
description: "For subsequent developers, maintainers, and AI Agents: records of important project decisions and discussion conclusions."
---

# Historical Decisions

> Note: The development team prioritizes maintaining the Chinese documentation. The English version is updated as much as possible, but may lag behind. If there are discrepancies between the Chinese and English versions, the Chinese version shall prevail.

> This document is for subsequent developers, maintainers, and AI Agents. If you plan to add new features, modify existing behavior, or open a new issue, please read this document first to avoid repeating discussions on issues that have already been closed or concluded.

This document is jointly maintained by Agents and humans. Questions are used as headings, answers as content, and each decision is accompanied by the corresponding issue / commit evidence. You may hand this document to a long-context large model for analysis.

## If You Want to Open a New Issue

~~Please check first:~~

~~1. Does your suggestion conflict with any historical decision in this document?~~
~~2. Can you provide new evidence (measured data, specific scenarios, error logs) showing that a historical decision needs to be revisited?~~
~~3. Does your suggestion align with the project's core positioning of "single binary, zero dependencies, precise editing"?~~

The above was generated by a large model. To gather more information, any friendly question is welcome in the discussion.

For any (yes, any) related issue mentioned below, you are welcome to open an issue to join the discussion. GitHub also allows opening an issue against a specific line. We look forward to any information you can provide that we don't yet know to make this tool more efficient and usable.

If you simply want to reopen a closed issue, please explicitly reference the historical issue number in the new issue and explain why the situation is different now.

{{< issue title="Feedback: Historical Decisions" body="Please describe the problem you found, the historical decision you want to discuss, or any new evidence." text="📝 Create an issue for this document" >}}

---

## I Want to Add `be-batch` / Batch Editing Tool

Based on [issue #13](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/13),
[#24](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/24),
[#35](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/35),
[#54](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/54), and commit `8ae2b2f`,
we decided **not to keep the `be-batch` MCP tool**.

Reasons:

- `be-batch`'s `spec` is a JSON string rather than structured parameters, making it very easy for models to make mistakes when constructing the JSON string (tool confusion).
- We tested this tool on an Agent (Hermes): all 3 calls failed, all stuck on constructing the JSON string in the spec.
- The same scenarios can be completed serially with `be-read` / `be-replace` / `be-insert` / `be-write`; the lower-level tools cover everything batch was originally meant to do in actual workflows.
- In a single tool call, the model can initiate multiple function calls, so there is no need to stuff all operations into one JSON string.

Therefore, residual `be-batch` descriptions in the README and Go API documentation were cleaned up in v0.11.0
([#54](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/54)).

If you really need batch editing, please use a combination of single tools, or consider orchestrating with scripts in CLI mode (CLI subcommands were provided in v0.11.0).


{{< issue title="Feedback: I Want to Add `be-batch` / Batch Editing Tool" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Simplify or Extend `be-delete` / `be-insert` Parameters

Based on [issue #35](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/35) and commit `8ae2b2f`, we decided to **keep parameters minimal and not easily add aliases**.

Current conventions:

- `be-delete`: only `start` / `end` + `target` are kept; aliases such as `start_line` / `end_line` / `line` / `lines` have been removed.
- `be-insert`: only `after_line` is kept (`--after-line` in CLI, with `--after` compatibility); the `line` parameter with implicit -1 conversion has been removed.

Reasons:

- Too many ways to express the same thing causes tool confusion for the model
  (the core view of [issue #35](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/35)).
- More parameter aliases increase maintenance costs for documentation, tests, and schemas.

If you want to add new parameter aliases, you need very strong evidence that the current parameters frequently cause model errors and that the new parameters can significantly reduce the error rate.


{{< issue title="Feedback: I Want to Simplify or Extend `be-delete` / `be-insert` Parameters" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Make Tool Names Shorter or Rename Them

Based on [issue #2](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/2), we decided
**tool names should uniformly use the `be-` prefix** and remain stable.

Current tool names:

- `be-read`, `be-replace`, `be-insert`, `be-delete`, `be-write`
- `be-balance`, `be-func-range`, `be-tag-range`
- `be-trx-commit`, `be-trx-rollback`, `be-trx-status`
- `be-insert-chip`

Reasons:

- A unified prefix makes names shorter and easier for models to read and select.
- Tool names are part of the external protocol; renaming is a breaking change and requires updating documentation and all callers.
- The project README states it is "experimental", but meaningless renaming should be avoided going forward.

Because implementation on the large-model side is not very standardized, directly integrating this tool via MCP shows many possibilities, such as...

- `be-read` (directly written into the tool list)
- `mcp_better_edit_tools_be_read` (Hermes behavior)
- `better-edit-tools_be-read` (OpenCode behavior)

Other acquisition methods are fine but the names are still long. We worry that if an agent does not deliberately distinguish them, `be-read` may conflict with the agent's built-in read tool, so we intentionally added this prefix.

**Update (v0.13.0)**: Per [issue #56](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/56), a `--no-prefix` CLI option has been added. When enabled, tool names returned by `tools/list` have the `be-` prefix stripped (e.g., `be-read` → `read`), and `tools/call` automatically prepends `be-` before dispatching unprefixed names. This resolves the issue where some Agent MCP controllers cannot re-edit tool names through configuration.

If you want to rename, please explain in the issue: what specific problem the current name causes, how much confusion the new name can reduce, and whether it is worth a breaking change (although we have not reached a major version > 0, we still cautiously value compatibility to avoid updates affecting extensibility)... at least provide users with a convenient migration guide.


{{< issue title="Feedback: I Want to Make Tool Names Shorter or Rename Them" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Add Formatting / Type Checking / Test Hook Post-Processing

Based on the discussion in [issue #1](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/1), we decided
**not to introduce post-edit validation hooks that depend on the external environment**.

Reasons:

- Formatting (gofmt, prettier, etc.), type checking, and test execution all rely on external toolchains and language runtimes.
- Introducing these would significantly increase project complexity and coupling, violating the design goal of "single binary, zero dependencies".
- This work is better left to the Agent workflow itself or the toolchain on the MCP client side.

If you want to add some validation, please explain why it must be completed inside better-edit-tools rather than by the caller.


{{< issue title="Feedback: I Want to Add Formatting / Type Checking / Test Hook Post-Processing" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Externalize Tool Descriptions / InputSchema

Based on [issue #48](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/48), we decided
**not to externalize tool metadata to configuration files at this stage**. Based on
[issue #49](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/49), we decided
**not to implement runtime tool override / disable mechanisms**.

Reasons:

- Currently there are only 8 tools; InputSchema and descriptions do not change frequently and are not large in scale, so complex runtime configuration is unnecessary.
- Externalization would add loading validation, backward compatibility, and distribution complexity; the benefits do not outweigh the costs.
- The project is still experimental and tool parameters may continue to be adjusted; building complex configuration mechanisms too early is over-engineering.
- Disabling core tools may break LLM workflows (for example, disabling `be-read` would invalidate the `viewed_code_id` mechanism), and some parameters may then be incomprehensible to large models.
- This is over-engineering and does not match the project's current stage.

As a compromise, v0.11.0 externalized **translation copy** to `internal/server/i18n/*.json` and embedded it via `//go:embed`
([#52](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/52)), so changing copy no longer requires modifying Go source code, but schemas remain in the code.

If you want to choose between externalization and built-in, please explain in the issue: what specific maintenance pain points you encounter and how much additional complexity you are willing to take on.


{{< issue title="Feedback: I Want to Externalize Tool Descriptions / InputSchema" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Refactor `listTools` into a Factory Pattern

Based on [issue #50](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/50), we decided
**not to refactor `listTools` into a Tool Factory**.

Reasons:

- With [#48](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/48) and
  [#49](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/49) closed, the main benefit of the factory pattern (supporting externalized configuration) no longer exists.
- Tool definitions in `server.go` are centralized but the scale is manageable; changing to a factory pattern would add unnecessary abstraction.
- Keeping it simple and direct better matches the project's current stage.

If the number of tools increases significantly in the future or multiple schema sets need to be supported, this can be re-evaluated.


{{< issue title="Feedback: I Want to Refactor `listTools` into a Factory Pattern" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Deeply Integrate Transactions / Snapshots with the Editing Workflow

Based on [issue #53](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/53), we decided
**not to over-emphasize transaction / snapshot workflows in tool descriptions**.

Reasons:

- `be-trx-rollback` relies on an in-memory snapshot queue; its reliability is affected by external factors (for example, rollback may be inconsistent after files are modified externally).
- The snapshot queue has a `MaxSnapshots = 30` capacity limit and deletes the oldest snapshots, so returned event_ids may expire quickly.
- Over-promising the reliability of rollback would mislead LLMs.
- Current tool descriptions already include basic functional explanations; keeping the status quo is sufficient.

If you want to improve the transaction mechanism, we suggest solving snapshot persistence / cross-process issues first rather than changing descriptions.


{{< issue title="Feedback: I Want to Deeply Integrate Transactions / Snapshots with the Editing Workflow" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Add `be-apply` or Atomic Multi-File Editing

Based on [issue #24](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/24), we decided
**not to implement the `be-apply` tool**, and plan to revisit it with a completely different design of "single-call two-phase commit" when needed.

Reasons:

- The `be-apply` proposal overlapped with `be-batch`, and `be-batch` was about to be removed at that time.
- Atomic multi-file editing is complex and requires a new design approach; it is not a simple extension of existing tools.

If you have a strong need for this, please first explain why your scenario cannot be met by existing tool combinations + snapshot rollback.


{{< issue title="Feedback: I Want to Add `be-apply` or Atomic Multi-File Editing" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Add CLI Subcommands / I Want Dedicated Integration for Pi Agent

Based on [issue #55](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/55), we decided
**to add CLI subcommands for the 8 core editing tools** (v0.11.0). This was also a new feature decision made after we started using Pi Agent and found it does not officially support MCP; however, we still **cannot provide dedicated integration for Pi** (mainly due to the cross-language differences between Golang and TypeScript), but you can improve it in the form of skills or high-level CLI commands. Better proposals are welcome via issue.

Implemented commands:

- For editing text: `read`, `replace`, `insert`, `delete`, `write`
- For identifying text content: `balance`, `func-range`, `tag-range`

Design highlights:

- Without subcommands, it still starts the MCP server for compatibility.
- No external dependencies such as `cobra` / `urfave/cli` are introduced; the flag parser remains hand-written.
- CLI parameters are kept as consistent as possible with the MCP schema.
- `--output json` outputs structured JSON corresponding to the Go API.
- `viewed_code_id` and transaction / snapshot tools are MCP-only because they rely on in-process session state.

Note: CLI mode is not specifically designed for Pi agent. Pi and similar agents directly generating precise shell commands are prone to errors (quotes, spaces, command substitution, etc. — to be precise, this is mostly an LLM issue: it cannot guarantee that generated JSON is valid. This problem occurs at the instruction level and our binary software cannot intercept it, because at the bash/shell layer it will be interpreted as multiple commands). If Pi integration is needed, please prioritize writing a Pi skill document or adding high-level wrapper commands more suitable for Pi rather than asking to abandon the CLI.

I personally recommend prioritizing MCP-based integration, especially for CLI code editing scenarios and Pi Agent scenarios.

Known issues:

- Pi directly generating precise shell commands is prone to errors (quotes, spaces, `$()`, backticks, and other shell metacharacters), and because this is interpreted as other commands at the shell layer, we cannot intervene at the software level...?
- The CLI currently lacks parameters like `--content-file` / `--old-file` to avoid shell quoting issues.

If you want to improve Pi integration, suggested directions:

1. First write a `docs/pi.md` skill document to teach Pi the workflow of using the existing CLI.
2. If Pi still struggles, then consider adding `--content-file` or a more natural "old / new" high-level command.

What Kimi 2.7 told us:

> Don't abandon the entire CLI feature because of this: CLI is still valuable for shell scripts and ordinary terminal users.

Then the following happened:

While editing this section, I thought of something: we could try using pipes to avoid agents generating symbols incorrectly and causing parsing failures. But the Kimi agent pointed out that this still requires ensuring the EOL markers at the beginning and end are paired, which I really can't do anything about. So I initiated a feature commit (see commit `2e4d97a`) to let the CLI use this functionality as much as possible.


{{< issue title="Feedback: I Want to Add CLI Subcommands / I Want Dedicated Integration for Pi Agent" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want `install.sh` to Automatically Configure MCP Clients

Based on the discussion in [issue #46](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/46), we decided
**install.sh is only responsible for downloading, verifying, placing the binary, and returning the absolute path and `--lang` parameter to the user / agent**, without actively modifying the user's MCP client configuration files.

Reasons:

- Automatically modifying user configuration files is unsafe and users cannot see the agent's behavior.
- Different MCP clients have different configuration paths and formats that change quickly, leading to high maintenance costs.
- Each agent usually has its own system prompt or skill to guide how to configure MCP; this should be left to the agent itself.

Considering that `install.sh` is actually only friendly to Linux and macOS users, we may need to provide other installation methods for Windows users in the future. But for the reasons above, we cannot and will not provide one-click installation. However, v0.11.0 added `docs/llm-setup-guide.zh.md` / `docs/llm-setup-guide.md` as workflow documents for AI Agents.


{{< issue title="Feedback: I Want `install.sh` to Automatically Configure MCP Clients" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Change the `--lang` Default Value or Auto-Detection Logic

Based on [issue #45](https://github.com/conglinyizhi/better-edit-tools-mcp/issues/45), we decided:

- Keep the current behavior where `--lang` falls back to the `LANG` environment variable and ultimately defaults to English.
- Add an explicit reminder at the top of the README telling Chinese users to manually add `"args": ["--lang", "zh"]`.
- `install.sh` will detect `LANG`; on Chinese systems the default output configuration example includes `--lang zh`.

Reasons:

- Defaulting to English is the safest assumption for global users.
- Chinese users should not rely on auto-detection because `LANG` may not reflect the MCP client's language environment.
- But if you have a better strategy, feel free to open an issue.

Appendix: This is the result of running `export | rg LANG` on a Chinese-language ArchLinux in our development environment:

```shell
CSF_LANGUAGE=us
LANG=zh_CN.UTF-8
LANGUAGE=''
```

The LC filter results are not shown because there is nothing to show (exit 1).


{{< issue title="Feedback: I Want to Change the `--lang` Default Value or Auto-Detection Logic" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## I Want to Change the Versioning Strategy or Release Process

The project is currently in rapid iteration, so we do not plan to bump the major version number for now.

But if you have a proposal for this plan, feel free to open an issue to discuss it together.

According to `.github/workflows/build.yml` and commit history, the current strategy:

- The version number is stored in the `Version` constant in `internal/app/lang.go`.
- Pushing a `v*` tag triggers GitHub Actions to automatically build packages for 6 platforms and create a Release.
- Release notes are automatically generated in Conventional Commits style.

Version rules:

- `0.MINOR.PATCH`
- New features bump minor (e.g., CLI subcommands, i18n externalization → v0.11.0).
- Bug fixes bump patch.
- Major version is reserved for a future stable 1.0 release.


{{< issue title="Feedback: I Want to Change the Versioning Strategy or Release Process" body="Please describe your suggestion, problem, or new evidence." labels="docs:talk" text="📝 Open issue" >}}

---

## Some Versions Don't Have Corresponding Release Packages

Because of CI / workflow design issues, we only know if something is wrong after pushing, when the GitHub action starts working. If it succeeds, there is a package; if it fails, there isn't. This means we don't have a good way to simulate the CI flow locally before every commit, and we are trying to solve this.