Skip to content

Commit 20fdb01

Browse files
authored
feat: elicitation, icons, jsonrpc errors, and docs for MCP protocol capabilities (#112)
* feat: add elicitation, icons, client logging, progress, and docs Complete Issue #102 implementation with documentation for all 6 MCP protocol capability features: resource templates, progress notifications, client logging, elicitation (cost estimation, PII consent), icons middleware, and resource links. Update middleware reference with 8-layer chain diagram, add config sections to server and reference docs, update llms.txt and llms-full.txt indexes. * feat: use jsonrpc.Error sentinels for malformed request errors Replace tool-level error results with protocol-level JSON-RPC errors (CodeInvalidParams) for truly malformed requests in middleware. Auth and authz failures remain as tool-level errors for better agent handling.
1 parent 415e776 commit 20fdb01

29 files changed

+3179
-78
lines changed

configs/platform.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,34 @@ tuning:
300300
# client_logging:
301301
# enabled: true
302302

303+
# Elicitation (user confirmation prompts)
304+
# Requests user confirmation before expensive queries or PII access.
305+
# Requires client-side elicitation support (e.g., Claude Desktop).
306+
# Gracefully degrades to no-op if the client doesn't support elicitation.
307+
# elicitation:
308+
# enabled: true
309+
# cost_estimation:
310+
# enabled: true
311+
# row_threshold: 1000000 # prompt when EXPLAIN IO estimates > 1M rows
312+
# pii_consent:
313+
# enabled: true # prompt when query accesses PII-tagged columns
314+
315+
# Icons (tool/resource/prompt visual metadata)
316+
# Override or add icons to MCP list responses.
317+
# Upstream toolkits provide default icons; use this to customize.
318+
# icons:
319+
# enabled: true
320+
# tools:
321+
# trino_query:
322+
# src: "https://example.com/custom-trino.svg"
323+
# mime_type: "image/svg+xml"
324+
# resources:
325+
# "schema://{catalog}.{schema}/{table}":
326+
# src: "https://example.com/schema.svg"
327+
# prompts:
328+
# knowledge_capture:
329+
# src: "https://example.com/knowledge.svg"
330+
303331
# Audit logging
304332
audit:
305333
enabled: false

docs/llms-full.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ The only requirement is DataHub (https://datahubproject.io/). Add Trino (https:/
3232

3333
- **Client Logging**: Server-to-client log messages for platform decisions (enrichment, timing) via MCP `logging/setLevel` protocol. Zero overhead if the client hasn't opted in.
3434

35+
- **Elicitation**: User confirmation prompts before expensive queries (EXPLAIN IO cost estimation) or PII access (sensitive column detection). Requires client-side elicitation support; gracefully degrades when unavailable.
36+
37+
- **Icons**: Visual metadata for tools, resources, and prompts. Upstream toolkits provide default icons; deployers can override via configuration.
38+
3539
---
3640

3741
# The Data Stack: DataHub + Trino + S3
@@ -321,6 +325,29 @@ When enabled, Trino query tools send three progress notifications per query: bef
321325

322326
When enabled, the platform sends log notifications to clients after enrichment is applied (tool name, duration). Uses MCP `logging/setLevel` protocol — zero overhead if the client hasn't called `setLevel`.
323327

328+
## Elicitation Configuration
329+
330+
| Field | Type | Default | Description |
331+
|-------|------|---------|-------------|
332+
| `elicitation.enabled` | bool | `false` | Enable user confirmation prompts |
333+
| `elicitation.cost_estimation.enabled` | bool | `false` | Prompt when EXPLAIN IO estimates exceed the row threshold |
334+
| `elicitation.cost_estimation.row_threshold` | int | `1000000` | Row estimate threshold for cost prompts |
335+
| `elicitation.pii_consent.enabled` | bool | `false` | Prompt when query accesses PII-tagged columns |
336+
337+
Elicitation requires client-side support (MCP `elicitation/create` capability). When the client doesn't support it, elicitation gracefully degrades to a no-op. If a user declines the confirmation, the tool returns an informational message instead of executing the query.
338+
339+
## Icons Configuration
340+
341+
| Field | Type | Default | Description |
342+
|-------|------|---------|-------------|
343+
| `icons.enabled` | bool | `false` | Enable icon injection middleware |
344+
| `icons.tools.<name>.src` | string | - | Icon URI for a tool |
345+
| `icons.tools.<name>.mime_type` | string | - | Icon MIME type |
346+
| `icons.resources.<uri>.src` | string | - | Icon URI for a resource template |
347+
| `icons.prompts.<name>.src` | string | - | Icon URI for a prompt |
348+
349+
Upstream toolkits (Trino, DataHub, S3) provide default icons on all tools. This configuration overrides or adds icons for tools, resource templates, and prompts in list responses.
350+
324351
## Audit Configuration
325352

326353
| Field | Type | Default | Description |

docs/llms.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
- [Home](index.md): Introduction, quick start, and key features
1212
- [Server Overview](server/overview.md): What the platform does, architecture, request flow
1313
- [Installation](server/installation.md): Install via go install, Homebrew, Docker, or from source
14-
- [Configuration](server/configuration.md): YAML configuration with environment variable expansion, config versioning (apiVersion field, version lifecycle, migrate-config CLI), config store options (file vs database mode), tool visibility filtering (allow/deny patterns for tools/list token reduction), resource templates, progress notifications, client logging, admin API and portal, database, audit, and session configuration
14+
- [Configuration](server/configuration.md): YAML configuration with environment variable expansion, config versioning (apiVersion field, version lifecycle, migrate-config CLI), config store options (file vs database mode), tool visibility filtering (allow/deny patterns for tools/list token reduction), resource templates, progress notifications, client logging, elicitation (cost estimation, PII consent), icons (tool/resource/prompt visual metadata), admin API and portal, database, audit, and session configuration
1515
- [Operating Modes](server/operating-modes.md): Three deployment modes — standalone (no database), full-config file + database, bootstrap + database config. Feature availability by mode, example configurations, decision guide
1616
- [Admin Portal](server/admin-portal.md): Built-in web dashboard for monitoring and managing the platform. Dashboard with activity timelines, performance percentiles, error monitoring. Tools overview with connection grid and tool inventory. Interactive tool explorer with semantic enrichment display. Searchable audit log with event detail drawer. Knowledge insight governance with approve/reject workflow and changeset tracking. Local dev with MSW mock data
1717
- [Admin API](server/admin-api.md): REST endpoints for system info, config management, personas, auth keys, audit, knowledge. Authentication, operating mode behavior, request/response reference. Interactive Swagger UI at `/api/v1/admin/docs/`
@@ -73,7 +73,7 @@
7373
- [Tools API](reference/tools-api.md): Complete tool specifications with parameters and responses
7474
- [Configuration](reference/configuration.md): Full YAML schema with all options
7575
- [Providers](reference/providers.md): Semantic, query, and storage provider interfaces
76-
- [Middleware](reference/middleware.md): Request processing chain including tool visibility middleware, client logging, progress notifications
76+
- [Middleware](reference/middleware.md): Request processing chain including tool visibility middleware, icon injection middleware, client logging, progress notifications
7777

7878
## Support
7979

docs/reference/configuration.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,72 @@ tools:
488488

489489
No patterns configured means all tools are visible. When both are set, allow is evaluated first, then deny removes from the result. Patterns use `filepath.Match` syntax (`*` matches any sequence of characters).
490490

491+
## Elicitation Configuration
492+
493+
Elicitation prompts users for confirmation before expensive queries or when accessing PII-tagged columns. Requires client-side elicitation support (MCP `elicitation/create` capability). Gracefully degrades to a no-op if the client doesn't support it.
494+
495+
```yaml
496+
elicitation:
497+
enabled: true
498+
cost_estimation:
499+
enabled: true
500+
row_threshold: 1000000
501+
pii_consent:
502+
enabled: true
503+
```
504+
505+
| Option | Type | Default | Description |
506+
|--------|------|---------|-------------|
507+
| `elicitation.enabled` | bool | `false` | Master switch for elicitation |
508+
| `elicitation.cost_estimation.enabled` | bool | `false` | Prompt when EXPLAIN IO estimates exceed the row threshold |
509+
| `elicitation.cost_estimation.row_threshold` | int | `1000000` | Row estimate threshold for cost prompts |
510+
| `elicitation.pii_consent.enabled` | bool | `false` | Prompt when query accesses columns tagged as PII/sensitive |
511+
512+
Elicitation is implemented as Trino toolkit middleware. When a user declines the prompt, the tool call returns an informational message instead of executing the query.
513+
514+
## Icons Configuration
515+
516+
Override or add icons to MCP `tools/list`, `resources/templates/list`, and `prompts/list` responses. Upstream toolkits (Trino, DataHub, S3) provide default icons; this configuration overrides them.
517+
518+
```yaml
519+
icons:
520+
enabled: true
521+
tools:
522+
trino_query:
523+
src: "https://example.com/custom-trino.svg"
524+
mime_type: "image/svg+xml"
525+
resources:
526+
"schema://{catalog}.{schema}/{table}":
527+
src: "https://example.com/schema.svg"
528+
prompts:
529+
knowledge_capture:
530+
src: "https://example.com/knowledge.svg"
531+
```
532+
533+
| Option | Type | Default | Description |
534+
|--------|------|---------|-------------|
535+
| `icons.enabled` | bool | `false` | Enable icon injection middleware |
536+
| `icons.tools` | map | `{}` | Tool name to icon mapping |
537+
| `icons.resources` | map | `{}` | Resource template URI to icon mapping |
538+
| `icons.prompts` | map | `{}` | Prompt name to icon mapping |
539+
| `icons.*.src` | string | - | Icon source URI (HTTPS URL or data URI) |
540+
| `icons.*.mime_type` | string | - | Icon MIME type (e.g., `image/svg+xml`) |
541+
542+
## Resource Links Configuration
543+
544+
DataHub search results and entity responses automatically include MCP resource links when resource templates are enabled. These links allow clients to navigate directly to related schema, glossary, and availability resources.
545+
546+
```yaml
547+
resources:
548+
enabled: true
549+
```
550+
551+
When `resources.enabled: true`, DataHub tools include links to:
552+
553+
- `schema://{catalog}.{schema}/{table}` — table schema details
554+
- `glossary://{term}` — glossary term definitions
555+
- `availability://{catalog}.{schema}/{table}` — query availability status
556+
491557
## Admin API Configuration
492558

493559
```yaml
@@ -696,6 +762,15 @@ injection:
696762
enabled: true
697763
mode: reference
698764
765+
resources:
766+
enabled: true
767+
768+
elicitation:
769+
enabled: true
770+
cost_estimation:
771+
enabled: true
772+
row_threshold: 1000000
773+
699774
knowledge:
700775
enabled: true
701776
apply:

docs/reference/middleware.md

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,27 @@ Middleware processes requests and responses at the MCP protocol level. Each midd
66

77
```mermaid
88
graph LR
9-
Request --> ToolVisibility
9+
Request --> Icons
10+
Icons --> ToolVisibility
1011
ToolVisibility --> AppsMetadata
1112
AppsMetadata --> MCPToolCall
1213
MCPToolCall --> MCPAudit
13-
MCPAudit --> MCPRules
14+
MCPAudit --> ClientLogging
15+
ClientLogging --> MCPRules
1416
MCPRules --> MCPEnrichment
1517
MCPEnrichment --> Handler
1618
Handler --> MCPEnrichment
1719
MCPEnrichment --> MCPRules
18-
MCPRules --> MCPAudit
20+
MCPRules --> ClientLogging
21+
ClientLogging --> MCPAudit
1922
MCPAudit --> MCPToolCall
2023
MCPToolCall --> AppsMetadata
2124
AppsMetadata --> ToolVisibility
22-
ToolVisibility --> Response
25+
ToolVisibility --> Icons
26+
Icons --> Response
2327
```
2428

25-
The platform registers up to six middleware layers. Execution flows left-to-right for requests and right-to-left for responses.
29+
The platform registers up to eight middleware layers. Execution flows left-to-right for requests and right-to-left for responses.
2630

2731
## MCP Middleware Interface
2832

@@ -197,6 +201,36 @@ func MCPToolVisibilityMiddleware(allow, deny []string) mcp.Middleware
197201

198202
This is a **visibility filter**, not a security boundary. Persona-level tool filtering via MCPToolCallMiddleware continues to gate `tools/call` independently.
199203

204+
### MCPIconMiddleware
205+
206+
Injects config-driven icons into `tools/list`, `resources/templates/list`, and `prompts/list` responses. Upstream toolkits provide default icons; this middleware allows deployers to override or add custom icons via configuration.
207+
208+
```go
209+
func MCPIconMiddleware(cfg IconsMiddlewareConfig) mcp.Middleware
210+
```
211+
212+
**Behavior:**
213+
214+
1. Intercepts list responses (`tools/list`, `resources/templates/list`, `prompts/list`)
215+
2. Matches tools/resources/prompts by name or URI
216+
3. Appends configured icons to matching entries
217+
4. Passes through all other methods unchanged
218+
219+
Only registered when `icons.enabled: true` in configuration.
220+
221+
### MCPClientLoggingMiddleware
222+
223+
Sends server-to-client log messages via the MCP `logging/setLevel` protocol. Reports enrichment decisions, timing data, and platform diagnostics. Zero overhead if the client hasn't called `setLevel`.
224+
225+
**Behavior:**
226+
227+
1. Only active for `tools/call` requests
228+
2. Sends log messages using the server session's `LoggingMessage` method
229+
3. Messages include enrichment details, query timing, and semantic cache hits
230+
4. No-op if the client hasn't subscribed via `logging/setLevel`
231+
232+
Only registered when `client_logging.enabled: true` in configuration.
233+
200234
### ToolMetadataMiddleware (MCP Apps)
201235

202236
Injects `_meta.ui` fields into `tools/list` responses for tools that have associated MCP Apps.

docs/server/configuration.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,112 @@ mcpapps:
555555

556556
See [MCP Apps Configuration](../mcpapps/configuration.md) for complete options.
557557

558+
## Resource Templates Configuration
559+
560+
Resource templates expose platform data as browseable, parameterized MCP resources using RFC 6570 URI templates.
561+
562+
```yaml
563+
resources:
564+
enabled: true
565+
```
566+
567+
| Field | Type | Default | Description |
568+
|-------|------|---------|-------------|
569+
| `enabled` | bool | `false` | Enable resource templates |
570+
571+
When enabled, the platform registers these resource templates:
572+
573+
- `schema://{catalog}.{schema}/{table}` — Table schema with column types and descriptions
574+
- `glossary://{term}` — Glossary term definitions
575+
- `availability://{catalog}.{schema}/{table}` — Query availability and row counts
576+
577+
Clients that support resource browsing (e.g., Claude Desktop) will show these as navigable resources alongside tools.
578+
579+
## Progress Notifications Configuration
580+
581+
Progress notifications send granular updates to MCP clients during long-running Trino queries. The client must include `_meta.progressToken` in the request to receive updates.
582+
583+
```yaml
584+
progress:
585+
enabled: true
586+
```
587+
588+
| Field | Type | Default | Description |
589+
|-------|------|---------|-------------|
590+
| `enabled` | bool | `false` | Enable progress notifications |
591+
592+
When enabled, Trino query execution sends progress updates including rows scanned, bytes processed, and query stage information. Clients that don't send a `progressToken` receive no notifications (zero overhead).
593+
594+
## Client Logging Configuration
595+
596+
Client logging sends server-to-client log messages via the MCP `logging/setLevel` protocol. Messages include enrichment decisions, timing data, and platform diagnostics.
597+
598+
```yaml
599+
client_logging:
600+
enabled: true
601+
```
602+
603+
| Field | Type | Default | Description |
604+
|-------|------|---------|-------------|
605+
| `enabled` | bool | `false` | Enable client logging |
606+
607+
Zero overhead if the client hasn't subscribed via `logging/setLevel`. When active, log messages report semantic cache hits/misses, enrichment timing, and cross-injection decisions.
608+
609+
## Elicitation Configuration
610+
611+
Elicitation requests user confirmation before potentially expensive or sensitive operations. Requires client-side elicitation support (e.g., Claude Desktop). Gracefully degrades to a no-op if the client doesn't support elicitation.
612+
613+
```yaml
614+
elicitation:
615+
enabled: true
616+
cost_estimation:
617+
enabled: true
618+
row_threshold: 1000000
619+
pii_consent:
620+
enabled: true
621+
```
622+
623+
| Field | Type | Default | Description |
624+
|-------|------|---------|-------------|
625+
| `enabled` | bool | `false` | Enable elicitation |
626+
| `cost_estimation.enabled` | bool | `false` | Prompt before expensive queries |
627+
| `cost_estimation.row_threshold` | int | `1000000` | Row count threshold from `EXPLAIN` IO estimates |
628+
| `pii_consent.enabled` | bool | `false` | Prompt when query accesses PII-tagged columns |
629+
630+
!!! note "Client support required"
631+
Elicitation uses the MCP `elicitation/create` capability. Clients that don't support elicitation will not receive prompts — queries proceed without confirmation.
632+
633+
## Icons Configuration
634+
635+
Icons add visual metadata to tools, resources, and prompts in MCP list responses. Upstream toolkits (Trino, DataHub, S3) provide default icons; this configuration overrides or extends them.
636+
637+
```yaml
638+
icons:
639+
enabled: true
640+
tools:
641+
trino_query:
642+
src: "https://example.com/custom-trino.svg"
643+
mime_type: "image/svg+xml"
644+
resources:
645+
"schema://{catalog}.{schema}/{table}":
646+
src: "https://example.com/schema.svg"
647+
prompts:
648+
knowledge_capture:
649+
src: "https://example.com/knowledge.svg"
650+
```
651+
652+
| Field | Type | Default | Description |
653+
|-------|------|---------|-------------|
654+
| `enabled` | bool | `false` | Enable icon injection middleware |
655+
| `tools` | map | - | Icon overrides keyed by tool name |
656+
| `resources` | map | - | Icon overrides keyed by resource URI |
657+
| `prompts` | map | - | Icon overrides keyed by prompt name |
658+
| `*.src` | string | - | Icon source URL |
659+
| `*.mime_type` | string | - | Icon MIME type (e.g., `image/svg+xml`) |
660+
661+
!!! tip "Default icons"
662+
Each upstream toolkit provides a default icon for all its tools. You only need this configuration if you want to customize or override those defaults.
663+
558664
## Environment Variables
559665

560666
Common environment variables:
@@ -663,6 +769,21 @@ injection:
663769
datahub_query_enrichment: true
664770
s3_semantic_enrichment: true
665771
772+
resources:
773+
enabled: true
774+
775+
progress:
776+
enabled: true
777+
778+
client_logging:
779+
enabled: true
780+
781+
elicitation:
782+
enabled: true
783+
cost_estimation:
784+
enabled: true
785+
row_threshold: 1000000
786+
666787
personas:
667788
definitions:
668789
analyst:
@@ -688,3 +809,4 @@ personas:
688809
- [Authentication](../auth/overview.md) - Add authentication
689810
- [Personas](../personas/overview.md) - Role-based access control
690811
- [MCP Apps](../mcpapps/overview.md) - Interactive UI for tool results
812+
- [Middleware Reference](../reference/middleware.md) - Request processing chain details

0 commit comments

Comments
 (0)