Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a7d22fa
docs: Add User Guide section
dishaprakash Mar 5, 2026
a9c315c
rebase
dishaprakash Mar 5, 2026
50e37bb
docs: Add reference and other docs
dishaprakash Mar 5, 2026
43f2b69
Update docs/en/reference/faq.md
dishaprakash Mar 5, 2026
8d97bab
chore: Add workflows to deploy to cloudflare
dishaprakash Mar 6, 2026
8f0ea15
use sticky comment
dishaprakash Mar 6, 2026
6e1c0c3
remove prs from pull_request_target and add second hugo config
dishaprakash Mar 7, 2026
a2eb7be
add header
dishaprakash Mar 7, 2026
8a58ffa
docs: implement deep re-routing, pagination, and migration banner
dishaprakash Mar 7, 2026
4a5432e
Apply suggestion from @gemini-code-assist[bot]
dishaprakash Mar 7, 2026
d45d9b6
gemini review changes
dishaprakash Mar 7, 2026
80822be
minor fix
dishaprakash Mar 7, 2026
c654670
docs: Optimize llms.txt and llms-full.txt
dishaprakash Mar 7, 2026
315df49
add documentation
dishaprakash Mar 8, 2026
3833b43
update integration directory structure
dishaprakash Mar 8, 2026
a48e3dd
docs: Add page standardization to external source integrations
dishaprakash Mar 8, 2026
435acc6
add documentation and ci check
dishaprakash Mar 8, 2026
40dd323
docs: Add page standardization to external tool integrations
dishaprakash Mar 8, 2026
5504f55
Update docs/en/integrations/cockroachdb/_index.md
dishaprakash Mar 9, 2026
b7520b7
gemini review
dishaprakash Mar 9, 2026
5001d0f
Update DEVELOPER.md
dishaprakash Mar 10, 2026
6613fd6
review changes
dishaprakash Mar 10, 2026
509aeeb
update gha workflow
dishaprakash Mar 10, 2026
8572e4f
minor fix
dishaprakash Mar 10, 2026
d14af85
Update DEVELOPER.md
dishaprakash Mar 10, 2026
8492914
Merge branch 'page-standardization' into tools-page-standard
dishaprakash Mar 10, 2026
06cf47c
documentation
dishaprakash Mar 10, 2026
ef3d0df
Merge branch 'documentation-reorg' into tools-page-standard
dishaprakash Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions .ci/lint-docs-tool-page.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/bin/bash
set -e

python3 - << 'EOF'
"""
MCP TOOLBOX: TOOL PAGE LINTER
=============================
This script enforces a standardized structure for individual Tool pages
(e.g., integrations/postgres/postgres-sql.md). It ensures that LLM agents
can parse tool capabilities and parameter definitions reliably.

MAINTENANCE GUIDE:
------------------
1. TO ADD A NEW HEADING:
Add the exact heading text to the 'ALLOWED_ORDER' list in the desired
sequence.

2. TO MAKE A HEADING MANDATORY:
Add the heading text to the 'REQUIRED' set.

3. TO UPDATE SHORTCODE LOGIC:
If the shortcode name changes, update 'SHORTCODE_PATTERN'.

4. SCOPE:
This script targets all .md files in integrations/ EXCEPT _index.md files.
"""

import os
import re
import sys
from pathlib import Path

# --- CONFIGURATION ---
ALLOWED_ORDER = [
"About",
"Compatible Sources",
"Requirements",
"Parameters",
"Example",
"Output Format",
"Reference",
"Advanced Usage",
"Troubleshooting",
"Additional Resources"
]
REQUIRED = {"About", "Example"}
SHORTCODE_PATTERN = r"\{\{<\s*compatible-sources.*?>\}\}"
# ---------------------

integration_dir = Path("./docs/en/integrations")
if not integration_dir.exists():
print("Info: Directory './docs/en/integrations' not found. Skipping linting.")
sys.exit(0)

has_errors = False

# Find all .md files, excluding _index.md (which are Source pages)
for filepath in integration_dir.rglob("*.md"):
if filepath.name == "_index.md":
continue

with open(filepath, "r", encoding="utf-8") as f:
content = f.read()

# Separate YAML frontmatter from the markdown body
match = re.match(r'^\s*---\s*\n(.*?)\n---\s*(.*)', content, re.DOTALL)
if match:
frontmatter = match.group(1)
body = match.group(2)
else:
frontmatter = ""
body = content

if not body.strip():
continue

file_errors = False

# 1. Check Frontmatter Title
title_source = frontmatter if frontmatter else content
title_match = re.search(r"^title:\s*[\"']?(.*?)[\"']?\s*$", title_source, re.MULTILINE)
if not title_match or not title_match.group(1).strip().endswith("Tool"):
found_title = title_match.group(1) if title_match else "None"
print(f"[{filepath}] Error: Frontmatter title must end with 'Tool'. Found: '{found_title}'")
file_errors = True

# 2. Check Shortcode Placement
sources_section_match = re.search(r"^##\s+Compatible Sources\s*(.*?)(?=^##\s|\Z)", body, re.MULTILINE | re.DOTALL)
if sources_section_match:
if not re.search(SHORTCODE_PATTERN, sources_section_match.group(1)):
print(f"[{filepath}] Error: The compatible-sources shortcode must be placed under '## Compatible Sources'.")
file_errors = True
elif re.search(SHORTCODE_PATTERN, body):
print(f"[{filepath}] Error: Shortcode found, but '## Compatible Sources' heading is missing.")
file_errors = True

# 3. Strip code blocks
clean_body = re.sub(r"^(?:```|~~~).*?^(?:```|~~~)", "", body, flags=re.DOTALL | re.MULTILINE)

# 4. Check H1 Headings
if re.search(r"^#\s+\w+", clean_body, re.MULTILINE):
print(f"[{filepath}] Error: H1 headings (#) are forbidden in the body.")
file_errors = True

# 5. Check H2 Headings
h2s = [h.strip() for h in re.findall(r"^##\s+(.*)", clean_body, re.MULTILINE)]

# Missing Required
if missing := (REQUIRED - set(h2s)):
print(f"[{filepath}] Error: Missing required H2 headings: {missing}")
file_errors = True

# Unauthorized Headings
if unauthorized := (set(h2s) - set(ALLOWED_ORDER)):
print(f"[{filepath}] Error: Unauthorized H2 headings found: {unauthorized}")
file_errors = True

# Strict Ordering
filtered_h2s = [h for h in h2s if h in ALLOWED_ORDER]
expected_order = [h for h in ALLOWED_ORDER if h in h2s]
if filtered_h2s != expected_order:
print(f"[{filepath}] Error: Headings are out of order.")
print(f" Expected: {expected_order}")
print(f" Found: {filtered_h2s}")
file_errors = True

if file_errors:
has_errors = True

if has_errors:
print("Linting failed for Tool pages. Please fix the structure errors above.")
sys.exit(1)
else:
print("Success: All Tool pages passed structure validation.")
EOF
13 changes: 8 additions & 5 deletions .github/workflows/docs_lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ name: Lint Documentation
on:
pull_request:
paths:
- 'integrations/**/*.md'
- '.ci/lint-docs-source-page.sh'
- 'docs/**'
- '.ci/lint-docs-*.sh'

jobs:
lint-source-pages:
Expand All @@ -42,8 +42,11 @@ jobs:
exit 1
fi

- name: Make script executable
run: chmod +x .ci/lint-docs-source-page.sh
- name: Make scripts executable
run: chmod +x .ci/lint-docs-*.sh

- name: Run Structure Linter for Source Pages
run: bash .ci/lint-docs-source-page.sh
run: bash .ci/lint-docs-source-page.sh

- name: Run Structure Linter for Tool Pages
run: bash .ci/lint-docs-tool-page.sh
64 changes: 40 additions & 24 deletions DEVELOPER.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,29 +229,6 @@ tools.

* **Adding Top-Level Sections:** If you add a completely new top-level documentation directory (e.g., a new section alongside `integrations`, `user-guide`, etc.), you **must** update the AI documentation layout files located at `.hugo/layouts/index.llms.txt` and `.hugo/layouts/index.llms-full.txt`. Specifically, you need to update the "Diátaxis Narrative Framework" preamble in both files so that the AI models understand the purpose of your new section.

#### Integration Documentation Rules

When generating or editing documentation for this repository, you must strictly adhere to the following CI-enforced rules. Failure to do so will break the build.

##### Source Page Constraints (`integrations/**/_index.md`)

1. **Title Convention:** The YAML frontmatter `title` must always end with "Source" (e.g., `title: "Postgres Source"`).
2. **No H1 Tags:** Never generate H1 (`#`) headings in the markdown body.
3. **Strict H2 Ordering:** You must use the following H2 (`##`) headings in this exact sequence.
* `## About` (Required)
* `## Available Tools` (Optional)
* `## Requirements` (Optional)
* `## Example` (Required)
* `## Reference` (Required)
* `## Advanced Usage` (Optional)
* `## Troubleshooting` (Optional)
* `## Additional Resources` (Optional)
4. **Shortcode Placement:** If you generate the `## Available Tools` section, you must include the `{{< list-tools >}}` shortcode beneath it.

##### Asset Constraints (`docs/`)

1. **File Size Limits:** Never add files larger than 24MB to the `docs/` directory.

#### Adding Prebuilt Tools

You can provide developers with a set of "build-time" tools to aid common
Expand Down Expand Up @@ -288,13 +265,22 @@ golangci-lint run --fix

To ensure consistency, we enforce a standardized structure for integration Source pages (_index.md) using a custom linter (.ci/lint_source_pages.sh).

Before pushing changes to integration pages, run the source page linter to verify heading order and required sections:
Before pushing changes to integration pages:

Run the **source page** linter to validate:

```bash
# From the repository root
./.ci/lint-docs-source-page.sh
```

Run the **tool page** linter to validate:

```bash
# From the repository root
./.ci/lint-docs-tool-page.sh
```

### Unit Tests

Execute unit tests locally:
Expand Down Expand Up @@ -438,6 +424,36 @@ We use **[lychee](https://github.com/lycheeverse/lychee-action)** for repository

## Developing Documentation

### Documentation Standards & CI Checks

To maintain consistency and prevent repository bloat, all pull requests must pass the automated documentation linters.

#### Source Page Structure (`integrations/**/_index.md`)

When adding or updating a Source page, your markdown file must strictly adhere to the following architectural rules:

* **Frontmatter:** The `title` field must end with the word "Source" (e.g., `title: "Firestore Source"`).
* **No H1 Headings:** Do not use H1 (`#`) tags in the markdown body. The page title is automatically generated from the frontmatter.
* **H2 Heading Hierarchy:** You must use H2 (`##`) headings in a strict, specific order.
* **Required Headings:** `About`, `Example`, `Reference`
* **Allowed Optional Headings:** `Available Tools`, `Requirements`, `Advanced Usage`, `Troubleshooting`, `Additional Resources`
* **Available Tools Shortcode:** If you include the `## Available Tools` heading, you must place the list-tools shortcode (e.g., `{{< list-tools >}}`) directly beneath it.

#### Tool Page Structure (`integrations/**/*.md`)

When adding or updating a Tool page, your markdown file must strictly adhere to the following architectural rules:

* **Frontmatter:** The `title` field must end with the word "Tool" (e.g., `title: "execute-sql Tool"`).
* **No H1 Headings:** Do not use H1 (`#`) tags in the markdown body. The page title is automatically generated from the frontmatter.
* **H2 Heading Hierarchy:** You must use H2 (`##`) headings in a strict, specific order.
* **Required Headings:** `About`, `Example`
* **Allowed Optional Headings:** `Compatible Sources`, `Requirements`, `Parameters`, `Output Format`, `Reference`, `Advanced Usage`, `Troubleshooting`, `Additional Resources`
* **Compatible Sources Shortcode:** If you include the `## Compatible Sources` heading, you must place the compatible-sources shortcode (e.g., `{{< compatible-sources >}}`) directly beneath it.

#### Repository Asset Limits

* **Max File Size:** No individual file within the `docs/` directory may exceed 24MB. This prevents repository bloat and ensures fast clone times. If you need to include large assets (like high-resolution videos or massive PDFs), host them externally and link to them in the markdown.

### Running a Local Hugo Server

Follow these steps to preview documentation changes locally using a Hugo server:
Expand Down
17 changes: 17 additions & 0 deletions GEMINI.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@ When generating or editing documentation for this repository, you must strictly
* `## Additional Resources` (Optional)
4. **Shortcode Placement:** If you generate the `## Available Tools` section, you must include the `{{< list-tools >}}` shortcode beneath it.

##### Tool Page Constraints (`integrations/**/*.md`)

1. **Title Convention:** The YAML frontmatter `title` must always end with "Tool" (e.g., `title: "Execute SQL Tool"`).
2. **No H1 Tags:** Never generate H1 (`#`) headings in the markdown body.
3. **Strict H2 Ordering:** You must use the following H2 (`##`) headings in this exact sequence.
* `## About` (Required)
* `## Compatible Sources` (Optional)
* `## Requirements` (Optional)
* `## Parameters` (Optional)
* `## Example` (Required)
* `## Output Format` (Optional)
* `## Reference` (Optional)
* `## Advanced Usage` (Optional)
* `## Troubleshooting` (Optional)
* `## Additional Resources` (Optional)
4. **Shortcode Placement:** If you generate the `## Compatible Sources` section, you must include the `{{< compatible-sources >}}` shortcode beneath it.

##### Asset Constraints (`docs/`)

1. **File Size Limits:** Never add files larger than 24MB to the `docs/` directory.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-create-cluster
title: alloydb-create-cluster Tool
type: docs
weight: 1
description: "The \"alloydb-create-cluster\" tool creates a new AlloyDB for PostgreSQL cluster in a specified project and location.\n"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-create-instance
title: alloydb-create-instance Tool
type: docs
weight: 1
description: "The \"alloydb-create-instance\" tool creates a new AlloyDB instance within a specified cluster.\n"
Expand Down
2 changes: 1 addition & 1 deletion docs/en/integrations/alloydb-admin/alloydb-create-user.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-create-user
title: alloydb-create-user Tool
type: docs
weight: 2
description: "The \"alloydb-create-user\" tool creates a new database user within a specified AlloyDB cluster.\n"
Expand Down
2 changes: 1 addition & 1 deletion docs/en/integrations/alloydb-admin/alloydb-get-cluster.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-get-cluster
title: alloydb-get-cluster Tool
type: docs
weight: 1
description: "The \"alloydb-get-cluster\" tool retrieves details for a specific AlloyDB cluster.\n"
Expand Down
2 changes: 1 addition & 1 deletion docs/en/integrations/alloydb-admin/alloydb-get-instance.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-get-instance
title: alloydb-get-instance Tool
type: docs
weight: 1
description: "The \"alloydb-get-instance\" tool retrieves details for a specific AlloyDB instance.\n"
Expand Down
2 changes: 1 addition & 1 deletion docs/en/integrations/alloydb-admin/alloydb-get-user.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-get-user
title: alloydb-get-user Tool
type: docs
weight: 1
description: "The \"alloydb-get-user\" tool retrieves details for a specific AlloyDB user.\n"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-list-clusters
title: alloydb-list-clusters Tool
type: docs
weight: 1
description: "The \"alloydb-list-clusters\" tool lists the AlloyDB clusters in a given project and location.\n"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-list-instances
title: alloydb-list-instances Tool
type: docs
weight: 1
description: "The \"alloydb-list-instances\" tool lists the AlloyDB instances for a given project, cluster and location.\n"
Expand Down
2 changes: 1 addition & 1 deletion docs/en/integrations/alloydb-admin/alloydb-list-users.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: alloydb-list-users
title: alloydb-list-users Tool
type: docs
weight: 1
description: "The \"alloydb-list-users\" tool lists all database users within an AlloyDB cluster.\n"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
---
title: alloydb-wait-for-operation
title: alloydb-wait-for-operation Tool
type: docs
weight: 10
description: "Wait for a long-running AlloyDB operation to complete.\n"
---

## About

The `alloydb-wait-for-operation` tool is a utility tool that waits for a
long-running AlloyDB operation to complete. It does this by polling the AlloyDB
Admin API operation status endpoint until the operation is finished, using
Expand Down
8 changes: 4 additions & 4 deletions docs/en/integrations/alloydb/alloydb-ai-nl.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "alloydb-ai-nl"
title: "alloydb-ai-nl Tool"
type: docs
weight: 1
description: >
Expand Down Expand Up @@ -57,9 +57,9 @@ existing configuration and redefine it using the instructions
[alloydb-ai-gen-nl]:
https://cloud.google.com/alloydb/docs/ai/generate-sql-queries-natural-language

## Configuration
### Configuration

### Specifying an `nl_config`
#### Specifying an `nl_config`

A `nl_config` is a configuration that associates an application to schema
objects, examples and other contexts that can be used. A large application can
Expand All @@ -71,7 +71,7 @@ Once you've followed the steps for configuring context, you can use the
`context` field when configuring a `alloydb-ai-nl` tool. When this tool is
invoked, the SQL will be generated and executed using this context.

### Specifying Parameters to PSV's
#### Specifying Parameters to PSV's

[Parameterized Secure Views (PSVs)][alloydb-psv] are a feature unique to AlloyDB
that allows you to require one or more named parameter values passed
Expand Down
Loading
Loading