Skip to content

Releases: txn2/mcp-datahub

mcp-datahub-v1.0.0

28 Feb 05:01
Immutable release. Only release title and notes can be modified.
7e2db69

Choose a tag to compare

Changelog

Features

Others

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_1.0.0_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_1.0.0_darwin_amd64.mcpb
  • Windows: mcp-datahub_1.0.0_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v1.0.0

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_1.0.0_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_1.0.0_linux_amd64.tar.gz

mcp-datahub-v0.8.1

22 Feb 06:37
Immutable release. Only release title and notes can be modified.
61f1068

Choose a tag to compare

Bug Fix: Query Mutation GraphQL Schema Alignment

Fixes a runtime GraphQL validation error that broke CreateQuery and UpdateQuery calls against DataHub v1.3+:

Validation error (FieldUndefined@[createQuery/subjects/datasets]) :
  Field 'datasets' in type 'QuerySubject' is undefined

This affected any downstream consumer calling CreateQuery with dataset associations — including the add_curated_query change type in txn2/mcp-data-platform's apply_knowledge pipeline.

Root Cause

The v0.8.0 Query write API (#63) shipped with a fabricated QuerySubjects wrapper type that doesn't exist in DataHub's GraphQL schema. Three layers were wrong:

Layer Before (wrong) After (correct) DataHub Schema
Mutation response subjects { datasets { dataset { urn } } } subjects { dataset { urn } } QueryEntity.subjects: [QuerySubject!] — flat array, no wrapper
Input variables {"subjects": {"datasets": [{datasetUrn: ...}]}} {"subjects": [{datasetUrn: ...}]} CreateQueryInput.subjects: [CreateQuerySubjectInput!]! — flat array
Go response struct querySubjectsRawOuter wrapping []queryDatasetRef []querySubjectRaw directly No QuerySubjects type exists

Additional Fix

CreateQueryInput.subjects is a required field ([CreateQuerySubjectInput!]!) in the DataHub schema. Previously, when no DatasetURNs were provided, the field was omitted entirely. It is now always sent as an empty array [] when no datasets are specified.

Upgrade

This is a drop-in replacement for v0.8.0. No API changes to CreateQueryInput, UpdateQueryInput, or DeleteQuery — only the wire format and GraphQL text were corrected.

# Go module
go get github.com/txn2/mcp-datahub@v0.8.1

# Homebrew
brew upgrade txn2/tap/mcp-datahub

# Docker
docker pull ghcr.io/txn2/mcp-datahub:v0.8.1

PR: #64


Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.8.1_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.8.1_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.8.1_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.8.1

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.8.1_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.8.1_linux_amd64.tar.gz

mcp-datahub-v0.8.0

21 Feb 22:14
Immutable release. Only release title and notes can be modified.
bef3896

Choose a tag to compare

What's New

Query Entity Write API (Client-Level)

The DataHub client now supports creating, updating, and deleting Query entities via native GraphQL mutations. These are client-level methods only — no new MCP tools are introduced, keeping the tool surface at 19 tools.

// Create a curated query and associate it with datasets
query, err := client.CreateQuery(ctx, client.CreateQueryInput{
    Name:        "Monthly Active Users",
    Description: "Distinct users with at least one login in the past 30 days",
    Statement:   "SELECT COUNT(DISTINCT user_id) FROM logins WHERE login_at > NOW() - INTERVAL '30' DAY",
    Language:    "SQL",                                                  // default if omitted
    DatasetURNs: []string{"urn:li:dataset:(urn:li:dataPlatform:trino,analytics.logins,PROD)"},
})

// Update specific fields (partial update — only non-empty fields are sent)
updated, err := client.UpdateQuery(ctx, client.UpdateQueryInput{
    URN:         query.URN,
    Description: "Updated description with additional context",
})

// Delete (cleanup/composability — not exposed as MCP tool)
err := client.DeleteQuery(ctx, query.URN)

Unlike existing write methods (tags, descriptions, links) that use the REST ingestProposal pattern for aspect-level CRUD, Query entities are first-class entities with dedicated GraphQL mutations. The new methods use Client.Execute() directly against createQuery, updateQuery, and deleteQuery.

Why client-only? The downstream consumer (txn2/mcp-data-platform#141) calls these methods internally from the apply_knowledge pipeline to persist curated queries discovered during agent sessions — they are not agent-facing tools.

PR: #63 | Closes: #62 | Unblocks: txn2/mcp-data-platform#141

Default Tool Icons

All 19 MCP tools now include a DataHub-branded SVG icon in tools/list responses. Clients that support icons (e.g., Claude Desktop) render these alongside tool names.

Icons follow the same three-tier priority system as descriptions and annotations:

  1. Per-registration override via WithIcon() (highest)
  2. Toolkit-level override via WithIcons(map[ToolName][]mcp.Icon)
  3. Built-in default — DataHub SVG (lowest)

PR: #55


Bug Fixes

Non-ASCII Character Support in Write Operations

Fixed ingestProposal validation failures when aspect content contains non-ASCII Unicode characters (em dash , en dash , bullets , CJK characters, accented letters, etc.).

DataHub's GenericAspect.value uses Avro-style byte encoding that only permits U+0000–U+00FF. Go's json.Marshal produces raw UTF-8 for non-ASCII, causing RestLi parameter validation to reject with HTTP 400. The fix escapes all non-ASCII characters to \uXXXX sequences (with surrogate pairs for supplementary characters) before embedding in the aspect value. A fast path skips allocation entirely for pure-ASCII content.

Affects all write operations: UpdateDescription, UpdateColumnDescription, AddTag, AddGlossaryTerm, AddLink.

PR: #61

Glossary Term and Link Write Fixes

Fixed HTTP 422 errors from AddGlossaryTerm() and AddLink() by aligning Go struct definitions with the DataHub PDL schemas:

  • AddGlossaryTerm: Added required auditStamp field that was entirely missing from glossaryTermsAspect
  • AddLink: Fixed JSON field name from "created" to "createStamp" per InstitutionalMemoryMetadata.pdl
  • All writes: Replaced hardcoded time: 0 with real epoch milliseconds via newAuditStamp() helper

PR: #60 | Fixes: #59

Null Aspect Crash Fix + Column Descriptions

Fixed json.Unmarshal panics when DataHub returns HTTP 200 with null/empty aspect values (common for entities where editable aspects have never been written). getAspect() now returns ErrNotFound for these cases, which all read-modify-write callers already handle gracefully.

Also added UpdateColumnDescription(ctx, urn, fieldPath, description) for setting editable descriptions on individual schema fields. The implementation preserves existing field metadata (tags, glossary terms) during updates using json.RawMessage.

PR: #58 | Closes: #57


Upgrading from v0.7.0

No breaking changes. All existing code continues to work without modification.

New features are additive:

  • Query write methods are new additions to Client — no impact on existing API
  • Tool icons are set automatically — no action required
  • All bug fixes are internal to the client's wire format serialization

New Public API

// Query entity CRUD
func (c *Client) CreateQuery(ctx context.Context, input CreateQueryInput) (*types.Query, error)
func (c *Client) UpdateQuery(ctx context.Context, input UpdateQueryInput) (*types.Query, error)
func (c *Client) DeleteQuery(ctx context.Context, urn string) error

// Column-level description updates
func (c *Client) UpdateColumnDescription(ctx context.Context, urn, fieldPath, description string) error

// Icon customization
tools.WithIcons(map[ToolName][]mcp.Icon)  // toolkit-level
tools.WithIcon([]mcp.Icon)                // per-registration

Changelog

Features

  • feat: add write API for Query entities (create, update, delete) (#63)
  • feat: add default icons for all tools (#55)

Bug Fixes

  • fix: escape non-ASCII characters in ingestProposal aspect value (#61)
  • fix: align glossaryTerms and institutionalMemory aspects with DataHub PDL schemas (#60)
  • fix: handle null getAspect responses, add UpdateColumnDescription (#58)

CI

  • ci: bump github/codeql-action from 4.32.2 to 4.32.3 (#56)

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.8.0_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.8.0_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.8.0_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.8.0

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.8.0_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.8.0_linux_amd64.tar.gz

mcp-datahub-v0.7.4

20 Feb 22:36
Immutable release. Only release title and notes can be modified.
1b0bd32

Choose a tag to compare

Bug Fixes

Fix: Non-ASCII characters in DataHub write operations (#61)

Fixed ingestProposal validation failures when writing metadata containing non-ASCII Unicode characters such as em dash (), en dash (), bullets (), or CJK characters.

Root cause: DataHub's GenericAspect.value is typed as bytes in the RestLi PDL schema, which uses Avro-style encoding permitting only characters U+0000–U+00FF. Go's json.Marshal produces raw UTF-8 multi-byte sequences for characters above this range, causing RestLi to reject the request with HTTP 400 before the handler executes.

Fix: Added escapeNonASCII() to convert non-ASCII runes to \uXXXX JSON escape sequences in the inner aspect JSON before embedding in the GenericAspect.value string. Includes a fast path that skips allocation entirely for pure-ASCII content (zero overhead for the common case). Supplementary characters (U+10000+) are encoded as surrogate pairs.

Affected operations: UpdateDescription, UpdateColumnDescription, AddTag, AddGlossaryTerm, AddLink — any write where the aspect content contains characters above U+00FF.

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.7.4_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.7.4_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.7.4_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.7.4

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.7.4_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.7.4_linux_amd64.tar.gz

mcp-datahub-v0.7.3

20 Feb 00:23
Immutable release. Only release title and notes can be modified.
634fd69

Choose a tag to compare

What's New

Fix: AddGlossaryTerm and AddLink 422 Errors (P1)

AddGlossaryTerm() and AddLink() both returned HTTP 422 from DataHub's ingestProposal REST API. Root causes identified by reading the upstream DataHub PDL schemas for DataHub 1.3.0+.

Missing required auditStamp on GlossaryTerms

GlossaryTerms.pdl defines auditStamp: AuditStamp as a required field. Our glossaryTermsAspect struct omitted it entirely, causing DataHub to reject every glossary term write with 422.

Fix: Added AuditStamp field to glossaryTermsAspect. Both AddGlossaryTerm() and RemoveGlossaryTerm() now populate it with the current epoch milliseconds before writing.

Wrong JSON field name on InstitutionalMemory

InstitutionalMemoryMetadata.pdl defines the audit stamp field as createStamp. Our linkElement struct used json:"created", so the field was silently dropped during JSON serialization and DataHub rejected the payload.

Fix: Renamed to CreateStamp with json:"createStamp" tag.

Hardcoded time: 0 in audit stamps

AuditStamp.pdl requires time: Time (epoch milliseconds). The previous code hardcoded 0 with a comment "DataHub will fill this in" — it doesn't.

Fix: New newAuditStamp() helper uses time.Now().UnixMilli(). All write paths now use real timestamps.

Affected methods:

  • AddGlossaryTerm() — now works
  • RemoveGlossaryTerm() — now works
  • AddLink() — now works
  • RemoveLink() — now works (read path fixed for existing links with createStamp)
// These now succeed against DataHub 1.3.0+
err := client.AddGlossaryTerm(ctx,
    "urn:li:dataset:(urn:li:dataPlatform:trino,catalog.schema.table,PROD)",
    "urn:li:glossaryTerm:CustomerPII",
)

err = client.AddLink(ctx,
    "urn:li:dataset:(urn:li:dataPlatform:trino,catalog.schema.table,PROD)",
    "https://wiki.example.com/data-dictionary",
    "Data dictionary for customer tables",
)

Changelog

Bug Fixes

  • e61d7d5 fix: align glossaryTerms and institutionalMemory aspects with DataHub PDL schemas (#60)

Upgrading

This is a backwards-compatible patch release. No configuration changes required.

Go module:

go get github.com/txn2/mcp-datahub@v0.7.3

Breaking change for direct struct users: If you construct linkElement or glossaryTermsAspect structs directly (outside of the provided Add*/Remove* methods), note:

  • linkElement.Created is now linkElement.CreateStamp (JSON tag changed from "created" to "createStamp")
  • glossaryTermsAspect now has a required AuditStamp field

If you only use the public Client methods (AddGlossaryTerm, AddLink, etc.), no code changes are needed.

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.7.3_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.7.3_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.7.3_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.7.3

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.7.3_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.7.3_linux_amd64.tar.gz

mcp-datahub-v0.7.2

19 Feb 23:13
Immutable release. Only release title and notes can be modified.
063b27d

Choose a tag to compare

What's New

Fix: Null Aspect Crash in REST Client (P0)

getAspect() now correctly handles DataHub returning HTTP 200 with a null or empty aspect value. Previously, this caused json.Unmarshal panics when the entity existed but the requested aspect had never been explicitly written.

Root cause: DataHub's REST API returns {"value": null} (not 404) when an entity exists but a specific editable aspect (e.g., editableDatasetProperties, editableSchemaMetadata, globalTags) has never been written. The client was passing this null value directly to json.Unmarshal, which crashed.

Fix: A new isNullOrEmptyJSON() check in getAspect() detects nil, empty, whitespace-only, and null literal responses and returns ErrNotFound. All existing read-modify-write operations (UpdateDescription, AddTag, RemoveTag, AddGlossaryTerm, AddLink) benefit from this fix since they already handle ErrNotFound by initializing a default struct.

Affected scenarios:

  • Entities created via ingestion that have never had editable properties set
  • Entities where tags, glossary terms, or documentation links have never been explicitly written
  • Any apply_knowledge or write operation targeting a "fresh" entity

New: Column-Level Description Writes

Added Client.UpdateColumnDescription(ctx, urn, fieldPath, description) for setting editable descriptions on individual columns/fields via the editableSchemaMetadata REST API aspect.

How it works:

  1. Reads the current editableSchemaMetadata via getAspect() (initializes empty struct if not found)
  2. Finds the matching fieldPath entry or appends a new one
  3. Updates the description while preserving existing globalTags and glossaryTerms as raw JSON
  4. Writes back via postIngestProposal()

Design choice: The editableFieldInfo struct uses json.RawMessage for GlobalTags and GlossaryTerms to avoid deserializing/reserializing metadata the caller didn't intend to modify. This prevents accidental data loss during read-modify-write cycles.

// Update a column description
err := client.UpdateColumnDescription(ctx,
    "urn:li:dataset:(urn:li:dataPlatform:trino,catalog.schema.table,PROD)",
    "email",
    "Customer email address used for account verification",
)

Housekeeping

  • Added #nosec G704 annotations on httpClient.Do() calls where URLs are constructed from configured server endpoints, suppressing false-positive SSRF warnings from gosec

Changelog

Bug Fixes

  • 063b27d fix: handle null getAspect responses, add UpdateColumnDescription (#58)

CI

  • 000985d ci: bump github/codeql-action from 4.32.2 to 4.32.3 (#56)

Upgrading

This is a backwards-compatible patch release. No configuration changes required.

Go module:

go get github.com/txn2/mcp-datahub@v0.7.2

If you use the client library directly: The new UpdateColumnDescription method is additive. No existing APIs changed signatures or behavior, with one exception: getAspect() now returns ErrNotFound for null values where it previously crashed. If you have custom callers that somehow relied on receiving a nil json.RawMessage from getAspect(), they should handle ErrNotFound instead.

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.7.2_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.7.2_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.7.2_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.7.2

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.7.2_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.7.2_linux_amd64.tar.gz

mcp-datahub-v0.7.1

16 Feb 19:57
Immutable release. Only release title and notes can be modified.
fe428c2

Choose a tag to compare

What's New

Default Icons for All Tools

All 19 tool registrations across 15 files now include a default SVG icon in tools/list responses. MCP clients that support icons (e.g., Claude Desktop) will render these alongside tool names, improving visual discoverability.

Read tools (12): datahub_search, datahub_get_entity, datahub_get_schema, datahub_get_lineage, datahub_get_column_lineage, datahub_get_queries, datahub_get_glossary_term, datahub_get_data_product, datahub_list_connections, datahub_list_domains, datahub_list_tags, datahub_list_data_products

Write tools (7): datahub_write_description, datahub_write_tags (dataset + column), datahub_write_glossary_terms (dataset + column), datahub_write_links (dataset + column)

Icon Customization API

A new 3-level priority chain lets consumers override icons at any level:

  1. Per-tool via WithIcon() tool option — highest priority
  2. Toolkit-wide via WithIcons() toolkit option — override specific tools by name
  3. Built-in default — all tools get the DataHub SVG automatically
// Override a specific tool's icon at registration time
toolkit := tools.NewToolkit(client, cfg,
    tools.WithIcons(map[tools.ToolName][]mcp.Icon{
        tools.ToolSearch: {{Source: "https://example.com/custom.svg", MIMEType: "image/svg+xml"}},
    }),
)

This follows the same resolution pattern already used by WithDescriptions() and WithAnnotations().

For mcp-data-platform Users

The mcp-data-platform icons middleware can override these defaults via YAML configuration — no code changes needed:

icons:
  enabled: true
  tools:
    datahub_search:
      src: "https://example.com/custom-datahub.svg"
      mime_type: "image/svg+xml"

Files Changed

File Change
icons/datahub.svg New — default DataHub tool icon
pkg/tools/icons.go New — icon resolution with 3-level priority chain
pkg/tools/icons_test.go New — comprehensive tests for all priority levels
pkg/tools/toolkit.go Add icons map to Toolkit struct
pkg/tools/options.go Add WithIcons() and WithIcon() options
15 tool files Add Icons field to all 19 tool registrations

Upgrading

This is a backward-compatible minor release. No configuration changes are required. Icons appear automatically in tools/list responses — clients that don't support icons simply ignore the field.

go get github.com/txn2/mcp-datahub@v0.7.1

Changelog

  • feat: add default icons for all tools (#55)

Full diff: v0.7.0...v0.7.1

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.7.1_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.7.1_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.7.1_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.7.1

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.7.1_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.7.1_linux_amd64.tar.gz

mcp-datahub-v0.7.0

16 Feb 01:28
Immutable release. Only release title and notes can be modified.
f618d93

Choose a tag to compare

What's New

MCP Tool Annotations

All 19 tools now declare MCP tool annotations per the MCP specification. These behavior hints enable MCP clients to make informed decisions about tool invocation — for example, auto-approving read-only tools or prompting for confirmation before write operations.

Tool Category ReadOnlyHint DestructiveHint IdempotentHint OpenWorldHint
Read tools (12) true (default) true false
Write tools (7) false false true false

Annotations follow the same three-tier priority system as descriptions:

  1. Per-registration override via WithAnnotation() (highest)
  2. Toolkit-level override via WithAnnotations(map[ToolName]*mcp.ToolAnnotations)
  3. Built-in default (lowest)
// Toolkit-level overrides
toolkit := tools.NewToolkit(datahubClient, tools.Config{},
    tools.WithAnnotations(map[tools.ToolName]*mcp.ToolAnnotations{
        tools.ToolSearch: {ReadOnlyHint: true, OpenWorldHint: boolPtr(true)},
    }),
)

// Per-registration override
toolkit.RegisterWith(server, tools.ToolSearch,
    tools.WithAnnotation(&mcp.ToolAnnotations{ReadOnlyHint: true}),
)

// Query defaults programmatically
ann := tools.DefaultAnnotations(tools.ToolSearch)

PR: #54 | Parent: txn2/mcp-data-platform#102

Typed Write Tool Outputs

Write tool handlers now return typed output structs instead of anonymous map[string]string values. This enables downstream consumers to work with structured data without type assertions on raw maps.

Seven new output types in pkg/tools/outputs.go:

Type Fields
UpdateDescriptionOutput URN, Aspect, Action
AddTagOutput / RemoveTagOutput URN, Tag, Aspect, Action
AddGlossaryTermOutput / RemoveGlossaryTermOutput URN, Term, Aspect, Action
AddLinkOutput / RemoveLinkOutput URN, URL, Aspect, Action

ListConnections also returns a typed *ListConnectionsOutput as its second value.

PR: #54 | Parent: txn2/mcp-data-platform#102

Documentation Updates

Comprehensive documentation across 7 files covering the new features:

  • README.md — annotation customization example in library section
  • CLAUDE.md — annotation overrides section
  • Doc site — tools reference (annotation behavior table), API reference (full annotation API + output types), configuration reference (annotation overrides), quickstart (annotation example), MCP protocol concepts (tool annotations)

Upgrading from v0.6.0

No breaking changes. All existing code continues to work without modification.

New features are additive:

  • Tool annotations are set automatically on all tools — no action required
  • Annotation overrides are opt-in via WithAnnotations() / WithAnnotation()
  • Typed output structs are returned as the second value from write handlers; existing code that ignores the second return value is unaffected
  • DefaultAnnotations() is a new public function for querying built-in defaults

Changelog

Features

  • feat: MCP tool annotations, typed write outputs, and documentation (#54)

New Public API

  • tools.WithAnnotations(map[ToolName]*mcp.ToolAnnotations) — toolkit-level annotation overrides
  • tools.WithAnnotation(*mcp.ToolAnnotations) — per-registration annotation override
  • tools.DefaultAnnotations(ToolName) — query default annotations
  • tools.UpdateDescriptionOutput — typed output for description updates
  • tools.AddTagOutput / tools.RemoveTagOutput — typed output for tag operations
  • tools.AddGlossaryTermOutput / tools.RemoveGlossaryTermOutput — typed output for glossary term operations
  • tools.AddLinkOutput / tools.RemoveLinkOutput — typed output for link operations

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.7.0_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.7.0_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.7.0_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.7.0

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.7.0_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.7.0_linux_amd64.tar.gz

mcp-datahub-v0.6.0

15 Feb 20:31
Immutable release. Only release title and notes can be modified.
bb33166

Choose a tag to compare

What's New

Description Override API

Library consumers and standalone users can now customize tool descriptions to match their deployment. The system uses three-tier priority:

  1. Per-registration override via WithDescription() (highest)
  2. Toolkit-level override via WithDescriptions(map[ToolName]string)
  3. Built-in default (lowest)
toolkit := tools.NewToolkit(datahubClient, tools.Config{},
    tools.WithDescriptions(map[tools.ToolName]string{
        tools.ToolSearch: "Search our internal data catalog for datasets and dashboards",
    }),
)

Standalone users can override descriptions via config file:

toolkit:
  descriptions:
    datahub_search: "Search our internal data catalog"

PR: #53 | Issue: #51

Extensions Package (pkg/extensions)

New package providing built-in middleware and YAML/JSON config file support, bringing feature parity with mcp-trino.

Built-in Middleware

Four production-ready middleware implementations, configurable via environment variables:

Middleware Env Variable Default Description
Logging MCP_DATAHUB_EXT_LOGGING false Structured logging with tool name, connection, duration, status
Metrics MCP_DATAHUB_EXT_METRICS false Call counts, error counts, and timing via MetricsCollector interface
Error Hints MCP_DATAHUB_EXT_ERRORS true Appends actionable hints to common error patterns
Metadata MCP_DATAHUB_EXT_METADATA false Appends execution metadata (tool, duration, timestamp) to results
import "github.com/txn2/mcp-datahub/pkg/extensions"

cfg := extensions.FromEnv()
opts := extensions.BuildToolkitOptions(cfg)
toolkit := tools.NewToolkit(datahubClient, toolsCfg, opts...)

Config File Support

Load full server configuration from YAML or JSON files as an alternative to environment variables:

datahub:
  url: https://datahub.example.com
  token: "${DATAHUB_TOKEN}"
  timeout: "30s"
  write_enabled: true

toolkit:
  default_limit: 20
  descriptions:
    datahub_search: "Custom search description for your deployment"

extensions:
  logging: true
  errors: true
serverCfg, _ := extensions.LoadConfig("config.yaml")

Environment variables override file values for sensitive fields. Token values support $VAR / ${VAR} expansion.

PR: #53 | Issue: #51 | Parent: txn2/mcp-data-platform#100

Enhanced Tool Descriptions

Improved descriptions for 6 tools with richer detail about return values, QueryProvider enrichment, and usage context:

  • datahub_search, datahub_get_entity, datahub_get_column_lineage, datahub_get_queries, datahub_get_glossary_term, datahub_get_data_product

Bug Fixes

  • Fix UpdateDescription to use read-modify-write pattern — Prevents overwriting existing metadata when updating descriptions (#46)
  • Fix ingestProposal for DataHub v1.3.0+ — Adapts write operations to work with DataHub's updated API (#44)
  • Fix release workflow — Create release as draft until MCPB bundles are uploaded (#47)

Dependencies

  • Bump github.com/modelcontextprotocol/go-sdk from 1.2.0 to 1.3.0 (#49)
  • Add gopkg.in/yaml.v3 for YAML config file parsing
  • Bump anchore/sbom-action from 0.22.1 to 0.22.2 (#48)
  • Bump github/codeql-action from 4.32.1 to 4.32.2 (#50)

New ToolContext.GetString() Method

Convenience method for middleware authors to retrieve string values from the Extra map:

func (m *MyMiddleware) Before(ctx context.Context, tc *tools.ToolContext) (context.Context, error) {
    connection := tc.GetString("connection")
    // ...
}

Upgrading from v0.5.0

No breaking changes. All existing code continues to work without modification.

New features are opt-in:

  • Extensions middleware is off by default (except error hints)
  • Description overrides only apply if you configure them
  • Config file support is an alternative to env vars, not a replacement

New dependency: gopkg.in/yaml.v3 is added to go.mod. Run go mod tidy after upgrading.


Changelog

Bug Fixes

  • fix: create release as draft until MCPB bundles are uploaded (#47)
  • Fix UpdateDescription to use read-modify-write pattern (#46)
  • Fix ingestProposal for DataHub v1.3.0+ (#44)

Features

  • Add description override API and extensions package (#51) (#53)

Dependencies

  • deps: bump github.com/modelcontextprotocol/go-sdk from 1.2.0 to 1.3.0 (#49)
  • ci: bump anchore/sbom-action from 0.22.1 to 0.22.2 (#48)
  • ci: bump github/codeql-action from 4.32.1 to 4.32.2 (#50)

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.6.0_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.6.0_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.6.0_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.6.0

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.6.0_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.6.0_linux_amd64.tar.gz

mcp-datahub-v0.5.2

11 Feb 00:04
Immutable release. Only release title and notes can be modified.
d199566

Choose a tag to compare

Bug Fix

UpdateDescription now uses read-modify-write to preserve audit stamps, fixing HTTP 400 failures on DataHub v1.3.0+.

Root cause: UpdateDescription was the only write operation sending a partial aspect ({"description": "..."}) without the created and lastModified audit stamps. DataHub v1.3.0 rejects incomplete editableDatasetProperties aspects during validation. All other write operations (AddTag, RemoveTag, etc.) already used read-modify-write and were unaffected.

Also includes: Fix for revive lint errors (unhandled-error on WriteRune calls in toEnumCase).

Closes #45

Installation

Claude Desktop (macOS/Windows)

Download the .mcpb bundle for your platform and double-click to install:

  • macOS Apple Silicon (M1/M2/M3/M4): mcp-datahub_0.5.2_darwin_arm64.mcpb
  • macOS Intel: mcp-datahub_0.5.2_darwin_amd64.mcpb
  • Windows: mcp-datahub_0.5.2_windows_amd64.mcpb

Homebrew (macOS)

brew install txn2/tap/mcp-datahub

Claude Code CLI

claude mcp add datahub \
  -e DATAHUB_URL=https://your-datahub.example.com/api/graphql \
  -e DATAHUB_TOKEN=your-token \
  -- mcp-datahub

Docker

docker pull ghcr.io/txn2/mcp-datahub:v0.5.2

Verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-datahub_0.5.2_linux_amd64.tar.gz.sigstore.json \
  mcp-datahub_0.5.2_linux_amd64.tar.gz