Skip to content

DEV-215183 - Add Collibra Data Access MCP tools - #124

Open
wouterc-collibra wants to merge 31 commits into
mainfrom
feat/DEV-215183-data-access-tools
Open

DEV-215183 - Add Collibra Data Access MCP tools#124
wouterc-collibra wants to merge 31 commits into
mainfrom
feat/DEV-215183-data-access-tools

Conversation

@wouterc-collibra

Copy link
Copy Markdown

🎯 What does this PR do?

Adds MCP tools for Collibra Data Access:

  • search_data_access_identities - search Data Access users by name/email
  • search_data_access_objects - search data objects (tables, columns, schemas, views, etc.)
  • get_data_access_data_source - resolve a data source ID to name/type/description
  • get_data_access_control_details - retrieve details of a single access control
  • check_user_data_object_access - check whether a user has access to one or more data objects
  • create_asset_access_request - create a Data Access request for a catalog asset

Also includes the collibra/data-access skill guiding agents through WHO/WHAT resolution before checking access or creating requests.

All six are behind the data-access experimental flag

The set is off by default and registers only under --experimental=data-access (or COLLIBRA_MCP_EXPERIMENTAL=data-access). create_asset_access_request writes to Data Access, so the whole set stays opt-in until it graduates rather than shipping the five read-only tools ahead of it.

Each tool also declares the scope it needs, so an instance without it fails with a named permission rather than an opaque error:

  • all six require dgc.data-access-view-all-access-and-usage
  • create_asset_access_request additionally requires dgc.data-access-create-access-controls

Unfiltered searches are rejected, not silently capped

search_data_access_objects and search_data_access_identities return status validation_error before any request is sent when the call would scan the whole instance — at least one real filter is required (name/dataSources/types/parents/ancestors, and name/email respectively). includeDeleted and pageSize do not count as filters. A pageSize outside 1–25 is rejected the same way instead of being silently clamped, so an agent can never believe it asked for 200 results and received them all.

About create_asset_access_request

Access is requested on a asset, and the WHAT of the request is the Data Access role linked to that asset. The tool resolves the role itself, so the caller never passes a role or a data object.

  • Which assets can be requested is instance configuration, so the roles linked to an asset are read through ListAccessControls rather than inferred from its asset type. Resolution is the same for every asset type — there is no special handling for any particular one. An asset with no active Grant comes back as the no_role_linked status, with whatever is linked in linkedRoles, instead of an error.
  • Beneficiaries are Collibra users and/or groups. Users map to Data Access users by email address, groups to Data Access groups by name — the only identifiers the two systems share. Nothing is created unless every beneficiary maps; failures come back in unresolvedUsers / unresolvedGroups.
  • A purpose and an expiration date are mandatory. The purpose must come from the user and is used as the description, with a note appended stating the request was created by AI.
  • name is optional. Pass it only when the user supplied one; otherwise omit it and Data Access generates a unique name itself. A name that is already taken comes back as status name_conflict with nothing created.
  • A confirm checkpoint guards the write. confirm=false (the default) resolves the asset, the role and every beneficiary and returns status preview with the complete composed request — asset, role, mapped users and groups, description and expiration date — creating nothing. Only confirm=true creates it.

Requires data-access-go-sdk v0.0.73 for the assetIds access control filter.

Jira

DEV-215183

✅ Checklist

  • My code follows the style guidelines of this project.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation (if needed).
  • My commit messages follow the Conventional Commits standard.

wouterc-collibra and others added 30 commits May 8, 2026 16:33
# Conflicts:
#	go.mod
#	go.sum
#	pkg/tools/tools_register.go
# Conflicts:
#	SKILLS.md
#	pkg/tools/register.go
# Conflicts:
#	README.md
#	pkg/tools/register.go
# Conflicts:
#	README.md
#	go.mod
#	go.sum
#	pkg/tools/register.go
… skill doc

get_data_access_control_details was fully implemented but never wired into
RegisterAll after a branch merge dropped it. Also fixes README links that
pointed to the wrong tool directories and removes a stale nextCursor
pagination claim in the data-access SKILL.md that doesn't match the
search_data_access_identities implementation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
go.mod requires go 1.26.5 (data-access-go-sdk needs >=1.26.4), but CI
was pinned to 1.25.0 with GOTOOLCHAIN=local, failing the build step.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Six data-access tools were missing Title and required
mcp.ToolAnnotations fields (OpenWorldHint, IdempotentHint for
read-only tools), failing TestRegisterAll_AllToolsHaveProperAnnotations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
golangci-lint v2.4.0 was built with go1.25 and refuses to lint a
module targeting go1.26.5. Bumping to v2.12.2 (built with a newer
toolchain) unblocks the Lint step.

Also fixes the staticcheck QF1008 findings it then surfaced: several
genqlient-generated SDK types embed a field with the same name as the
struct (e.g. AccessControl.AccessControl.Id), so the outer field name
can be dropped from the selector.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…et_access_request

Access requests are now raised on a Collibra catalog asset rather than on
data objects. The WHAT of the request is the Data Access role linked to the
asset, which the tool resolves itself, so the caller never picks a role or a
data object.

Which assets can be requested is instance configuration, so the roles linked
to an asset are read through ListAccessControls rather than inferred from its
asset type. A Data Product with no requestable role of its own is expanded to
its output ports, and an asset with no active Grant comes back as the
no_role_linked status instead of an error.

Beneficiaries are Collibra users and/or groups: users map to Data Access users
by email address, groups to Data Access groups by name. Nothing is created
unless every beneficiary maps. A purpose and an expiration date are mandatory.

Bumps data-access-go-sdk to v0.0.73 for the assetIds access control filter.

BREAKING CHANGE: create_data_access_request is removed. Requesting access to a
data object directly is no longer supported; access is requested on the
catalog asset that carries the role.
…access_request

The tool treated Data Products as a special case: it expanded a product with
no requestable role of its own into its output ports, offered those ports for
selection, and took an outputPortId to pick one. None of that is needed to
request access, because whether an asset carries a role is already answered by
the roles linked to it.

Resolution is now the same for every asset: read the roles linked to it and
use the active Grant, or return no_role_linked. The outputPortId input, the
outputPorts output and the needs_port_selection status are gone, along with
the relation traversal that found the ports.

Also documents the tool's parameters in the README the way the other tools
document theirs, as prose naming each parameter inline.
Resolve the users and groups holding the OwnerRole on an access control
and return them as `owners`. Owner lookup is supplementary: failures are
logged and the affected owners skipped rather than failing the whole
access control lookup.

Also update the skill guidance to call GRANT access controls "roles" and
to report role owners as the implementors of an access request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The role assignment filter left `inherited` unset, which the API defaults
to true, so owners inherited from ancestor resources were reported as
owners of the access control itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The tool used to withhold the request when no name was given: it derived a
suggestion from the purpose and returned needs_name_confirmation so the agent
could confirm it with the user. That round trip is unnecessary — Data Access
generates a unique name itself when none is sent, so the name is now simply
left out of the mutation unless the user supplied one, and the agent is told
never to invent or ask for a name.

Because access request names must be unique, a supplied name that is already
taken is now reported as status name_conflict instead of a generic failure.
The backend signals this as an InvalidInputError, which is the same type it
uses for every other input problem, so only the "already exists" message is
treated as a conflict; anything else still surfaces as an error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Put the six Data Access tools behind a new `data-access` experimental
feature. create_asset_access_request writes to Data Access, so the whole
set stays opt-in until it graduates.

Declare the permissions each tool actually needs: every tool requires
`dgc.data-access-view-all-access-and-usage`, and create_asset_access_request
additionally requires `dgc.data-access-create-access-controls`.

Reject unfiltered searches on search_data_access_identities and
search_data_access_objects with `validation_error` instead of listing every
user or paging through every data object on the instance, and bound
pageSize to 1-25.

Add a confirm checkpoint to create_asset_access_request: confirm=false (the
default) resolves the asset, role and beneficiaries and returns status
`preview` with everything that would be written, creating nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@svc-snyk-github-jira

svc-snyk-github-jira commented Aug 28, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@wouterc-collibra wouterc-collibra changed the title Add Collibra Data Access MCP tools DEV-215183 - Add Collibra Data Access MCP tools Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants