oracle-mcp-common 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ **/__pycache__/**
2
+
3
+ # Virtual environment
4
+ venv/
5
+ .env/
6
+ .venv/
7
+ ENV/
8
+ env/
9
+ env.bak/
10
+ venv.bak/
11
+
12
+ # Python uv
13
+ .python-version
14
+
15
+ # VScode
16
+ .vscode
17
+
18
+ # Mac files
19
+ .DS_Store
20
+
21
+ #IDE
22
+ .idea
23
+
24
+ # test environments
25
+ .env
26
+
27
+ .coverage*
28
+ htmlcov/
29
+
30
+ # Maven
31
+ **/target/
32
+
33
+ # GoldenGate MCP local runtime artifacts
34
+ **/logs/
35
+ **/oracle-goldengate-mcp-server.env
36
+ **/build/**
37
+
38
+
39
+ .csis
@@ -0,0 +1,290 @@
1
+ Metadata-Version: 2.4
2
+ Name: oracle-mcp-common
3
+ Version: 0.1.0
4
+ Summary: Shared utilities for Oracle MCP Python servers
5
+ Project-URL: Documentation, https://github.com/oracle/mcp
6
+ Author-email: Oracle MCP <237432095+oracle-mcp@users.noreply.github.com>
7
+ License-Expression: UPL-1.0
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Requires-Python: >=3.13
12
+ Requires-Dist: fastmcp<4.0.0,>=3.2.4
13
+ Requires-Dist: oci>=2.179.0
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Oracle MCP Common
17
+
18
+ `oracle-mcp-common` is the shared Python library for Oracle MCP servers. It
19
+ provides reusable components that belong in more than one server while keeping
20
+ server-specific tools, client lifecycles, and service behavior in each server.
21
+
22
+ The library currently provides OCI SDK authentication through
23
+ `oracle_mcp_common.auth`. Future shared modules should follow the same
24
+ server-agnostic approach and expose a focused, documented public API.
25
+
26
+ ## Package requirements
27
+
28
+ - Python 3.13 or later
29
+ - OCI Python SDK 2.179.0 or later
30
+ - FastMCP 3.4.2 for the optional HTTP IDCS authentication API
31
+
32
+ An adopting server normally declares a bounded dependency on this package:
33
+
34
+ ```toml
35
+ dependencies = [
36
+ "oracle-mcp-common>=0.1.0,<0.2.0",
37
+ ]
38
+ ```
39
+
40
+ ## Authentication module
41
+
42
+ `oracle_mcp_common.auth` resolves outbound authentication for OCI Python SDK
43
+ clients. It chooses a supported authentication type and returns the SDK-native
44
+ ingredients needed to create a service client.
45
+
46
+ The module owns credential resolution only. Each server continues to own its
47
+ OCI client type, retry and circuit-breaker policy, `additional_user_agent`, and
48
+ client lifecycle.
49
+
50
+ ### Quick start
51
+
52
+ Set up OCI credentials for the authentication type you intend to use, then
53
+ build a context and pass its config and signer to the OCI SDK client.
54
+
55
+ ```python
56
+ import oci
57
+
58
+ from oracle_mcp_common import build_auth_context
59
+
60
+ auth_context = build_auth_context()
61
+ config = {
62
+ **auth_context.config,
63
+ "additional_user_agent": "oci-example-mcp/1.2.3",
64
+ }
65
+ client = oci.object_storage.ObjectStorageClient(config, signer=auth_context.signer)
66
+ ```
67
+
68
+ The returned `AuthContext` contains:
69
+
70
+ | Field | Meaning |
71
+ | --- | --- |
72
+ | `auth_type` | The selected `AuthType`; `auto` is resolved to `api_key` or `security_token`. |
73
+ | `config` | An OCI SDK config dictionary. It contains the resolved `region` when one is available. |
74
+ | `signer` | The OCI SDK signer to pass to a client constructor. |
75
+ | `tenancy_id` | Tenancy metadata when the selected signer or profile supplies it. |
76
+ | `region` | The resolved client region, if available. |
77
+ | `profile_name` | The selected profile for profile-backed authentication; otherwise `None`. |
78
+
79
+ ### Select an authentication type
80
+
81
+ Set `OCI_MCP_AUTH_TYPE`, or pass `AuthOptions(auth_type=...)` to
82
+ `build_auth_context()`. The supported values are:
83
+
84
+ | Type | Credential source | Notes |
85
+ | --- | --- | --- |
86
+ | `auto` | Selected OCI config profile | Uses `security_token` only if the selected profile directly declares `security_token_file`; otherwise uses `api_key`. |
87
+ | `api_key` | Selected OCI config profile | Requires `tenancy`, `user`, `fingerprint`, and `key_file`. The library logs a one-time recommendation to use session-token authentication. |
88
+ | `security_token` | Selected OCI config profile | Requires `security_token_file` directly in the selected profile, plus the API-key fields required to construct its signer. |
89
+ | `identity_domain_upst` | Identity Domains JWT-to-UPST token exchange | Uses file-backed JWT and client-secret inputs. See [Identity Domains token exchange](#identity-domains-token-exchange). |
90
+ | `instance_principal` | OCI instance principal | Intended for OCI compute instances. |
91
+ | `resource_principal` | OCI resource principal | Intended for supported OCI managed-resource environments. |
92
+ | `instance_principal_delegation` | Instance principal and delegation token | Requires a delegation-token file. |
93
+ | `resource_principal_delegation` | Resource principal and delegation token | Requires a delegation-token file. |
94
+ | `oke_workload_identity` | OKE workload identity | Uses the OCI SDK's default service-account token unless an override is supplied. |
95
+
96
+ `auto` intentionally does not probe instance, resource, delegation, or OKE
97
+ principal environments. Select those types explicitly so a deployment's OCI
98
+ identity remains predictable.
99
+
100
+ ### Configuration precedence
101
+
102
+ An explicit non-empty `AuthOptions` value wins over its canonical environment
103
+ variable. Empty strings are treated as unset.
104
+
105
+ | Setting | Precedence, highest first |
106
+ | --- | --- |
107
+ | Authentication type | `AuthOptions.auth_type` → `OCI_MCP_AUTH_TYPE` → supported legacy aliases → `auto` |
108
+ | Config file | `AuthOptions.config_file` → `OCI_CONFIG_FILE` → OCI SDK default location |
109
+ | Profile | `AuthOptions.profile_name` → `OCI_CONFIG_PROFILE` → `ORACLE_MCP_AUTH_PROFILE` → OCI SDK default profile |
110
+ | Region | `AuthOptions.region` → `OCI_REGION` → profile- or signer-derived region |
111
+ | Other type-specific inputs | Their matching `AuthOptions` field → canonical `OCI_MCP_*` variable → documented legacy alias, if one exists |
112
+
113
+ `OCI_REGION` changes the region used for the returned SDK client config. It
114
+ does not change the selected profile, tenancy, signing key, or principal
115
+ credential source.
116
+
117
+ #### Profile-backed authentication
118
+
119
+ `auto`, `api_key`, and `security_token` honor the usual OCI CLI-compatible
120
+ variables: `OCI_CONFIG_FILE` and `OCI_CONFIG_PROFILE`.
121
+
122
+ For safety, `security_token_file` must be declared in the selected profile's
123
+ own section. A value inherited from `[DEFAULT]` is not treated as a session
124
+ token for another profile. This prevents an inherited setting from silently
125
+ changing the OCI principal used by a named API-key profile.
126
+
127
+ Once a selected profile directly declares a session token, the library reports
128
+ an unreadable token or incomplete session configuration instead of falling
129
+ back to API-key authentication.
130
+
131
+ ### Type-specific inputs
132
+
133
+ | Authentication type | Required inputs | Optional inputs |
134
+ | --- | --- | --- |
135
+ | `identity_domain_upst` | `OCI_MCP_IDENTITY_DOMAIN_URL`, `OCI_MCP_UPST_JWT_FILE`, `OCI_MCP_IDENTITY_DOMAIN_CLIENT_ID`, `OCI_MCP_IDENTITY_DOMAIN_CLIENT_SECRET_FILE`, and a region | Explicit `AuthOptions` equivalents |
136
+ | `*_delegation` | `OCI_MCP_DELEGATION_TOKEN_FILE` | Deprecated `OCI_MCP_DELEGATION_TOKEN` compatibility input |
137
+ | `oke_workload_identity` | None | `OCI_MCP_OKE_SERVICE_ACCOUNT_TOKEN_PATH`; deprecated inline-token compatibility input |
138
+ | Principal types | None | `OCI_MCP_TENANCY_ID_OVERRIDE` when signer metadata does not provide a tenancy ID |
139
+
140
+ All file-backed secret values are read as UTF-8 and surrounding whitespace is
141
+ trimmed. The library reports the variable name when a value is absent,
142
+ unreadable, or empty, without including secret contents in the error.
143
+
144
+ ### Identity Domains token exchange
145
+
146
+ Use `identity_domain_upst` when a file-backed Identity Domains service-bearer
147
+ JWT must be exchanged for an OCI User Principal Security Token (UPST).
148
+
149
+ ```bash
150
+ export OCI_MCP_AUTH_TYPE=identity_domain_upst
151
+ export OCI_MCP_IDENTITY_DOMAIN_URL=https://example.identity.oraclecloud.com
152
+ export OCI_MCP_UPST_JWT_FILE=/var/run/secrets/identity/jwt
153
+ export OCI_MCP_IDENTITY_DOMAIN_CLIENT_ID=example-client-id
154
+ export OCI_MCP_IDENTITY_DOMAIN_CLIENT_SECRET_FILE=/var/run/secrets/identity/client-secret
155
+ export OCI_REGION=us-chicago-1
156
+ ```
157
+
158
+ The URL must be an absolute `https://` URL with a host. The Identity Domain
159
+ must have an Identity Propagation Trust that accepts the JWT and an OAuth client
160
+ authorized for token exchange.
161
+
162
+ The JWT file is read again when the OCI SDK refreshes the UPST, so a rotated JWT
163
+ at the same path can be observed by an existing signer. The client secret is
164
+ read when the signer is created; rotating that secret requires a controlled
165
+ process restart that recreates the signer and every cached OCI client. A
166
+ replacement process should complete an initial token exchange before it accepts
167
+ traffic.
168
+
169
+ This outbound token-exchange type is independent of inbound HTTP MCP OAuth.
170
+ It does not read request access tokens or FastMCP transport configuration.
171
+
172
+ ### HTTP IDCS authentication
173
+
174
+ Use the HTTP IDCS API when an HTTP MCP server must authenticate each caller
175
+ through OCI IAM and make OCI SDK calls as that caller. This is intentionally a
176
+ different path from `build_auth_context()`: stdio continues to use the flexible
177
+ OCI profile, principal, and service-bearer authentication modes above.
178
+
179
+ At startup, build the HTTP policy with the scopes required by the server and
180
+ assign its provider to FastMCP. During an authenticated request, pass the
181
+ request token explicitly to create an OCI SDK context.
182
+
183
+ ```python
184
+ import oci
185
+ from fastmcp.server.dependencies import get_access_token
186
+
187
+ from oracle_mcp_common import build_idcs_http_auth
188
+
189
+ http_auth = build_idcs_http_auth(
190
+ ["openid", "profile", "email", "oci_mcp.example.invoke"]
191
+ )
192
+ mcp.auth = http_auth.provider
193
+
194
+ # Call only while handling an authenticated HTTP request.
195
+ request_token = get_access_token()
196
+ request_auth = http_auth.context_for(request_token.token)
197
+ config = {
198
+ **request_auth.config,
199
+ "additional_user_agent": "oci-example-mcp/1.2.3",
200
+ }
201
+ client = oci.object_storage.ObjectStorageClient(config, signer=request_auth.signer)
202
+ ```
203
+
204
+ `build_idcs_http_auth()` validates the provider configuration before it creates
205
+ FastMCP's `OCIProvider`. It does not inspect `ORACLE_MCP_HOST` or
206
+ `ORACLE_MCP_PORT`, start the listener, assign `mcp.auth`, read FastMCP request
207
+ context, create a service client, or set `additional_user_agent`; the adopting
208
+ server owns each of those steps.
209
+
210
+ | Setting | Purpose |
211
+ | --- | --- |
212
+ | `IDCS_DOMAIN` | Identity Domains host, such as `example.identity.oraclecloud.com`, or an absolute `https://` origin. |
213
+ | `IDCS_CLIENT_ID` / `IDCS_CLIENT_SECRET` | OAuth client used for the provider and request-token exchange. Keep the secret in the deployment secret store. |
214
+ | `IDCS_AUDIENCE` | Audience configured for the MCP OAuth client. |
215
+ | `ORACLE_MCP_BASE_URL` | Absolute public HTTP or HTTPS server URL; include a mount path when applicable. Register `${ORACLE_MCP_BASE_URL}/auth/callback` with the OCI IAM confidential application. |
216
+ | `OCI_REGION` | Region used for the returned OCI SDK context, unless `context_for(..., region=...)` supplies one explicitly. |
217
+
218
+ The HTTP access token is required for `context_for()` and is never read from a
219
+ global FastMCP context by the library. Treat each returned signer and any OCI
220
+ client built with it as caller-specific: do not cache it globally or reuse it
221
+ for another request. Provider configuration and token-exchange errors identify
222
+ missing settings but never include access-token or client-secret values.
223
+
224
+ ### Delegation and OKE token inputs
225
+
226
+ For delegation types, use a mounted file:
227
+
228
+ ```bash
229
+ export OCI_MCP_AUTH_TYPE=instance_principal_delegation
230
+ export OCI_MCP_DELEGATION_TOKEN_FILE=/var/run/secrets/oci/delegation-token
231
+ ```
232
+
233
+ Do not set both the file and inline token inputs. Inline delegation tokens are
234
+ compatibility-only because environment variables are more easily exposed in
235
+ process inspection and diagnostics.
236
+
237
+ For OKE workload identity, the default OCI SDK token discovery needs no
238
+ configuration. To use a non-default mounted token, set
239
+ `OCI_MCP_OKE_SERVICE_ACCOUNT_TOKEN_PATH`. Do not set both the path and the
240
+ deprecated inline token input.
241
+
242
+ ### Compatibility aliases
243
+
244
+ Canonical `OCI_MCP_*` inputs take precedence. The following aliases are
245
+ accepted only during the migration window and emit a one-time deprecation
246
+ warning when used:
247
+
248
+ | Canonical input | Supported legacy aliases |
249
+ | --- | --- |
250
+ | `OCI_MCP_AUTH_TYPE` | `OCI_IOT_AUTH_TYPE`, `OCI_AUTH_TYPE`, `ORACLE_MCP_AUTH_METHOD` |
251
+ | `OCI_CONFIG_PROFILE` | `ORACLE_MCP_AUTH_PROFILE` |
252
+ | `OCI_MCP_DELEGATION_TOKEN_FILE` | `OCI_IOT_DELEGATION_TOKEN` (inline token) |
253
+ | `OCI_MCP_OKE_SERVICE_ACCOUNT_TOKEN_PATH` | `OCI_IOT_OKE_SERVICE_ACCOUNT_TOKEN_PATH` |
254
+ | Deprecated OKE inline token | `OCI_IOT_OKE_SERVICE_ACCOUNT_TOKEN` |
255
+ | `OCI_MCP_TENANCY_ID_OVERRIDE` | `OCI_IOT_TENANCY_ID_OVERRIDE`, `TENANCY_ID_OVERRIDE` |
256
+
257
+ The compatibility window begins with version 0.1.0 and ends no earlier than the
258
+ later of 180 days or two published adopter-server release waves. Removals are
259
+ planned no earlier than version 0.2.0.
260
+
261
+ ### Public API
262
+
263
+ ```python
264
+ from oracle_mcp_common import (
265
+ AuthContext,
266
+ AuthOptions,
267
+ AuthType,
268
+ build_auth_context,
269
+ profile_declares_security_token,
270
+ )
271
+ ```
272
+
273
+ Use `profile_declares_security_token(config_file, profile_name)` when a caller
274
+ needs the same inheritance-safe classification without constructing an OCI SDK
275
+ signer. For example, an OCI CLI wrapper can use it to decide whether an
276
+ explicit `--auth` flag is appropriate.
277
+
278
+ ## Development
279
+
280
+ From the repository root, run the package test suite with:
281
+
282
+ ```bash
283
+ make test project=common
284
+ ```
285
+
286
+ Run the repository Python lint check after source changes:
287
+
288
+ ```bash
289
+ make lint
290
+ ```
@@ -0,0 +1,275 @@
1
+ # Oracle MCP Common
2
+
3
+ `oracle-mcp-common` is the shared Python library for Oracle MCP servers. It
4
+ provides reusable components that belong in more than one server while keeping
5
+ server-specific tools, client lifecycles, and service behavior in each server.
6
+
7
+ The library currently provides OCI SDK authentication through
8
+ `oracle_mcp_common.auth`. Future shared modules should follow the same
9
+ server-agnostic approach and expose a focused, documented public API.
10
+
11
+ ## Package requirements
12
+
13
+ - Python 3.13 or later
14
+ - OCI Python SDK 2.179.0 or later
15
+ - FastMCP 3.4.2 for the optional HTTP IDCS authentication API
16
+
17
+ An adopting server normally declares a bounded dependency on this package:
18
+
19
+ ```toml
20
+ dependencies = [
21
+ "oracle-mcp-common>=0.1.0,<0.2.0",
22
+ ]
23
+ ```
24
+
25
+ ## Authentication module
26
+
27
+ `oracle_mcp_common.auth` resolves outbound authentication for OCI Python SDK
28
+ clients. It chooses a supported authentication type and returns the SDK-native
29
+ ingredients needed to create a service client.
30
+
31
+ The module owns credential resolution only. Each server continues to own its
32
+ OCI client type, retry and circuit-breaker policy, `additional_user_agent`, and
33
+ client lifecycle.
34
+
35
+ ### Quick start
36
+
37
+ Set up OCI credentials for the authentication type you intend to use, then
38
+ build a context and pass its config and signer to the OCI SDK client.
39
+
40
+ ```python
41
+ import oci
42
+
43
+ from oracle_mcp_common import build_auth_context
44
+
45
+ auth_context = build_auth_context()
46
+ config = {
47
+ **auth_context.config,
48
+ "additional_user_agent": "oci-example-mcp/1.2.3",
49
+ }
50
+ client = oci.object_storage.ObjectStorageClient(config, signer=auth_context.signer)
51
+ ```
52
+
53
+ The returned `AuthContext` contains:
54
+
55
+ | Field | Meaning |
56
+ | --- | --- |
57
+ | `auth_type` | The selected `AuthType`; `auto` is resolved to `api_key` or `security_token`. |
58
+ | `config` | An OCI SDK config dictionary. It contains the resolved `region` when one is available. |
59
+ | `signer` | The OCI SDK signer to pass to a client constructor. |
60
+ | `tenancy_id` | Tenancy metadata when the selected signer or profile supplies it. |
61
+ | `region` | The resolved client region, if available. |
62
+ | `profile_name` | The selected profile for profile-backed authentication; otherwise `None`. |
63
+
64
+ ### Select an authentication type
65
+
66
+ Set `OCI_MCP_AUTH_TYPE`, or pass `AuthOptions(auth_type=...)` to
67
+ `build_auth_context()`. The supported values are:
68
+
69
+ | Type | Credential source | Notes |
70
+ | --- | --- | --- |
71
+ | `auto` | Selected OCI config profile | Uses `security_token` only if the selected profile directly declares `security_token_file`; otherwise uses `api_key`. |
72
+ | `api_key` | Selected OCI config profile | Requires `tenancy`, `user`, `fingerprint`, and `key_file`. The library logs a one-time recommendation to use session-token authentication. |
73
+ | `security_token` | Selected OCI config profile | Requires `security_token_file` directly in the selected profile, plus the API-key fields required to construct its signer. |
74
+ | `identity_domain_upst` | Identity Domains JWT-to-UPST token exchange | Uses file-backed JWT and client-secret inputs. See [Identity Domains token exchange](#identity-domains-token-exchange). |
75
+ | `instance_principal` | OCI instance principal | Intended for OCI compute instances. |
76
+ | `resource_principal` | OCI resource principal | Intended for supported OCI managed-resource environments. |
77
+ | `instance_principal_delegation` | Instance principal and delegation token | Requires a delegation-token file. |
78
+ | `resource_principal_delegation` | Resource principal and delegation token | Requires a delegation-token file. |
79
+ | `oke_workload_identity` | OKE workload identity | Uses the OCI SDK's default service-account token unless an override is supplied. |
80
+
81
+ `auto` intentionally does not probe instance, resource, delegation, or OKE
82
+ principal environments. Select those types explicitly so a deployment's OCI
83
+ identity remains predictable.
84
+
85
+ ### Configuration precedence
86
+
87
+ An explicit non-empty `AuthOptions` value wins over its canonical environment
88
+ variable. Empty strings are treated as unset.
89
+
90
+ | Setting | Precedence, highest first |
91
+ | --- | --- |
92
+ | Authentication type | `AuthOptions.auth_type` → `OCI_MCP_AUTH_TYPE` → supported legacy aliases → `auto` |
93
+ | Config file | `AuthOptions.config_file` → `OCI_CONFIG_FILE` → OCI SDK default location |
94
+ | Profile | `AuthOptions.profile_name` → `OCI_CONFIG_PROFILE` → `ORACLE_MCP_AUTH_PROFILE` → OCI SDK default profile |
95
+ | Region | `AuthOptions.region` → `OCI_REGION` → profile- or signer-derived region |
96
+ | Other type-specific inputs | Their matching `AuthOptions` field → canonical `OCI_MCP_*` variable → documented legacy alias, if one exists |
97
+
98
+ `OCI_REGION` changes the region used for the returned SDK client config. It
99
+ does not change the selected profile, tenancy, signing key, or principal
100
+ credential source.
101
+
102
+ #### Profile-backed authentication
103
+
104
+ `auto`, `api_key`, and `security_token` honor the usual OCI CLI-compatible
105
+ variables: `OCI_CONFIG_FILE` and `OCI_CONFIG_PROFILE`.
106
+
107
+ For safety, `security_token_file` must be declared in the selected profile's
108
+ own section. A value inherited from `[DEFAULT]` is not treated as a session
109
+ token for another profile. This prevents an inherited setting from silently
110
+ changing the OCI principal used by a named API-key profile.
111
+
112
+ Once a selected profile directly declares a session token, the library reports
113
+ an unreadable token or incomplete session configuration instead of falling
114
+ back to API-key authentication.
115
+
116
+ ### Type-specific inputs
117
+
118
+ | Authentication type | Required inputs | Optional inputs |
119
+ | --- | --- | --- |
120
+ | `identity_domain_upst` | `OCI_MCP_IDENTITY_DOMAIN_URL`, `OCI_MCP_UPST_JWT_FILE`, `OCI_MCP_IDENTITY_DOMAIN_CLIENT_ID`, `OCI_MCP_IDENTITY_DOMAIN_CLIENT_SECRET_FILE`, and a region | Explicit `AuthOptions` equivalents |
121
+ | `*_delegation` | `OCI_MCP_DELEGATION_TOKEN_FILE` | Deprecated `OCI_MCP_DELEGATION_TOKEN` compatibility input |
122
+ | `oke_workload_identity` | None | `OCI_MCP_OKE_SERVICE_ACCOUNT_TOKEN_PATH`; deprecated inline-token compatibility input |
123
+ | Principal types | None | `OCI_MCP_TENANCY_ID_OVERRIDE` when signer metadata does not provide a tenancy ID |
124
+
125
+ All file-backed secret values are read as UTF-8 and surrounding whitespace is
126
+ trimmed. The library reports the variable name when a value is absent,
127
+ unreadable, or empty, without including secret contents in the error.
128
+
129
+ ### Identity Domains token exchange
130
+
131
+ Use `identity_domain_upst` when a file-backed Identity Domains service-bearer
132
+ JWT must be exchanged for an OCI User Principal Security Token (UPST).
133
+
134
+ ```bash
135
+ export OCI_MCP_AUTH_TYPE=identity_domain_upst
136
+ export OCI_MCP_IDENTITY_DOMAIN_URL=https://example.identity.oraclecloud.com
137
+ export OCI_MCP_UPST_JWT_FILE=/var/run/secrets/identity/jwt
138
+ export OCI_MCP_IDENTITY_DOMAIN_CLIENT_ID=example-client-id
139
+ export OCI_MCP_IDENTITY_DOMAIN_CLIENT_SECRET_FILE=/var/run/secrets/identity/client-secret
140
+ export OCI_REGION=us-chicago-1
141
+ ```
142
+
143
+ The URL must be an absolute `https://` URL with a host. The Identity Domain
144
+ must have an Identity Propagation Trust that accepts the JWT and an OAuth client
145
+ authorized for token exchange.
146
+
147
+ The JWT file is read again when the OCI SDK refreshes the UPST, so a rotated JWT
148
+ at the same path can be observed by an existing signer. The client secret is
149
+ read when the signer is created; rotating that secret requires a controlled
150
+ process restart that recreates the signer and every cached OCI client. A
151
+ replacement process should complete an initial token exchange before it accepts
152
+ traffic.
153
+
154
+ This outbound token-exchange type is independent of inbound HTTP MCP OAuth.
155
+ It does not read request access tokens or FastMCP transport configuration.
156
+
157
+ ### HTTP IDCS authentication
158
+
159
+ Use the HTTP IDCS API when an HTTP MCP server must authenticate each caller
160
+ through OCI IAM and make OCI SDK calls as that caller. This is intentionally a
161
+ different path from `build_auth_context()`: stdio continues to use the flexible
162
+ OCI profile, principal, and service-bearer authentication modes above.
163
+
164
+ At startup, build the HTTP policy with the scopes required by the server and
165
+ assign its provider to FastMCP. During an authenticated request, pass the
166
+ request token explicitly to create an OCI SDK context.
167
+
168
+ ```python
169
+ import oci
170
+ from fastmcp.server.dependencies import get_access_token
171
+
172
+ from oracle_mcp_common import build_idcs_http_auth
173
+
174
+ http_auth = build_idcs_http_auth(
175
+ ["openid", "profile", "email", "oci_mcp.example.invoke"]
176
+ )
177
+ mcp.auth = http_auth.provider
178
+
179
+ # Call only while handling an authenticated HTTP request.
180
+ request_token = get_access_token()
181
+ request_auth = http_auth.context_for(request_token.token)
182
+ config = {
183
+ **request_auth.config,
184
+ "additional_user_agent": "oci-example-mcp/1.2.3",
185
+ }
186
+ client = oci.object_storage.ObjectStorageClient(config, signer=request_auth.signer)
187
+ ```
188
+
189
+ `build_idcs_http_auth()` validates the provider configuration before it creates
190
+ FastMCP's `OCIProvider`. It does not inspect `ORACLE_MCP_HOST` or
191
+ `ORACLE_MCP_PORT`, start the listener, assign `mcp.auth`, read FastMCP request
192
+ context, create a service client, or set `additional_user_agent`; the adopting
193
+ server owns each of those steps.
194
+
195
+ | Setting | Purpose |
196
+ | --- | --- |
197
+ | `IDCS_DOMAIN` | Identity Domains host, such as `example.identity.oraclecloud.com`, or an absolute `https://` origin. |
198
+ | `IDCS_CLIENT_ID` / `IDCS_CLIENT_SECRET` | OAuth client used for the provider and request-token exchange. Keep the secret in the deployment secret store. |
199
+ | `IDCS_AUDIENCE` | Audience configured for the MCP OAuth client. |
200
+ | `ORACLE_MCP_BASE_URL` | Absolute public HTTP or HTTPS server URL; include a mount path when applicable. Register `${ORACLE_MCP_BASE_URL}/auth/callback` with the OCI IAM confidential application. |
201
+ | `OCI_REGION` | Region used for the returned OCI SDK context, unless `context_for(..., region=...)` supplies one explicitly. |
202
+
203
+ The HTTP access token is required for `context_for()` and is never read from a
204
+ global FastMCP context by the library. Treat each returned signer and any OCI
205
+ client built with it as caller-specific: do not cache it globally or reuse it
206
+ for another request. Provider configuration and token-exchange errors identify
207
+ missing settings but never include access-token or client-secret values.
208
+
209
+ ### Delegation and OKE token inputs
210
+
211
+ For delegation types, use a mounted file:
212
+
213
+ ```bash
214
+ export OCI_MCP_AUTH_TYPE=instance_principal_delegation
215
+ export OCI_MCP_DELEGATION_TOKEN_FILE=/var/run/secrets/oci/delegation-token
216
+ ```
217
+
218
+ Do not set both the file and inline token inputs. Inline delegation tokens are
219
+ compatibility-only because environment variables are more easily exposed in
220
+ process inspection and diagnostics.
221
+
222
+ For OKE workload identity, the default OCI SDK token discovery needs no
223
+ configuration. To use a non-default mounted token, set
224
+ `OCI_MCP_OKE_SERVICE_ACCOUNT_TOKEN_PATH`. Do not set both the path and the
225
+ deprecated inline token input.
226
+
227
+ ### Compatibility aliases
228
+
229
+ Canonical `OCI_MCP_*` inputs take precedence. The following aliases are
230
+ accepted only during the migration window and emit a one-time deprecation
231
+ warning when used:
232
+
233
+ | Canonical input | Supported legacy aliases |
234
+ | --- | --- |
235
+ | `OCI_MCP_AUTH_TYPE` | `OCI_IOT_AUTH_TYPE`, `OCI_AUTH_TYPE`, `ORACLE_MCP_AUTH_METHOD` |
236
+ | `OCI_CONFIG_PROFILE` | `ORACLE_MCP_AUTH_PROFILE` |
237
+ | `OCI_MCP_DELEGATION_TOKEN_FILE` | `OCI_IOT_DELEGATION_TOKEN` (inline token) |
238
+ | `OCI_MCP_OKE_SERVICE_ACCOUNT_TOKEN_PATH` | `OCI_IOT_OKE_SERVICE_ACCOUNT_TOKEN_PATH` |
239
+ | Deprecated OKE inline token | `OCI_IOT_OKE_SERVICE_ACCOUNT_TOKEN` |
240
+ | `OCI_MCP_TENANCY_ID_OVERRIDE` | `OCI_IOT_TENANCY_ID_OVERRIDE`, `TENANCY_ID_OVERRIDE` |
241
+
242
+ The compatibility window begins with version 0.1.0 and ends no earlier than the
243
+ later of 180 days or two published adopter-server release waves. Removals are
244
+ planned no earlier than version 0.2.0.
245
+
246
+ ### Public API
247
+
248
+ ```python
249
+ from oracle_mcp_common import (
250
+ AuthContext,
251
+ AuthOptions,
252
+ AuthType,
253
+ build_auth_context,
254
+ profile_declares_security_token,
255
+ )
256
+ ```
257
+
258
+ Use `profile_declares_security_token(config_file, profile_name)` when a caller
259
+ needs the same inheritance-safe classification without constructing an OCI SDK
260
+ signer. For example, an OCI CLI wrapper can use it to decide whether an
261
+ explicit `--auth` flag is appropriate.
262
+
263
+ ## Development
264
+
265
+ From the repository root, run the package test suite with:
266
+
267
+ ```bash
268
+ make test project=common
269
+ ```
270
+
271
+ Run the repository Python lint check after source changes:
272
+
273
+ ```bash
274
+ make lint
275
+ ```
@@ -0,0 +1,30 @@
1
+ """
2
+ Copyright (c) 2026, Oracle and/or its affiliates.
3
+ Licensed under the Universal Permissive License v1.0 as shown at
4
+ https://oss.oracle.com/licenses/upl.
5
+ """
6
+
7
+ from .auth import (
8
+ AuthContext,
9
+ AuthType,
10
+ AuthOptions,
11
+ IDCSHttpAuth,
12
+ IDCSHttpAuthContext,
13
+ IDCSHttpAuthOptions,
14
+ build_auth_context,
15
+ build_idcs_http_auth,
16
+ profile_declares_security_token,
17
+ )
18
+
19
+ __all__ = [
20
+ "AuthContext",
21
+ "AuthType",
22
+ "AuthOptions",
23
+ "IDCSHttpAuth",
24
+ "IDCSHttpAuthContext",
25
+ "IDCSHttpAuthOptions",
26
+ "build_auth_context",
27
+ "build_idcs_http_auth",
28
+ "profile_declares_security_token",
29
+ ]
30
+ __version__ = "0.1.0"