Add file mode (executable bit) support to `push_files`
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
Hướng nghiên cứu
Bắt đầu trong pkg/github/repositories.go, tại phần định nghĩa công cụ push_files và vòng lặp xây dựng các mục trong cây Git Data API. Theo dõi schema đầu vào files[] và các giá trị mặc định hiện có, sau đó xác minh rằng các mode được chấp nhận và hành vi khi bỏ qua mode được thể hiện nhất quán. Công việc được xem là hoàn tất khi push_files có thể giữ lại mode được yêu cầu, các giá trị mặc định vẫn tương thích và create_or_update_file nằm ngoài phạm vi.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Feature request: expose file mode (executable bit) on push_files
Use case
Agentic coding harnesses use this MCP server to publish files into a repo
on behalf of an LLM (issue execution, autonomous PR workflows, etc.).
When the work the agent is asked to produce is a shell script, build
helper, or other executable, the resulting file needs the executable
bit set (100755) — otherwise reviewers either have to chmod +x after
merge or merge a broken artifact.
Today there is no way for an MCP client to land an executable file
through this server. Both file-write tools use APIs that surface a fixed
mode:
create_or_update_file→ Contents API (PUT /repos/.../contents/{path}),
which always writes mode100644. This is a GitHub API limitation, not
something this server can route around.push_files→ Git Data API (CreateTree+CreateCommit+
UpdateRef). The underlying API does support per-entry mode, but
the tool's input schema doesn't expose it. Each entry is currently
{content, path}only.
We've observed agents react to this in two unhelpful ways:
- Quiet hallucination. The agent reports in the PR body that it
pushed with mode100755when in fact the blob landed as100644. - Workaround scope drift. The agent invents a second file (e.g.
scripts/permissions.shcontainingfind scripts/ -exec chmod +x)
that wasn't part of the task, hoping a CI step or human will run it.
A first-class mode parameter on push_files would close both failure
modes cleanly.
Proposed change
Extend the push_files.files[] input schema with an optional mode
field, validated against the set the Git Data API accepts:
| Mode | Meaning |
|---|---|
100644 |
regular file (default if omitted) |
100755 |
executable file |
120000 |
symlink |
040000 |
subdirectory (subtree) |
160000 |
submodule |
For most agentic use cases only 100644 (default) and 100755 matter,
but echoing the full Git Data API set keeps parity with the underlying
endpoint.
Backwards compatible: existing callers that omit mode get 100644,
which is what they get today.
Implementation pointer
The relevant code is already calling Git.CreateTree with a
[]*github.TreeEntry (in pkg/github/repositories.go, around the
PushFiles tool definition). The go-github TreeEntry struct
already has a Mode *string field — it just isn't being set from the
tool input. Threading it through should be a small change:
// in the loop that builds entries:
mode := "100644"
if f.Mode != nil {
mode = *f.Mode
}
entries = append(entries, &github.TreeEntry{
Path: github.String(f.Path),
Mode: github.String(mode),
Type: github.String("blob"),
Content: github.String(f.Content),
})
Plus input-schema additions for the optional field with the validated
set above.
Single-file case
create_or_update_file can't be fixed the same way because the Contents
API doesn't support mode at all — it's a GitHub API constraint, not a
server constraint. For the single-file executable case, callers can use
push_files with a one-entry files array. Worth noting that in the
tool's description so clients pick the right call.
Out of scope
- Changes to
create_or_update_file(blocked by Contents API). - Symlink/submodule write flows beyond just accepting their modes on the
schema. - Validating the executable-bit semantics on the receiving end.
Context
Filed against this server because we've been hitting the limitation
from a Claude-Code-plans / Goose-executes harness
(why-pengo/claude_and_goose),
where local-model executors are asked to ship small bash helpers as
part of issue-driven PRs. Happy to send a PR if the proposed shape
looks right.
- Ngôn ngữ chính
- Go
- Star
- 33.1k
- Fork
- 5k
- Merge trung bình
- 2 ngày 15 giờ
- Pull request đã merge (30 ngày)
- 27
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của github/github-mcp-server
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
github/github-mcp-server#3235 ·
-
enhancement
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
github/github-mcp-server#3042 · 2 bình luận ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
github/github-mcp-server#3032 · 1 reaction ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
github/github-mcp-server#2803 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
github/github-mcp-server#2740 ·
Tất cả issue của github/github-mcp-server
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 84/100
-
enhancement needs triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
-
kind/cleanup
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
kubernetes-sigs/kueue#15947 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
sympozium-ai/sympozium#627 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100