Add file mode (executable bit) support to `push_files`

Offen Anfängerfreundlich
#2,578 0 Kommentare 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
78/100
Issue-Typ
Feature
Klarheit
Klar beschrieben
Aktivitätsstatus
Ruhig
Tech-Stack
github, go
Bereich
api, tooling

Rechercherichtung

Beginne in pkg/github/repositories.go bei der Definition des push_files-Tools und der Schleife, die Einträge für den Git Data API-Baum erstellt. Verfolge das Eingabeschema für files[] und die bestehenden Standardwerte; prüfe dann, dass die akzeptierten Modi und das Verhalten bei ausgelassenem Modus konsistent dargestellt werden. Die Aufgabe ist erledigt, wenn push_files den angeforderten Modus beibehalten kann, die Standardwerte kompatibel bleiben und create_or_update_file außerhalb des Umfangs bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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 mode 100644. 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:

  1. Quiet hallucination. The agent reports in the PR body that it
    pushed with mode 100755 when in fact the blob landed as 100644.
  2. Workaround scope drift. The agent invents a second file (e.g.
    scripts/permissions.sh containing find 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.

Vorherrschende Sprache
Go
Sterne
33.1k
Forks
5k
Ø Merge
2 T. 15 Std.
Gemergte PRs (30 T.)
27

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus github/github-mcp-server

Alle Issues in github/github-mcp-server

Ähnliche Issues

Weitere Issues zu Go

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.