Skip to content

Commit 07aafc6

Browse files
committed
feat: sync contextforge sdk to upstream rc1
1 parent ad481ee commit 07aafc6

13 files changed

Lines changed: 387 additions & 67 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- Feat: add teams direct-member endpoint support (`POST /teams/{team_id}/members`)
12+
13+
### Changed
14+
- Build: run integration harness against ContextForge v1.0.0-RC1
15+
16+
### Documentation
17+
- Docs: update tested-against version to ContextForge v1.0.0-RC1
18+
1019
## [0.9.0] - 2026-02-09
1120

1221
### Added

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,6 @@ Some integration tests are skipped due to confirmed bugs in the upstream Context
252252
| CONTEXTFORGE-001 | Toggle endpoints return stale state | 4 tests |
253253
| CONTEXTFORGE-002 | API accepts empty template string | 1 test |
254254
| CONTEXTFORGE-003 | Toggle returns 400 instead of 404 | 1 test |
255-
| CONTEXTFORGE-004 | Teams endpoints reject valid auth | 12 tests |
256255
| CONTEXTFORGE-005 | Teams slug field ignored | 2 tests |
257256
| CONTEXTFORGE-007 | Gateway tags not persisted | 2 tests |
258257
| CONTEXTFORGE-008 | Agent bearer auth requires auth_token | 1 test |
@@ -262,6 +261,7 @@ Some integration tests are skipped due to confirmed bugs in the upstream Context
262261
**Resolved Issues (tests re-enabled):**
263262
| Bug ID | Summary | Resolution |
264263
|--------|---------|------------|
264+
| CONTEXTFORGE-004 | Teams endpoints reject valid auth | Fixed in ContextForge v1.0.0-RC1 |
265265
| CONTEXTFORGE-006 | 422 for validation errors | By design (FastAPI standard)
266266

267267
To re-enable a skipped test once the upstream bug is fixed:

README.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ For more information about the A2A protocol, see the [official specification](ht
7676

7777
### Compatibility
7878

79-
This SDK is tested against **ContextForge v1.0.0-BETA-2** (PyPI: `mcpgateway==1.0.0b2`).
79+
This SDK is tested against **ContextForge v1.0.0-RC1** (PyPI: `mcp-contextforge-gateway==1.0.0rc1`).
8080

8181
## Installation
8282

@@ -682,6 +682,12 @@ _, err = client.Teams.Delete(ctx, "team-id")
682682
// List team members
683683
members, _, err := client.Teams.ListMembers(ctx, "team-id")
684684

685+
// Add a direct member
686+
member, _, err := client.Teams.AddMember(ctx, "team-id", &contextforge.TeamMemberAdd{
687+
Email: "user@example.com",
688+
Role: "member",
689+
})
690+
685691
// Update member role (uses email as identifier)
686692
memberUpdate := &contextforge.TeamMemberUpdate{
687693
Role: "owner", // "owner" | "member"
@@ -909,6 +915,7 @@ if resp.Rate.Limit > 0 {
909915
| `Update(ctx, teamID, team)` | Update team |
910916
| `Delete(ctx, teamID)` | Delete team |
911917
| `ListMembers(ctx, teamID)` | List team members |
918+
| `AddMember(ctx, teamID, add)` | Add member directly by email |
912919
| `UpdateMember(ctx, teamID, email, update)` | Update member role (uses email) |
913920
| `RemoveMember(ctx, teamID, email)` | Remove member (uses email) |
914921
| `InviteMember(ctx, teamID, invite)` | Invite user to team |
@@ -1229,25 +1236,24 @@ This SDK follows the service-oriented architecture pattern established by [googl
12291236

12301237
### Upstream ContextForge API Bugs
12311238

1232-
The SDK integration tests have identified six bugs in ContextForge (confirmed in both v0.8.0 and v1.0.0-BETA-1; revalidation against v1.0.0-BETA-2 is pending in this repository). These bugs are in the upstream API, not the SDK implementation. Affected tests are skipped and will be re-enabled once upstream bugs are fixed.
1239+
The SDK integration tests currently document several upstream ContextForge API bugs. These bugs are in the upstream API, not the SDK implementation. Affected tests are skipped and will be re-enabled once upstream fixes land; see the linked reports for the latest validated version for each issue.
12331240

12341241
**CONTEXTFORGE-001: Toggle Endpoints Return Stale State**
12351242
The `POST /prompts/{id}/toggle` and `POST /resources/{id}/toggle` endpoints return stale `isActive` state despite correctly updating the database. See [`docs/upstream-bugs/contextforge-001-prompt-toggle.md`](docs/upstream-bugs/contextforge-001-prompt-toggle.md).
12361243

12371244
**CONTEXTFORGE-002: Prompts API Accepts Empty Template Field**
12381245
The `POST /prompts` endpoint accepts prompt creation without the `template` field, allowing semantically invalid prompts. See [`docs/upstream-bugs/contextforge-002-prompt-validation-missing-template.md`](docs/upstream-bugs/contextforge-002-prompt-validation-missing-template.md).
12391246

1240-
**CONTEXTFORGE-003: Prompts Toggle Returns 400 Instead of 404**
1241-
The `POST /prompts/{id}/toggle` endpoint returns HTTP 400 for non-existent prompts instead of 404. See [`docs/upstream-bugs/contextforge-003-prompt-toggle-error-code.md`](docs/upstream-bugs/contextforge-003-prompt-toggle-error-code.md).
1242-
1243-
**CONTEXTFORGE-004: Teams Individual Resource Endpoints Reject Valid Authentication**
1244-
Individual team endpoints (`GET/PUT/DELETE /teams/{id}/*`) reject valid JWT tokens with 401 Unauthorized, despite list/create working correctly. See [`docs/upstream-bugs/contextforge-004-teams-auth-individual-endpoints.md`](docs/upstream-bugs/contextforge-004-teams-auth-individual-endpoints.md).
1245-
12461247
**CONTEXTFORGE-005: Teams API Ignores User-Provided Slug Field**
12471248
The `POST /teams` endpoint ignores the `slug` field and always auto-generates from team name. See [`docs/upstream-bugs/contextforge-005-teams-slug-ignored.md`](docs/upstream-bugs/contextforge-005-teams-slug-ignored.md).
12481249

1249-
**CONTEXTFORGE-006: Teams API Returns 422 Instead of 400 for Validation Errors**
1250-
The `POST /teams` endpoint returns HTTP 422 (Unprocessable Entity) for validation errors instead of 400 (Bad Request). See [`docs/upstream-bugs/contextforge-006-teams-validation-error-code.md`](docs/upstream-bugs/contextforge-006-teams-validation-error-code.md).
1250+
**CONTEXTFORGE-008: Agent Bearer Auth Field Name Mismatch**
1251+
The A2A agent API still expects `auth_token` for bearer auth instead of the SDK’s `auth_value` field. See [`docs/upstream-bugs/contextforge-008-agent-auth-field-name.md`](docs/upstream-bugs/contextforge-008-agent-auth-field-name.md).
1252+
1253+
**CONTEXTFORGE-010: Team ID Filter Returns Permission Error**
1254+
The tools list API still returns a `403` for some team-scoped filter combinations that should succeed. See [`docs/upstream-bugs/contextforge-010-team-id-filter-permission-error.md`](docs/upstream-bugs/contextforge-010-team-id-filter-permission-error.md).
1255+
1256+
Resolved in current RC1 validation: `CONTEXTFORGE-004` team endpoint auth failures no longer reproduce. Historical and resolved reports remain under [`docs/upstream-bugs/`](docs/upstream-bugs/).
12511257

12521258
All bug reports include root cause analysis, proposed solutions, and workarounds.
12531259

contextforge/teams.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,24 @@ func (s *TeamsService) ListMembers(ctx context.Context, teamID string) ([]*TeamM
123123
return members, resp, nil
124124
}
125125

126+
// AddMember adds a user to a team.
127+
func (s *TeamsService) AddMember(ctx context.Context, teamID string, add *TeamMemberAdd) (*TeamMember, *Response, error) {
128+
u := fmt.Sprintf("teams/%s/members/", url.PathEscape(teamID))
129+
130+
req, err := s.client.NewRequest(http.MethodPost, u, add)
131+
if err != nil {
132+
return nil, nil, err
133+
}
134+
135+
var member *TeamMember
136+
resp, err := s.client.Do(ctx, req, &member)
137+
if err != nil {
138+
return nil, resp, err
139+
}
140+
141+
return member, resp, nil
142+
}
143+
126144
// UpdateMember updates a team member's role.
127145
// Note: Uses email as the member identifier, not ID.
128146
func (s *TeamsService) UpdateMember(ctx context.Context, teamID, userEmail string, update *TeamMemberUpdate) (*TeamMember, *Response, error) {

contextforge/teams_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,50 @@ func TestTeamsService_ListMembers(t *testing.T) {
225225
}
226226
}
227227

228+
func TestTeamsService_AddMember(t *testing.T) {
229+
client, mux, _, teardown := setup()
230+
defer teardown()
231+
232+
input := &TeamMemberAdd{
233+
Email: "newuser@test.local",
234+
Role: "member",
235+
}
236+
237+
mux.HandleFunc("/teams/123/members/", func(w http.ResponseWriter, r *http.Request) {
238+
testMethod(t, r, "POST")
239+
240+
var body TeamMemberAdd
241+
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
242+
t.Errorf("Request body decode error: %v", err)
243+
}
244+
245+
if body.Email != input.Email {
246+
t.Errorf("Request body email = %q, want %q", body.Email, input.Email)
247+
}
248+
if body.Role != input.Role {
249+
t.Errorf("Request body role = %q, want %q", body.Role, input.Role)
250+
}
251+
252+
w.Header().Set("Content-Type", "application/json")
253+
w.WriteHeader(http.StatusCreated)
254+
fmt.Fprint(w, `{"id":"1","team_id":"123","user_email":"newuser@test.local","role":"member","is_active":true}`)
255+
})
256+
257+
ctx := context.Background()
258+
member, _, err := client.Teams.AddMember(ctx, "123", input)
259+
260+
if err != nil {
261+
t.Errorf("Teams.AddMember returned error: %v", err)
262+
}
263+
264+
if member.UserEmail != input.Email {
265+
t.Errorf("Teams.AddMember returned email %q, want %q", member.UserEmail, input.Email)
266+
}
267+
if member.Role != input.Role {
268+
t.Errorf("Teams.AddMember returned role %q, want %q", member.Role, input.Role)
269+
}
270+
}
271+
228272
func TestTeamsService_UpdateMember(t *testing.T) {
229273
client, mux, _, teardown := setup()
230274
defer teardown()

contextforge/types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,12 @@ type TeamMember struct {
10601060
IsActive bool `json:"is_active"`
10611061
}
10621062

1063+
// TeamMemberAdd represents the request body for adding a team member.
1064+
type TeamMemberAdd struct {
1065+
Email string `json:"email"`
1066+
Role string `json:"role"`
1067+
}
1068+
10631069
// TeamMemberUpdate represents the request body for updating a team member's role.
10641070
type TeamMemberUpdate struct {
10651071
Role string `json:"role"`

docs/agents/testing.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,18 @@ Known skipped issue IDs:
3232

3333
- `CONTEXTFORGE-001`
3434
- `CONTEXTFORGE-002`
35+
- `CONTEXTFORGE-005`
36+
- `CONTEXTFORGE-008`
37+
- `CONTEXTFORGE-010`
38+
39+
Resolved issue IDs:
40+
3541
- `CONTEXTFORGE-003`
3642
- `CONTEXTFORGE-004`
37-
- `CONTEXTFORGE-005`
3843
- `CONTEXTFORGE-007`
39-
- `CONTEXTFORGE-008`
4044
- `CONTEXTFORGE-009`
41-
- `CONTEXTFORGE-010`
4245

43-
Resolved issue:
46+
Informational:
4447

4548
- `CONTEXTFORGE-006` (validation error behavior is by design)
4649

docs/upstream-bugs/contextforge-004-teams-auth-individual-endpoints.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
**Bug ID:** CONTEXTFORGE-004
44
**Component:** ContextForge MCP Gateway
5-
**Affected Version:** v0.8.0, v1.0.0-BETA-1, v1.0.0-BETA-2
5+
**Affected Version:** v0.8.0, v1.0.0-BETA-1, v1.0.0-BETA-2 (fixed in v1.0.0-RC1)
66
**Severity:** High
7-
**Status:** Confirmed in v1.0.0-BETA-2 (still valid)
7+
**Status:** FIXED in v1.0.0-RC1
88
**Reported:** 2025-11-09
9-
**Last Validated:** 2026-02-06
9+
**Last Validated:** 2026-03-05
1010

1111
## Summary
1212

13-
Individual team resource endpoints (`GET/PUT/DELETE /teams/{id}/*`) reject valid JWT authentication tokens with "Invalid token" (401 Unauthorized) errors, despite the same token working correctly for team list and create operations. This prevents any read, update, or delete operations on individual teams.
13+
In affected versions, individual team resource endpoints (`GET/PUT/DELETE /teams/{id}/*`) reject valid JWT authentication tokens with "Invalid token" (401 Unauthorized) errors, despite the same token working correctly for team list and create operations. This issue is fixed in ContextForge v1.0.0-RC1.
1414

1515
## Affected Endpoints
1616

@@ -441,19 +441,33 @@ async def get_team(team_id: str, current_user_ctx: dict = Depends(get_current_us
441441

442442
**Report Generated:** 2025-11-09
443443
**Tested Against:** ContextForge v0.8.0
444-
**Validated Against:** ContextForge v1.0.0-BETA-2
444+
**Validated Against:** ContextForge v1.0.0-RC1
445445
**Reporter:** go-contextforge SDK Team
446446

447447
---
448448

449+
## v1.0.0-RC1 Revalidation Notes
450+
451+
**Validated:** 2026-03-05
452+
453+
- **Still Valid?** No. The issue no longer reproduces in the RC1 integration harness.
454+
- **Observed behavior:** `GET`, `PUT`, `DELETE`, member management, invitations, and discovery routes all completed successfully under authenticated SDK calls.
455+
- **SDK action:** Removed the `CONTEXTFORGE-004` skips from team integration coverage and re-enabled the affected scenarios.
456+
457+
### Evidence
458+
459+
- `TestTeamsService_BasicCRUD` passed for get, update, and delete operations.
460+
- `TestTeamsService_Members`, `TestTeamsService_Invitations`, and `TestTeamsService_Discovery` all passed against the RC1 harness.
461+
- The full `make integration-test-all` run passed with the RC1 harness after switching tests to reuse the pre-generated setup token.
462+
449463
## v1.0.0-BETA-2 Revalidation Notes
450464

451465
**Validated:** 2026-02-06
452466

453467
- **Still Valid?** Yes. Individual teams endpoints remain broken under valid auth contexts.
454468
- **Is it actually a bug?** Yes. Authenticated users should not receive auth failures for valid routes/permissions.
455469

456-
### Evidence
470+
### Historical Evidence
457471

458472
- `teams.get_team(...)` still raises authentication errors in live checks.
459473
- Route order still allows `/{team_id}` to shadow `/discover` in `mcpgateway/routers/teams.py`.

docs/upstream-sync/reconcile-report.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,41 @@
11
# ContextForge Upstream Reconciliation Report
22

3-
- Generated: 2026-02-05T23:02:44-05:00
3+
- Generated: 2026-03-05T23:05:14-05:00
44
- SDK root: `/Users/lee/Dev/leefowlercu/go-contextforge`
55
- Upstream: `https://github.com/IBM/mcp-context-forge.git`
66
- Channel: `all semver tags`
77

88
## Version Discovery
99

10-
- README tested-against: `v1.0.0-BETA-2` (high)
11-
- CLAUDE.md mention: `v0.8.0` (low)
10+
- README tested-against: `v1.0.0-RC1` (high)
1211
- CLAUDE.md mention: `v1.0.0` (low)
1312
- CLAUDE.md mention: `v0.8.0` (low)
1413
- CLAUDE.md mention: `v1.0.0-BETA-1` (low)
14+
- CLAUDE.md mention: `v1.0.0-RC1` (low)
1515

1616
- Selected current tag: `v1.0.0-BETA-2`
17-
- Selected from: README tested-against (`v1.0.0-BETA-2`)
18-
- Selected target tag: `v1.0.0-BETA-2`
19-
- Latest upstream semver tag: `v1.0.0-BETA-2`
17+
- Selected from: override (`v1.0.0-BETA-2`)
18+
- Selected target tag: `v1.0.0-RC1`
19+
- Latest upstream semver tag: `v1.0.0-RC1`
2020
- Latest upstream stable tag: `v0.9.0`
2121

2222
## Newer Tags
2323

24-
- None
24+
- `v1.0.0-RC1`
2525

2626
## Service Delta
2727

2828
- Added services: none
2929
- Removed services: none
30-
- Changed existing services: 0
30+
- Changed existing services: 5
31+
32+
### Endpoint Changes by Service
33+
34+
- `admin`: +13 / -0
35+
- `auth`: +4 / -0
36+
- `roots`: +3 / -0
37+
- `.well-known`: +1 / -0
38+
- `teams`: +1 / -0
3139

3240
## SDK Mapping Impact
3341

0 commit comments

Comments
 (0)