1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! MCP credential provider (v2.1).
//!
//! Abstracts how an MCP transport obtains the credentials it needs to
//! authenticate against a server (API key, OAuth bearer token, ...).
//! Implementations live outside `oxi-agent` so that the storage backend
//! (e.g. `oxi-cli`'s auth store) can be swapped without changing the
//! transport code.
//!
//! The trait is deliberately narrow — two methods, both infallible from
//! the transport's point of view (they return `Option<Credential>` and
//! the transport simply omits the `Authorization` header when no
//! credential is available). It is **not** promoted to a full SDK port
//! (see `docs/designs/2026-06-19-mcp-v2-conformance-transports.md` §D11
//! / §5.2): MCP is an agent feature, not infrastructure, and most
//! products are happy with the noop default plus a per-product
//! implementation injected via [`crate::mcp::McpManager::set_credential_provider`].
use async_trait;
/// A single credential materialising an MCP server's authentication.
///
/// The transport treats this as opaque and only consumes [`Self::access_token`]
/// to populate the `Authorization: Bearer …` header. Refresh material
/// (e.g. OAuth refresh token) is handled by [`McpCredentialProvider::refresh`]
/// and is never read by the transport itself.
/// Source of authentication material for an MCP transport.
///
/// `server` is the configured server name (e.g. `"github"`) and `url`
/// is the MCP endpoint the transport is connecting to. Providers may
/// key storage on either or both. Implementations should be cheap to
/// call — `access_token` is consulted on every connect, `refresh` is
/// called at most once per request on a `401`/`403` response.
/// Default no-op provider. Returns `None` for every lookup, which tells
/// transports to connect without authentication. Used by
/// [`crate::mcp::McpManager`] when no real provider has been injected.
;