Commit b2c14a1
committed
Fix OAuthClientProvider._initialize() to enable transparent token refresh
Two bugs in OAuthClientProvider._initialize() combine to force interactive
re-authentication on every process restart, even when a valid refresh_token
is on disk and the IdP would happily exchange it.
Bug 1: _initialize() loads tokens but never calls update_token_expiry(),
so context.token_expiry_time stays None. is_token_valid() then
short-circuits to True regardless of whether the access_token is actually
expired, and the refresh-on-expiry guard in async_auth_flow never fires.
Bug 2: _refresh_token() falls back to urljoin(base, '/token') when
context.oauth_metadata is unset, which gives the wrong endpoint for any
IdP that mounts its token endpoint at a non-root path (Hydra/Ory:
/oauth/token, Auth0: /oauth/token, Keycloak:
/protocol/openid-connect/token, etc.). The refresh grant silently 404s.
This affects every MCP client using OAuthClientProvider against an IdP
with short-lived access_tokens and a Hydra-style token endpoint —
including Fold MCP, Notion, GitHub PAT-rotated OAuth, etc.
Fix:
- Mirror what set_tokens() does on the write path: call
update_token_expiry() after loading tokens so is_token_valid() returns
the correct boolean.
- Call storage.load_oauth_metadata() (when implemented, via getattr
guard) to pre-populate context.oauth_metadata. The TokenStorage
Protocol is unchanged — load_oauth_metadata is treated as an optional
extension. SDK-provided storages that don't implement it remain
unaffected; downstream clients (e.g. hermes-agent's HermesTokenStorage)
that already implement it get the fix transparently.
Fixes #3250
Verified live against https://mcp.fold.money with a 16-minute repro:
without the fix, every restart sent an expired access_token, got a 401,
and bounced the user through the full re-auth flow. With the fix,
the refresh grant returns HTTP 200 transparently, fold.json mtime
advances, and the MCP call returns real data.
Tests: three new tests added in tests/client/test_auth.py
(TestOAuthFallback class) — all 3 fail against the unpatched code
(negative control) and pass against the patched code. Full test suite
(5333 tests) still passes.
AI disclosure: Drafted with AI assistance (GPT-class model). The bug
analysis, code-path tracing, fix design, and live verification were
all done by a human reviewer who understood every line.1 parent a4f4ccd commit b2c14a1
2 files changed
Lines changed: 141 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
551 | 552 | | |
552 | 553 | | |
553 | 554 | | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
554 | 587 | | |
555 | 588 | | |
556 | 589 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
636 | 636 | | |
637 | 637 | | |
638 | 638 | | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
639 | 747 | | |
640 | 748 | | |
641 | 749 | | |
| |||
0 commit comments