Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

<!-- START TOKEN CLAIM -->

**11,396 tokens of startup context by default, the same on every GitLab tier (1,994 with `GITLAB_MCP_CAPABILITY_SURFACE=minimal`).** Two tools reach the whole catalog, where listing every tool as its own costs from 577,678 to 737,573 tokens. Measured with the cl100k_base tokenizer and checked in CI. [How it is measured](https://docs.jmrp.io/gitlab-mcp-server/tools/dynamic-tools/#how-much-startup-context-does-dynamic-mode-save)
**11,396 tokens of startup context by default, the same on every GitLab tier (1,994 with `GITLAB_MCP_CAPABILITY_SURFACE=minimal`).** Two tools reach the whole catalog, where listing every tool as its own costs from 576,925 to 738,013 tokens. Measured with the cl100k_base tokenizer and checked in CI. [How it is measured](https://docs.jmrp.io/gitlab-mcp-server/tools/dynamic-tools/#how-much-startup-context-does-dynamic-mode-save)

<!-- END TOKEN CLAIM -->

Expand Down
12 changes: 11 additions & 1 deletion cmd/audit_1to1/internal/paths/sent_declarations.go
Original file line number Diff line number Diff line change
Expand Up @@ -1136,11 +1136,14 @@ var declaredUnsurfaced = slices.Concat([]sentDeclaration{ //nolint:gochecknoglob
// The existence probes: three list actions read the project, and the LDAP
// link listing the group, only to tell a missing object from one with
// nothing to list. The option declarations above still answer the license
// and custom attribute keys, since they come first.
// and custom attribute keys, since they come first. The group approval at
// Minimal access reads the group for its parent_id alone, which is a
// probe of the same kind.
{Package: attestationsPkg, Entity: projectWithAccessEntity, Field: declaredSegment, Category: categoryReadForItsOwnUse, Reason: reasonAttestationProjectProbe},
{Package: securityFindingsPkg, Entity: projectWithAccessEntity, Field: declaredSegment, Category: categoryReadForItsOwnUse, Reason: reasonGraphQLProjectProbe},
{Package: vulnerabilitiesPkg, Entity: projectWithAccessEntity, Field: declaredSegment, Category: categoryReadForItsOwnUse, Reason: reasonGraphQLProjectProbe},
{Package: groupLDAPPkg, Entity: groupDetailEntity, Field: declaredSegment, Category: categoryReadForItsOwnUse, Reason: reasonLDAPGroupProbe},
{Package: accessRequestsPkg, Entity: groupDetailEntity, Field: declaredSegment, Category: categoryReadForItsOwnUse, Reason: reasonMinimalAccessGroupProbe},

// The current user, which one package reads for the caller's id and the
// other to prove the credential.
Expand Down Expand Up @@ -1282,6 +1285,13 @@ const reasonLDAPGroupProbe = "internal/tools/groupldap reads GET /groups/:id onl
"answered 404, to tell a group with no LDAP link (an empty list) from a group that does not exist (the error), and " +
"returns nothing of the answer. group.get is the action that answers with a group."

// reasonMinimalAccessGroupProbe answers the group a Minimal access approval
// reads before it is sent.
const reasonMinimalAccessGroupProbe = "internal/tools/accessrequests reads GET /groups/:id only when access.approve_group is " +
"asked for access_level 5, to refuse the approval on a subgroup, where GitLab answers it with 201 and leaves the request " +
"pending, before it is sent; it reads parent_id and returns nothing of the answer. group.get is the action that answers " +
"with a group."

// reasonAwardEmojiCurrentUser answers the user the merge request emoji award
// reads to find the caller's own existing award.
const reasonAwardEmojiCurrentUser = "internal/tools/awardemoji reads GET /user only after awarding an emoji to a merge " +
Expand Down
32 changes: 31 additions & 1 deletion docs/development/action-requests.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@
],
"classic": "api",
"requests": [
{
"kind": "rest",
"route": "GET /groups/:id",
"class": "optional",
"classic": "read_api",
"sites": [
"accessrequests.refuseMinimalAccessGroup"
],
"sdk_methods": [
"Groups.GetGroup"
],
"directives": [
"optional: the group is read only for a Minimal access approval, to refuse it on a subgroup before the approval is sent"
]
},
{
"kind": "rest",
"route": "PUT /groups/:id/access_requests/:user_id/approve",
Expand All @@ -19,11 +34,26 @@
"sdk_methods": [
"AccessRequests.ApproveGroupAccessRequest"
]
},
{
"kind": "rest",
"route": "GET /groups/:id/members/:user_id",
"class": "optional",
"classic": "read_api",
"sites": [
"accessrequests.confirmMinimalAccess"
],
"sdk_methods": [
"GroupMembers.GetGroupMember"
],
"directives": [
"optional: the requester is read back only after a Minimal access approval, since the approval answers alike whether GitLab saved it or not"
]
}
],
"paths": [
[
0
1
]
]
},
Expand Down
25 changes: 24 additions & 1 deletion docs/development/request-inventory.json
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,18 @@
"method": "GET",
"path": "/version"
},
{
"package": "internal/tools/accessrequests",
"kind": "rest",
"method": "GET",
"path": "/groups/:group_id",
"query": [
"with_projects"
],
"identifiers": {
":group_id": 1
}
},
{
"package": "internal/tools/accessrequests",
"kind": "rest",
Expand Down Expand Up @@ -1842,6 +1854,16 @@
":group_id": 2
}
},
{
"package": "internal/tools/accessrequests",
"kind": "rest",
"method": "GET",
"path": "/groups/:group_id/members/:member_id",
"identifiers": {
":group_id": 1,
":member_id": 1
}
},
{
"package": "internal/tools/accessrequests",
"kind": "rest",
Expand Down Expand Up @@ -13890,7 +13912,8 @@
"method": "PUT",
"path": "/groups/grp/notification_settings",
"body": [
"level"
"level",
"new_epic"
]
},
{
Expand Down
48 changes: 24 additions & 24 deletions docs/development/testing/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@

| Metric | Value |
| ----------------------------------------------------- | -----: |
| Total test functions | 22,484 |
| Unit test functions | 20,840 |
| E2E test functions | 1,644 |
| cmd test functions | 5,214 |
| Total test functions | 22,523 |
| Unit test functions | 20,873 |
| E2E test functions | 1,650 |
| cmd test functions | 5,223 |
| Test files (internal/) | 731 |
| Test files (cmd/) | 390 |
| Test files (test/e2e/) | 430 |
| Test files (cmd/) | 391 |
| Test files (test/e2e/) | 433 |
| Tool sub-packages tested | 181 |
| Core packages tested | 34 |
| Overall coverage (`go test ./internal/... ./cmd/...`) | 100.0% |
Expand All @@ -37,22 +37,22 @@

| Pattern | Count | % |
| -------------------------------------- | -----: | ----: |
| `TestFunc_Scenario` (2-part) | 13,564 | 60.3% |
| `TestFunc_Scenario` (2-part) | 13,568 | 60.2% |
| `TestFunc` (no underscore) | 909 | 4.0% |
| `TestFunc_Scenario_Expected` (3+ part) | 8,011 | 35.6% |
| `TestFunc_Scenario_Expected` (3+ part) | 8,046 | 35.7% |

## Test Distribution

### By Layer

| Layer | Test Functions | Test Files | Description |
| ----------------------- | -------------: | ---------: | ----------------------------------------------------------------------------------------------- |
| Core packages | 4,094 | 243 | shared runtime packages such as config, GitLab client, OAuth, resources, prompts, and utilities |
| Tools orchestration | 421 | 16 | registration, meta-tool dispatch, safe mode, validation, markdown, and routing tests |
| Tool sub-packages (181) | 11,111 | 472 | domain-specific GitLab tool handlers |
| E2E integration | 1,644 | 430 | build-tagged; only test/e2e/gitlab and test/e2e/orbit need a real instance |
| cmd packages | 5,214 | 390 | server entry point and developer command utilities |
| **Total** | **22,484** | **1,551** | |
| Core packages | 4,100 | 243 | shared runtime packages such as config, GitLab client, OAuth, resources, prompts, and utilities |
| Tools orchestration | 428 | 16 | registration, meta-tool dispatch, safe mode, validation, markdown, and routing tests |
| Tool sub-packages (181) | 11,122 | 472 | domain-specific GitLab tool handlers |
| E2E integration | 1,650 | 433 | build-tagged; only test/e2e/gitlab and test/e2e/orbit need a real instance |
| cmd packages | 5,223 | 391 | server entry point and developer command utilities |
| **Total** | **22,523** | **1,555** | |

### Core Packages

Expand Down Expand Up @@ -91,8 +91,8 @@
| testutil/netfixture | 8 | 100.0% | Package netfixture gives a test an HTTP address that stops answering without giving its port away. |
| testutil/serialtypecheck | 6 | 100.0% | Package serialtypecheck makes golang.org/x/tools/go/packages type-check one package at a time in a race build, and does nothing in any other build. |
| testutil/shardio | 32 | 100.0% | Package shardio is the shard mechanism the records written by a test process and read back by a command are built on: one shard file per process, one JSON line per record, a directory tree read in one pass, and a line nobody can read reported rather than dropped. |
| toolutil | 1,343 | 100.0% | Package toolutil provides shared utilities for MCP tool handler sub-packages. |
| **Subtotal** | **4,094** | | |
| toolutil | 1,349 | 100.0% | Package toolutil provides shared utilities for MCP tool handler sub-packages. |
| **Subtotal** | **4,100** | | |

### Tool Sub-Packages (Top Domains by Test Count)

Expand All @@ -116,11 +116,11 @@
| containerregistry | 125 | 100.0% | 16 |
| branches | 115 | 100.0% | 10 |
| snippets | 115 | 100.0% | 15 |
| accesstokens | 110 | 100.0% | 18 |
| groupmilestones | 110 | 100.0% | 8 |
| accesstokens | 109 | 100.0% | 18 |
| pipelineschedules | 109 | 100.0% | 11 |
| groupmembers | 108 | 100.0% | 10 |
| mrapprovals | 108 | 100.0% | 7 |
| groupmembers | 107 | 100.0% | 10 |
| files | 101 | 100.0% | 8 |
| milestones | 97 | 100.0% | 9 |

Expand All @@ -131,8 +131,8 @@

| Sub-package | Tests | Test Files | Coverage | Tools |
| ----------------------- | ---------: | ---------: | -------: | --------: |
| accessrequests | 58 | 4 | 100.0% | 8 |
| accesstokens | 109 | 2 | 100.0% | 18 |
| accessrequests | 65 | 4 | 100.0% | 8 |
| accesstokens | 110 | 2 | 100.0% | 18 |
| achievements | 67 | 3 | 100.0% | 12 |
| actioncatalog | 75 | 8 | 100.0% | 0 |
| actioncompat | 61 | 3 | 100.0% | 1 |
Expand Down Expand Up @@ -202,14 +202,14 @@
| grouplabels | 65 | 3 | 100.0% | 7 |
| groupldap | 23 | 2 | 100.0% | 5 |
| groupmarkdownuploads | 35 | 4 | 100.0% | 3 |
| groupmembers | 107 | 5 | 100.0% | 10 |
| groupmembers | 108 | 5 | 100.0% | 10 |
| groupmilestones | 110 | 3 | 100.0% | 8 |
| groupprotectedbranches | 24 | 2 | 100.0% | 5 |
| groupprotectedenvs | 36 | 3 | 100.0% | 5 |
| grouprelationsexport | 30 | 3 | 100.0% | 2 |
| groupreleases | 24 | 3 | 100.0% | 1 |
| groups | 317 | 10 | 100.0% | 37 |
| groupsaml | 39 | 3 | 100.0% | 5 |
| groupsaml | 40 | 3 | 100.0% | 5 |
| groupscim | 31 | 3 | 100.0% | 4 |
| groupserviceaccounts | 34 | 2 | 100.0% | 9 |
| groupsshcerts | 33 | 5 | 100.0% | 3 |
Expand Down Expand Up @@ -251,7 +251,7 @@
| mrdraftnotes | 80 | 3 | 100.0% | 7 |
| mrnotes | 52 | 4 | 100.0% | 5 |
| namespaces | 52 | 2 | 100.0% | 4 |
| notifications | 39 | 2 | 100.0% | 6 |
| notifications | 40 | 2 | 100.0% | 6 |
| orbit | 92 | 3 | 100.0% | 6 |
| packages | 178 | 6 | 100.0% | 10 |
| pages | 66 | 2 | 100.0% | 9 |
Expand Down Expand Up @@ -312,7 +312,7 @@
| wikis | 74 | 2 | 100.0% | 6 |
| workitems | 136 | 6 | 100.0% | 6 |
| workitemsavedviews | 63 | 4 | 100.0% | 7 |
| **Total** | **11,111** | **472** | | **1,195** |
| **Total** | **11,122** | **472** | | **1,195** |

</details>

Expand Down
Loading
Loading