MCP server¶
DataHub MCP server (datahub-mcp-k8s) is a Kubernetes operator for the DataHub MCP server, the Model Context Protocol interface to the catalog. It is an optional extension of a DataHub deployment: it runs alongside datahub-k8s and relates to it. See Deploy the MCP server.
Workload¶
Property |
Value |
|---|---|
Container |
|
Port |
8000 |
Transport |
Streamable HTTP, stateless (no MCP session between requests) |
Workload |
|
Juju |
3.4 or later |
HTTP routes¶
Route |
Authentication |
Description |
|---|---|---|
|
Bearer token, when an identity provider is related |
The MCP endpoint. |
|
None |
Health route, also used by the Pebble check. |
|
None |
RFC 9728 resource metadata, naming the authorization server. Advertised in the |
|
None |
RFC 8414 metadata, served only when the charm fronts Google as an OAuth proxy. |
|
None |
Authorization endpoint of the OAuth proxy, served only when the charm fronts Google. Where a caller sends the user to sign in. |
|
Client credentials |
Token endpoint of the OAuth proxy, served only when the charm fronts Google. Exchanges an authorization code, and refreshes. |
|
None |
RFC 7591 dynamic client registration, served only when the charm fronts Google and |
|
None |
Redirect URI of the OAuth proxy, served only when the charm fronts Google. Register it on the Google client, alongside the redirect URI of any client configured against Google directly. |
The .well-known documents are served at the root of the host, so the server needs a hostname of its own rather than a path on another one.
Relation endpoints¶
Required¶
Endpoint |
Interface |
Description |
|---|---|---|
|
|
GMS URL and the access token of a dedicated service account, provided by datahub-k8s. Single relation. |
Optional¶
Endpoint |
Interface |
Description |
|---|---|---|
|
|
Publishes the endpoint at an external URL. Required for client authentication, and the URL must be HTTPS. |
|
|
OIDC credentials used to authenticate callers, from the Canonical Identity Platform or an oauth-external-idp-integrator. Without it, callers are not authenticated. |
Tools¶
The read-only tool set is served by default:
Tool |
Description |
|---|---|
|
Full-text search across catalog entities, with filters and sorting. |
|
Fetch one or more entities by URN, with their properties, ownership, tags, and glossary terms. |
|
Walk upstream or downstream lineage of an entity, for a whole dataset or a single column. |
|
Return the lineage paths connecting two entities or columns, including the intermediate steps. |
|
List the schema fields of a dataset, with keyword filtering and pagination. |
|
Return the SQL queries recorded against a dataset or column. |
enable-mutation-tools=true additionally serves the write tools: add_tags, remove_tags, add_terms, remove_terms, add_owners, remove_owners, set_domains, remove_domains, update_description, add_structured_properties, and remove_structured_properties. Writes are attributed to the shared service account, which holds no write privileges unless granted them in DataHub.
Service account¶
The DataHub charm creates one service account per datahub-client relation:
Resource |
Naming pattern |
Notes |
|---|---|---|
Service account |
|
Created with no privileges of its own; inherits the DataHub default all-users policies, which grant metadata read. |
Access token |
Non-expiring, passed in a Juju secret granted to the relation |
Never written to relation data, to charm configuration, or to the logs. Deleted with the service account when the relation is removed. |
Client registration¶
A caller needs an OAuth client before it can authenticate a user, and there are two ways for it to hold one.
How the caller obtains a client |
Example |
|
|---|---|---|
Registers its own |
Dynamically, on first connection, from whichever party registers clients |
An MCP client on a developer’s machine, configured with the URL alone |
Registered in advance |
An operator gives it this deployment’s own client ID and secret |
Gemini Enterprise, configured with Google’s endpoints and those credentials |
Which endpoints a pre-registered caller is given depends on whether it discovers this server. One that reads the resource metadata finds the OAuth proxy and uses /authorize and /token here. One configured from a form does not look, and is given Google’s own https://accounts.google.com/o/oauth2/auth and https://oauth2.googleapis.com/token instead. Both are accepted: the first presents a token this server minted, the second one Google minted, and each is admitted on the client it names.
enable-client-registration=false leaves only the second kind. What that changes depends on which party is the registrar:
Identity provider |
Registrar |
Effect of turning registration off |
|---|---|---|
This server, acting as an OAuth proxy |
|
|
One that registers clients itself (Hydra, Canonical Identity Platform) |
The provider |
The provider cannot be stopped from registering, so tokens are refused instead unless their |
Scaling¶
Identity provider |
Units |
|---|---|
None, or one that registers clients itself (Hydra, Canonical Identity Platform) |
Scalable. The server holds no state; tokens are checked against the provider. |
One. The charm runs an OAuth proxy that is itself the authorization server, holding client registrations and issued tokens in the unit. A restart loses them, and callers that discovered the proxy sign in again; a caller configured against Google directly holds a token no unit had to issue and is unaffected. |
Network egress¶
Fronting Google, the workload validates tokens and exchanges authorization codes server-side and needs egress to oauth2.googleapis.com. The charm forwards the model’s juju-http-proxy, juju-https-proxy, and juju-no-proxy settings to the workload; see Configure model proxies.
Generated reference on Charmhub¶
Configuration options, actions, and relation endpoints are generated from the charm itself and published on Charmhub, they are not duplicated here: