From de06a7cfd31c6c2c6ac00d59ae9f03107babe1ae Mon Sep 17 00:00:00 2001 From: quiloos39 Date: Fri, 30 Jan 2026 10:22:13 +0100 Subject: [PATCH 1/3] feat: add since and until date filters to list_commits Add optional `since` and `until` parameters to the list_commits tool, allowing users to filter commits by date range using ISO 8601 format. This enables more efficient commit queries for time-based workflows like calculating working hours or reviewing activity within specific periods, reducing unnecessary context from historical commits. Co-Authored-By: Claude Opus 4.5 --- pkg/github/repositories.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pkg/github/repositories.go b/pkg/github/repositories.go index f6203f39f..adc960db5 100644 --- a/pkg/github/repositories.go +++ b/pkg/github/repositories.go @@ -8,6 +8,7 @@ import ( "net/http" "net/url" "strings" + "time" ghErrors "github.com/github/github-mcp-server/pkg/errors" "github.com/github/github-mcp-server/pkg/inventory" @@ -147,6 +148,14 @@ func ListCommits(t translations.TranslationHelperFunc) inventory.ServerTool { Type: "string", Description: "Author username or email address to filter commits by", }, + "since": { + Type: "string", + Description: "Only show commits after this date (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ)", + }, + "until": { + Type: "string", + Description: "Only show commits before this date (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ)", + }, }, Required: []string{"owner", "repo"}, }), @@ -169,6 +178,27 @@ func ListCommits(t translations.TranslationHelperFunc) inventory.ServerTool { if err != nil { return utils.NewToolResultError(err.Error()), nil, nil } + sinceStr, err := OptionalParam[string](args, "since") + if err != nil { + return utils.NewToolResultError(err.Error()), nil, nil + } + untilStr, err := OptionalParam[string](args, "until") + if err != nil { + return utils.NewToolResultError(err.Error()), nil, nil + } + var sinceTime, untilTime time.Time + if sinceStr != "" { + sinceTime, err = time.Parse(time.RFC3339, sinceStr) + if err != nil { + return utils.NewToolResultError(fmt.Sprintf("invalid 'since' date format, expected ISO 8601 (YYYY-MM-DDTHH:MM:SSZ): %s", err.Error())), nil, nil + } + } + if untilStr != "" { + untilTime, err = time.Parse(time.RFC3339, untilStr) + if err != nil { + return utils.NewToolResultError(fmt.Sprintf("invalid 'until' date format, expected ISO 8601 (YYYY-MM-DDTHH:MM:SSZ): %s", err.Error())), nil, nil + } + } pagination, err := OptionalPaginationParams(args) if err != nil { return utils.NewToolResultError(err.Error()), nil, nil @@ -181,6 +211,8 @@ func ListCommits(t translations.TranslationHelperFunc) inventory.ServerTool { opts := &github.CommitsListOptions{ SHA: sha, Author: author, + Since: sinceTime, + Until: untilTime, ListOptions: github.ListOptions{ Page: pagination.Page, PerPage: perPage, From 93411adccaf558ebbed8376ce92cbf14d4e2bc7a Mon Sep 17 00:00:00 2001 From: quiloos39 Date: Wed, 4 Feb 2026 22:02:37 +0300 Subject: [PATCH 2/3] fix: update toolsnap and generated docs for since/until filters Co-Authored-By: Claude Opus 4.5 --- README.md | 2 ++ pkg/github/__toolsnaps__/list_commits.snap | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/README.md b/README.md index afe003002..e8eb1eced 100644 --- a/README.md +++ b/README.md @@ -1223,6 +1223,8 @@ The following sets of tools are available: - `perPage`: Results per page for pagination (min 1, max 100) (number, optional) - `repo`: Repository name (string, required) - `sha`: Commit SHA, branch or tag name to list commits of. If not provided, uses the default branch of the repository. If a commit SHA is provided, will list commits up to that SHA. (string, optional) + - `since`: Only show commits after this date (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ) (string, optional) + - `until`: Only show commits before this date (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ) (string, optional) - **list_releases** - List releases - **Required OAuth Scopes**: `repo` diff --git a/pkg/github/__toolsnaps__/list_commits.snap b/pkg/github/__toolsnaps__/list_commits.snap index 38b63736f..c2ffba170 100644 --- a/pkg/github/__toolsnaps__/list_commits.snap +++ b/pkg/github/__toolsnaps__/list_commits.snap @@ -32,6 +32,14 @@ "sha": { "description": "Commit SHA, branch or tag name to list commits of. If not provided, uses the default branch of the repository. If a commit SHA is provided, will list commits up to that SHA.", "type": "string" + }, + "since": { + "description": "Only show commits after this date (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ)", + "type": "string" + }, + "until": { + "description": "Only show commits before this date (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ)", + "type": "string" } }, "required": [ From e324f6fef5d005cf7107db0084b091644e5e680c Mon Sep 17 00:00:00 2001 From: quiloos39 Date: Wed, 4 Feb 2026 22:06:53 +0300 Subject: [PATCH 3/3] test: add tests for since/until date filters in list_commits Co-Authored-By: Claude Opus 4.5 --- pkg/github/repositories_test.go | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pkg/github/repositories_test.go b/pkg/github/repositories_test.go index d91af8851..6b1e7cc64 100644 --- a/pkg/github/repositories_test.go +++ b/pkg/github/repositories_test.go @@ -826,6 +826,8 @@ func Test_ListCommits(t *testing.T) { assert.Contains(t, schema.Properties, "repo") assert.Contains(t, schema.Properties, "sha") assert.Contains(t, schema.Properties, "author") + assert.Contains(t, schema.Properties, "since") + assert.Contains(t, schema.Properties, "until") assert.Contains(t, schema.Properties, "page") assert.Contains(t, schema.Properties, "perPage") assert.ElementsMatch(t, schema.Required, []string{"owner", "repo"}) @@ -965,6 +967,49 @@ func Test_ListCommits(t *testing.T) { expectError: false, expectedCommits: mockCommits, }, + { + name: "successful commits fetch with since and until", + mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{ + GetReposCommitsByOwnerByRepo: expectQueryParams(t, map[string]string{ + "since": "2025-01-01T00:00:00Z", + "until": "2025-01-31T23:59:59Z", + "page": "1", + "per_page": "30", + }).andThen( + mockResponse(t, http.StatusOK, mockCommits), + ), + }), + requestArgs: map[string]interface{}{ + "owner": "owner", + "repo": "repo", + "since": "2025-01-01T00:00:00Z", + "until": "2025-01-31T23:59:59Z", + }, + expectError: false, + expectedCommits: mockCommits, + }, + { + name: "invalid since date format", + mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{}), + requestArgs: map[string]interface{}{ + "owner": "owner", + "repo": "repo", + "since": "not-a-date", + }, + expectError: true, + expectedErrMsg: "invalid 'since' date format", + }, + { + name: "invalid until date format", + mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{}), + requestArgs: map[string]interface{}{ + "owner": "owner", + "repo": "repo", + "until": "2025/01/01", + }, + expectError: true, + expectedErrMsg: "invalid 'until' date format", + }, { name: "commits fetch fails", mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{