# Toolbox enrichment demo

> End-to-end TypeScript demo: kcmd init and pull, kcagent enrich with md-fileset MCP tools, fileset skills, prompt configuration, and BigQuery demo dataset setup.

- Repository: GoogleCloudPlatform/knowledge-catalog
- GitHub: https://github.com/GoogleCloudPlatform/knowledge-catalog
- Human docs: https://grok-wiki.com/public/docs/googlecloudplatform-knowledge-catalog-9cee6ee3cba5
- Complete Markdown: https://grok-wiki.com/public/docs/googlecloudplatform-knowledge-catalog-9cee6ee3cba5/llms-full.txt

## Source Files

- `toolbox/enrichment/README.md`
- `toolbox/enrichment/src/agent/enrich/command.ts`
- `toolbox/enrichment/src/agent/enrich/agent.ts`
- `toolbox/enrichment/src/tools/md/server.ts`
- `samples/enrichment/src/tools/fileskb/README.md`
- `toolbox/enrichment/package.json`

---

---
title: "Toolbox enrichment demo"
description: "End-to-end TypeScript demo: kcmd init and pull, kcagent enrich with md-fileset MCP tools, fileset skills, prompt configuration, and BigQuery demo dataset setup."
---

The `toolbox/enrichment` package ships two compiled CLIs — `kcagent` and `md-fileset` — that run an ADK-based enrichment loop over a local kcmd workspace: `kcagent enrich` loads a catalog snapshot, iterates entries, grounds each asset on MCP tools and fileset skills, and writes enriched `dataplex-types.global.overview` markdown back into the workspace via an `update_documentation` function tool.

## What this demo covers

| Stage | Tool / artifact | Outcome |
| --- | --- | --- |
| BigQuery setup | `bq query` | `demo_ecommerce.events` table from GA4 public data |
| Catalog snapshot | `kcmd init` or `catalog.yaml` + `kcmd pull` | Local `catalog/` entry YAML under a kcmd workspace |
| Information sources | `md-fileset` MCP + `fileset-source` skill | Agent searches and reads markdown in `fileset/` |
| Enrichment | `kcagent enrich` | Per-entry overview documentation updated in the workspace |
| Publication (optional) | `kcmd push` | Publishes local overview edits to Knowledge Catalog |

<Note>
The Python sample under `samples/enrichment/` follows a similar pattern with `fileskb`; this page documents the TypeScript toolbox path that bundles `md-fileset` as a native MCP server.
</Note>

## Prerequisites

<Steps>
<Step title="Install dependencies">

```bash
git clone https://github.com/GoogleCloudPlatform/knowledge-catalog
cd toolbox/enrichment
npm install
npm run build
```

Build produces `dist/kcagent`, `dist/md-fileset`, and the `kcmd` binary at `../mdcode/dist/kcmd`.

</Step>

<Step title="Authenticate and set project">

```bash
export DEMO_CLOUD_PROJECT="<your-gcp-project-id>"

gcloud auth application-default login
gcloud config set project $DEMO_CLOUD_PROJECT
gcloud config set compute/region us
```

`kcagent` resolves Vertex AI project and location from `kcmd.gcp.ApiContext.default()`, which reads gcloud ADC configuration.

</Step>
</Steps>

## Architecture

```mermaid
sequenceDiagram
  participant User
  participant kcmd
  participant kcagent
  participant ADK as ADK Runner
  participant MCP as md-fileset MCP
  participant Fileset as fileset/ markdown
  participant Catalog as catalog/ workspace

  User->>kcmd: init + pull (or manual catalog.yaml + pull)
  kcmd->>Catalog: write entry YAML + aspects
  User->>kcagent: enrich --catalog-path --tools-path --prompt-path
  kcagent->>Catalog: listEntries / lookupEntry
  loop Per catalog entry
    kcagent->>ADK: runEphemeral(asset prompt)
    ADK->>MCP: list / search / read fileset tools
    MCP->>Fileset: listContents / searchContents / readFile
    Fileset-->>MCP: markdown snippets
    MCP-->>ADK: tool results
    ADK->>Catalog: update_documentation → overview aspect
  end
```

For each entry, `enrichCommand` constructs a per-entry prompt from the entry name, schema aspect, existing overview, and the shared `prompt.md` file, then runs an ephemeral ADK session. The agent's built-in instruction (in `agent.ts`) defines documentation structure, citation requirements, and when to skip updates.

## Demo workspace layout

:::files
demo/
├── catalog.yaml              # kcmd manifest (scope + snapshot aspects)
├── catalog/                  # pulled entry YAML (created by kcmd pull)
├── prompt.md                 # per-run enrichment instructions
├── fileset/                  # markdown knowledge base for md-fileset
└── tools/
    ├── mcp.json              # MCP server definitions
    └── skills/
        └── fileset-source/
            └── SKILL.md      # agent skill describing md-fileset usage
:::

## Set up the BigQuery demo dataset

Create a partitioned `events` table in your project from the GA4 obfuscated ecommerce public dataset:

<RequestExample>

```bash title="Create demo_ecommerce schema and table"
bq query --use_legacy_sql=false <<EOF
CREATE SCHEMA IF NOT EXISTS \`${DEMO_CLOUD_PROJECT}.demo_ecommerce\`
OPTIONS (
  location = 'US',
  labels = [('usage', 'demo')]
);

CREATE TABLE IF NOT EXISTS \`${DEMO_CLOUD_PROJECT}.demo_ecommerce.events\`
PARTITION BY event_date_dt
AS
SELECT
  *,
  PARSE_DATE('%Y%m%d', event_date) AS event_date_dt
FROM
  \`bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*\`;
EOF
```

</RequestExample>

The same dataset shape is scripted in `toolbox/mdcode/demo/bq/setup.ts` for the mdcode demo harness.

## Initialize and pull the catalog snapshot

<Tabs>
<Tab title="kcmd init (recommended)">

```bash
mkdir -p demo && cd demo

../../mdcode/dist/kcmd init \
  --bigquery-dataset ${DEMO_CLOUD_PROJECT}.demo_ecommerce

../../mdcode/dist/kcmd pull
```

`kcmd init` scaffolds `catalog.yaml` with the correct `bq-dataset` scope.

</Tab>
<Tab title="Manual catalog.yaml">

```bash
mkdir -p demo && cd demo

cat <<EOF > catalog.yaml
scope: bq-dataset.${DEMO_CLOUD_PROJECT}.demo_ecommerce

snapshot:
  entries:
    - dataplex-types.global.bigquery-dataset
    - dataplex-types.global.bigquery-table
  aspects:
    - dataplex-types.global.overview
EOF

../../mdcode/dist/kcmd pull
```

</Tab>
</Tabs>

<ResponseExample>

After `kcmd pull`, the workspace contains `catalog/` YAML files for the dataset and its tables, including schema and any existing overview aspects.

</ResponseExample>

## Configure prompt, MCP tools, and skills

### Prompt file

```bash title="prompt.md"
cat <<EOF > prompt.md
Enrich the documentation of the assets using the internal organizational information.
Use the following sources:

* Fileset source
EOF
```

The prompt is appended to each per-entry message alongside asset metadata and existing documentation.

### MCP server (`tools/mcp.json`)

```json title="tools/mcp.json"
{
  "mcpServers": {
    "md-fileset": {
      "command": "../dist/md-fileset",
      "args": ["--dir", "fileset"]
    }
  }
}
```

`loadMcpTools` reads `tools/mcp.json`, expands `$VAR` / `${VAR}` environment references in `command`, `args`, and `env`, and registers each server as an ADK `MCPToolset`. Stdio servers use `command` + `args`; HTTP servers use `httpUrl`.

### Fileset skill (`tools/skills/fileset-source/SKILL.md`)

```markdown title="tools/skills/fileset-source/SKILL.md"
---
name: fileset-source
description: >
  Use the fileset source to find relevant markdown documents and extract information
  about assets.
---

The `md-fileset` mcp server provides the following tools to extract relevant
information from a directory hierarchy of markdown files:

* **list_fileset_contents** - browse and navigate the directory tree
* **read_fileset_file** - read the full contents of a file
* **search_fileset_contents** - regex search with file, line, and snippet results
```

`loadSkills` loads every `SKILL.md` under `tools/skills/` via `adk.loadAllSkillsInDir` and exposes them as a `SkillToolset` with `UnsafeLocalCodeExecutor`.

### Populate the fileset directory

Copy markdown from `samples/enrichment/sample/docs/` into `demo/fileset/`. These files describe GA4 ecommerce context, query patterns, and usage notes that ground enrichment beyond raw BigQuery schema.

<Info>
Skills and MCP servers are provider-neutral extension points: swap `md-fileset` for any MCP-compatible information source (for example the Python `fileskb` server in `samples/enrichment`) without changing the `kcagent enrich` command shape.
</Info>

## Run enrichment

<Steps>
<Step title="Start the agent">

```bash
../dist/kcagent enrich \
  --catalog-path . \
  --tools-path tools \
  --prompt-path prompt.md
```

</Step>

<Step title="Observe runtime output">

The CLI prints structured ADK events:

- `[Thought]` — model reasoning (when `includeThoughts` is enabled)
- `[Tool Invoke]` / `[Tool Result]` — MCP and function tool calls
- `[Agent]` — final agent messages

Each entry is processed sequentially; `Processing: <entry-name>` marks the current asset.

</Step>

<Step title="Verify workspace changes">

Inspect updated overview aspects in `catalog/` entry YAML files. Entries where the agent found no additional information are left unchanged per the agent instruction.

</Step>
</Steps>

## `kcagent enrich` CLI reference

<ParamField body="--catalog-path" type="string" required>
Path to the kcmd workspace root containing `catalog.yaml` and the `catalog/` directory.
</ParamField>

<ParamField body="--tools-path" type="string" required>
Directory containing `mcp.json` and optional `skills/` subdirectory.
</ParamField>

<ParamField body="--prompt-path" type="string" required>
Path to a markdown or plain-text prompt file appended to each per-entry enrichment message.
</ParamField>

## `md-fileset` MCP tools

| Tool | Parameters | Behavior |
| --- | --- | --- |
| `list_fileset_contents` | `path` (optional, default `''`) | Lists files and subdirectories under a relative path |
| `read_fileset_file` | `path` (required) | Returns full file contents; rejects paths outside the fileset root |
| `search_fileset_contents` | `query` (required), `path` (optional) | Case-insensitive regex search across `.md` files; returns file, line number, and matching line |

The `md-fileset` binary requires `--dir <root>` pointing at the markdown root directory. Run it standalone via stdio transport for MCP inspector debugging:

```bash
npm run run:mdtool
```

## Agent model and documentation contract

The enrichment agent (`kcagent-enrich`) uses `gemini-2.5-flash` on Vertex AI with thinking enabled. Generated documentation must:

- Follow a markdown template with summary paragraphs, **Data Details**, **Usage Details**, and **Citations** sections
- Synthesize sources rather than verbatim copy
- Ground statements in retrieved facts; skip `update_documentation` when no new information is found
- Call `update_documentation` with markdown content, which writes `dataplex-types.global.overview` with `contentType: MARKDOWN` via `catalog.updateEntry`

## Publish enriched metadata (optional)

After enrichment, push local overview edits back to Knowledge Catalog:

```bash
../../mdcode/dist/kcmd status
../../mdcode/dist/kcmd push
```

Use `--dry-run` on `pull` or `push` to preview sync behavior without writing remote state.

## Clean up demo resources

```bash
bq rm -r -f -d ${DEMO_CLOUD_PROJECT}:demo_ecommerce
```

<Warning>
The cleanup command in `toolbox/enrichment/README.md` references `demo-dataset`; the demo creates `demo_ecommerce`. Use the dataset name above.
</Warning>

## Troubleshooting

| Symptom | Likely cause | Check |
| --- | --- | --- |
| `catalog-path is not a directory` | Wrong `--catalog-path` | Run from the `demo/` workspace root |
| Empty MCP tool list | Missing or invalid `tools/mcp.json` | Confirm file exists; warnings print on parse failure |
| No fileset matches | Empty `fileset/` or wrong `--dir` | Verify sample docs were copied |
| Vertex AI auth errors | ADC or quota project misconfigured | Re-run `gcloud auth application-default login` |
| MCP session leaks on exit | ADK MCP lifecycle | `patchadk.ts` registers session cleanup hooks |

## Developer commands

| Command | Purpose |
| --- | --- |
| `npm run build` | Compile `kcagent`, `md-fileset`, and TypeScript library |
| `npm run compile` | Type-check without emit |
| `npm run test` | Run package tests |
| `npm run debug` | Launch ADK web UI against `agent.ts` |

## Related pages

<CardGroup>
<Card title="Installation" href="/installation">
Prerequisites, Node.js setup, credential configuration for BigQuery and Vertex AI.
</Card>
<Card title="Sync catalog metadata" href="/sync-catalog-metadata">
`kcmd init`, `pull`, `status`, and `push` for BigQuery dataset workspaces.
</Card>
<Card title="Enrichment workflows" href="/enrichment-workflows">
How enrichment agents read metadata, ground on external sources, and hand off to kcmd push.
</Card>
<Card title="Publish enriched metadata" href="/publish-enriched-metadata">
Push mdcode workspace edits and reconcile aspects after enrichment.
</Card>
<Card title="kcmd MCP reference" href="/kcmd-mcp-reference">
Expose kcmd pull/push and entry operations as MCP tools in agentic workflows.
</Card>
</CardGroup>
