Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
ba50393
docs: Add User Guide section (#2647)
dishaprakash Mar 6, 2026
6e19610
docs: Add Integrations section (#2648)
dishaprakash Mar 6, 2026
103b293
docs: Add Build with MCP Toolbox Section (#2649)
dishaprakash Mar 6, 2026
99bc05b
docs: Add reference and other docs (#2650)
dishaprakash Mar 6, 2026
f12c4bf
chore: Add workflows to deploy to cloudflare (#2652)
dishaprakash Mar 10, 2026
c75897e
docs: implement deep re-routing, pagination, and migration banner (#2…
dishaprakash Mar 11, 2026
996a04c
docs: Optimize llms.txt and llms-full.txt (#2665)
dishaprakash Mar 12, 2026
b4f910b
docs: Add page standardization to external source integrations (#2666)
dishaprakash Mar 12, 2026
7679d0a
docs: Add page standardization to external tool integrations (#2668)
dishaprakash Mar 12, 2026
ee89f26
docs: integrate Pagefind search, Google Analytics, and feedback butto…
dishaprakash Mar 12, 2026
bed066f
docs: Fix documentation after internal review (#2723)
dishaprakash Mar 23, 2026
8b15e1c
docs: Update root folder names (#2779)
dishaprakash Mar 23, 2026
43dbdef
docs: Update integrations section structure (#2788)
dishaprakash Mar 23, 2026
3ec5488
docs: Add new UI and samples UI (#2790)
dishaprakash Mar 23, 2026
1aa68a8
Update package-lock.json
dishaprakash Mar 24, 2026
f682bc6
Update package-lock.json
dishaprakash Mar 24, 2026
6885483
Update agent.test.js
dishaprakash Mar 24, 2026
9cef936
Update package-lock.json
dishaprakash Mar 24, 2026
7e1f199
Update package-lock.json
dishaprakash Mar 24, 2026
2a1b591
Update generate_skill.md
dishaprakash Mar 24, 2026
53cc4b2
Update cli.md
dishaprakash Mar 24, 2026
4732e34
Update _index.md
dishaprakash Mar 24, 2026
dc67f2c
Update index.md
dishaprakash Mar 24, 2026
9b3de83
Update index.md
dishaprakash Mar 24, 2026
beb3141
Update _index.md
dishaprakash Mar 24, 2026
2ee5e5d
Update source.md
dishaprakash Mar 24, 2026
0cea268
Update source.md
dishaprakash Mar 24, 2026
ecdf58f
Update _index.md
dishaprakash Mar 24, 2026
55b2f67
Update package-lock.json
dishaprakash Mar 24, 2026
1ef93c7
Update generate_skill.md
dishaprakash Mar 24, 2026
5cc64e6
Update cli.md
dishaprakash Mar 24, 2026
ccf045c
Update _index.md
dishaprakash Mar 24, 2026
e4a956a
Update _index.md
dishaprakash Mar 24, 2026
7b91ebc
Update production-security-warning.html
dishaprakash Mar 24, 2026
f21ef09
Update requirements.txt
dishaprakash Mar 24, 2026
387ebad
Create style-guide.md
dishaprakash Mar 24, 2026
946befa
Create oracle_mcp.md
dishaprakash Mar 24, 2026
5d6457d
Update _index.md
dishaprakash Mar 24, 2026
395e340
Update source.md
dishaprakash Mar 24, 2026
f4366ea
Create oracle-list-tables.md
dishaprakash Mar 24, 2026
af6b7b4
Update release-please.yml
dishaprakash Mar 24, 2026
3835c53
Update _index.md
dishaprakash Mar 24, 2026
a3c4a77
Create looker-git-branch.md
dishaprakash Mar 24, 2026
af620c4
Update generate_skill.md
dishaprakash Mar 24, 2026
e145933
Update cli.md
dishaprakash Mar 24, 2026
ce603c3
Update source.md
dishaprakash Mar 24, 2026
c156393
Update source.md
dishaprakash Mar 24, 2026
5e40bcf
Update dataplex-search-entries.md
dishaprakash Mar 24, 2026
9fe06d5
Create _index.md
dishaprakash Mar 24, 2026
a54fc41
Create index.md
dishaprakash Mar 24, 2026
44bfb5d
Update looker_mcp.md
dishaprakash Mar 24, 2026
e69a5cb
Update _index.md
dishaprakash Mar 24, 2026
5a05879
Update looker_gemini.md
dishaprakash Mar 24, 2026
3ca215b
Update looker_mcp.md
dishaprakash Mar 24, 2026
23f8718
Update looker_mcp.md
dishaprakash Mar 24, 2026
2a883c9
Create versioning.md
dishaprakash Mar 24, 2026
77371fd
Propagating changes from main
dishaprakash Mar 24, 2026
99a9793
rebase onto main
dishaprakash Mar 24, 2026
289e7a1
rebase onto main
dishaprakash Mar 24, 2026
7264f28
rebase onto main
dishaprakash Mar 24, 2026
3528780
rebase onto main
dishaprakash Mar 24, 2026
0da306f
Update _index.md
dishaprakash Mar 24, 2026
a7f20d0
Update hugo.toml
dishaprakash Mar 24, 2026
3ac06e7
Update _index.md
dishaprakash Mar 24, 2026
37be1e6
update sdk pages
dishaprakash Mar 24, 2026
1294110
CodeQL fixes
dishaprakash Mar 24, 2026
aac4c67
retrigger gha workflows
dishaprakash Mar 24, 2026
2121d42
Update GEMINI.md
dishaprakash Mar 24, 2026
e83937b
revert changes to package-lock.json files
dishaprakash Mar 24, 2026
d2b553f
revert change to package-lock
dishaprakash Mar 24, 2026
01129ba
add samples instructions
dishaprakash Mar 24, 2026
6b3d5ca
update order of left navbar
dishaprakash Mar 24, 2026
7ed6bb1
add type
dishaprakash Mar 24, 2026
18d55df
add pagefind in previews
dishaprakash Mar 24, 2026
fb72685
rebase
dishaprakash Mar 24, 2026
78aca78
redirect icons fix
dishaprakash Mar 24, 2026
68aefea
enable list dbs
dishaprakash Mar 24, 2026
5fc859d
review changes
dishaprakash Mar 25, 2026
3dcc6fd
rebase
dishaprakash Mar 25, 2026
580a4f8
update path
dishaprakash Mar 25, 2026
b858b09
link check
dishaprakash Mar 25, 2026
abff835
Update deploy_versioned_docs_to_cf.yaml
dishaprakash Mar 25, 2026
bfaf6f5
Update deploy_previous_version_docs_to_cf.yaml
dishaprakash Mar 25, 2026
d58ced7
Update lint-docs-source-page.sh
dishaprakash Mar 25, 2026
219ebd1
Update go.integration.cloudbuild.yaml
dishaprakash Mar 25, 2026
5488e68
Merge remote-tracking branch 'origin/main' into documentation-reorg
dishaprakash Mar 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
136 changes: 136 additions & 0 deletions .ci/lint-docs-source-page.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/bin/bash
set -e


python3 - << 'EOF'
"""
MCP TOOLBOX: SOURCE PAGE LINTER
===============================
This script enforces a standardized structure for integration Source pages
(source.md files). It ensures users can predictably find connection details
and configurations across all database integrations.

Note: The structural _index.md folder wrappers are intentionally ignored
by this script as they should only contain YAML frontmatter.

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/OPTIONAL:
Add or remove the heading text in the 'REQUIRED' set.

3. TO IGNORE NEW CONTENT TYPES:
Update the regex in the 'clean_body' variable to strip out
Markdown before linting.

4. SCOPE:
This script only targets docs/en/integrations/**/source.md.
"""

import os
import re
import sys
from pathlib import Path

# --- CONFIGURATION ---
ALLOWED_ORDER = [
"About",
"Available Tools",
"Requirements",
"Example",
"Reference",
"Advanced Usage",
"Troubleshooting",
"Additional Resources"
]
REQUIRED = {"About", "Example", "Reference"}

# Regex to catch any variation of the list-tools shortcode
SHORTCODE_PATTERN = r"\{\{<\s*list-tools.*?>\}\}"
# ---------------------

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
source_pages_found = 0

# ONLY scan files specifically named "source.md"
for filepath in integration_dir.rglob("source.md"):
source_pages_found += 1
file_errors = False

if filepath.parent.parent != integration_dir:
continue

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

match = re.match(r'^\s*---\s*\n(.*?)\n---\s*(.*)', content, re.DOTALL)
if match:
frontmatter, body = match.group(1), match.group(2)
else:
print(f"[{filepath}] Error: Missing or invalid YAML frontmatter.")
has_errors = True
continue

# 1. Check for linkTitle: "Source" in frontmatter
link_title_match = re.search(r"^linkTitle:\s*[\"']?(.*?)[\"']?\s*$", frontmatter, re.MULTILINE)
if not link_title_match or link_title_match.group(1).strip() != "Source":
print(f"[{filepath}] Error: Frontmatter must contain exactly linkTitle: \"Source\".")
file_errors = True

# 2. Check for weight: 1 in frontmatter
weight_match = re.search(r"^weight:\s*[\"']?(\d+)[\"']?\s*$", frontmatter, re.MULTILINE)
if not weight_match or weight_match.group(1).strip() != "1":
print(f"[{filepath}] Error: Frontmatter must contain exactly weight: 1.")
file_errors = True

# 3. Check Shortcode Placement & Available Tools Section (Only if present)
tools_section_match = re.search(r"^##\s+Available Tools\s*(.*?)(?=^##\s|\Z)", body, re.MULTILINE | re.DOTALL)
if tools_section_match:
if not re.search(SHORTCODE_PATTERN, tools_section_match.group(1)):
print(f"[{filepath}] Error: The list-tools shortcode must be placed under the '## Available Tools' heading.")
file_errors = True

# Strip code blocks from body to avoid linting example markdown headings
clean_body = re.sub(r"```.*?```", "", body, flags=re.DOTALL)

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

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

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

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

# 5. Order Check
if [h for h in h2s if h in ALLOWED_ORDER] != [h for h in ALLOWED_ORDER if h in h2s]:
print(f"[{filepath}] Error: Headings out of order. Reference: {ALLOWED_ORDER}")
file_errors = True

if file_errors: has_errors = True

# Handle final output based on what was found
if source_pages_found == 0:
print("Info: No 'source.md' files found in integrations. Passing gracefully.")
sys.exit(0)
elif has_errors:
print(f"\nLinting failed. Please fix the structure errors in the {source_pages_found} 'source.md' file(s) above.")
sys.exit(1)
else:
print(f"Success: {source_pages_found} 'source.md' file(s) passed structure validation.")
EOF
155 changes: 155 additions & 0 deletions .ci/lint-docs-tool-page.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#!/bin/bash
set -e

python3 - << 'EOF'
"""
MCP TOOLBOX: TOOL PAGE LINTER
=============================
This script enforces a standardized structure for individual Tool pages
and their parent directory wrappers. It ensures 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/OPTIONAL:
Add or remove the heading text in the 'REQUIRED' set.

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

4. SCOPE & BEHAVIOR:
This script targets all .md files in docs/en/integrations/**/tools/.
- For `_index.md` files: It only validates the frontmatter (requiring
`title: "Tools"` and `weight: 2`) and ignores the body.
- For regular tool files: It validates H1/H2 hierarchy, checks for
required headings ("About", "Example"), and enforces that the
`{{< compatible-sources >}}` shortcode is paired with the
"## Compatible Sources" heading.
"""

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
tools_pages_found = 0

# Specifically target the tools directories
for filepath in integration_dir.rglob("tools/*.md"):
tools_pages_found += 1
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:
print(f"[{filepath}] Error: Missing or invalid YAML frontmatter.")
has_errors = True
continue

file_errors = False

# --- SPECIAL VALIDATION FOR tools/_index.md ---
if filepath.name == "_index.md":
title_match = re.search(r"^title:\s*[\"']?(.*?)[\"']?\s*$", frontmatter, re.MULTILINE)
if not title_match or title_match.group(1).strip() != "Tools":
print(f"[{filepath}] Error: tools/_index.md must have exactly title: \"Tools\"")
file_errors = True

weight_match = re.search(r"^weight:\s*(\d+)\s*$", frontmatter, re.MULTILINE)
if not weight_match or weight_match.group(1).strip() != "2":
print(f"[{filepath}] Error: tools/_index.md must have exactly weight: 2")
file_errors = True

if file_errors:
has_errors = True
continue # Skip the rest of the body linting for this structural file

# --- VALIDATION FOR REGULAR TOOL PAGES ---
# If the file has no markdown content (metadata placeholder only), skip it entirely
if not body.strip():
continue

# 1. 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

# 2. Strip code blocks from body to avoid linting example markdown headings
clean_body = re.sub(r"```.*?```", "", body, flags=re.DOTALL)

# 3. 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

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

# 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 tools_pages_found == 0:
print("Info: No tool directories found. Passing gracefully.")
sys.exit(0)
elif has_errors:
print("Linting failed for Tool pages. Please fix the structure errors above.")
sys.exit(1)
else:
print(f"Success: All {tools_pages_found} Tool page(s) passed structure validation.")
EOF
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ timeout: 1200s
substitutions:
_TARGET_LANG: "go"
_IMAGE: "golang:1.25.7"
_TARGET_ROOT: "docs/en/samples/pre_post_processing/go"
_TARGET_ROOT: "docs/en/documentation/configuration/pre-post-processing/go"
_TABLE_NAME: "hotels_go_pre_post_processing"
_SQL_FILE: ".ci/sample_tests/setup_hotels.sql"
_AGENT_FILE_PATTERN: "agent.go"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ timeout: 1200s
substitutions:
_TARGET_LANG: "js"
_IMAGE: "node:22"
_TARGET_ROOT: "docs/en/samples/pre_post_processing/js"
_TARGET_ROOT: "docs/en/documentation/configuration/pre-post-processing/js"
_TABLE_NAME: "hotels_js_pre_post_processing"
_SQL_FILE: ".ci/sample_tests/setup_hotels.sql"
_AGENT_FILE_PATTERN: "agent.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ timeout: 1200s
substitutions:
_TARGET_LANG: "python"
_IMAGE: "gcr.io/google.com/cloudsdktool/cloud-sdk:537.0.0"
_TARGET_ROOT: "docs/en/samples/pre_post_processing/python"
_TARGET_ROOT: "docs/en/documentation/configuration/pre-post-processing/python"
_TABLE_NAME: "hotels_py_pre_post_processing"
_SQL_FILE: ".ci/sample_tests/setup_hotels.sql"
_AGENT_FILE_PATTERN: "agent.py"
Expand Down
6 changes: 3 additions & 3 deletions .ci/sample_tests/quickstart/go.integration.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

steps:
- name: 'golang:1.25.1'
- name: 'golang:1.25.7'
id: 'go-quickstart-test'
entrypoint: 'bash'
args:
Expand All @@ -30,7 +30,7 @@ steps:
- 'GCP_PROJECT=${_GCP_PROJECT}'
- 'DATABASE_NAME=${_DATABASE_NAME}'
- 'DB_USER=${_DB_USER}'
- 'TARGET_ROOT=docs/en/getting-started/quickstart/go'
- 'TARGET_ROOT=docs/en/documentation/getting-started/quickstart/go'
- 'TARGET_LANG=go'
- 'TABLE_NAME=hotels_go'
- 'SQL_FILE=.ci/sample_tests/setup_hotels.sql'
Expand All @@ -49,4 +49,4 @@ availableSecrets:
timeout: 1000s

options:
logging: CLOUD_LOGGING_ONLY
logging: CLOUD_LOGGING_ONLY
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ steps:
- 'GCP_PROJECT=${_GCP_PROJECT}'
- 'DATABASE_NAME=${_DATABASE_NAME}'
- 'DB_USER=${_DB_USER}'
- 'TARGET_ROOT=docs/en/getting-started/quickstart/js'
- 'TARGET_ROOT=docs/en/documentation/getting-started/quickstart/js'
- 'TARGET_LANG=js'
- 'TABLE_NAME=hotels_js'
- 'SQL_FILE=.ci/sample_tests/setup_hotels.sql'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ steps:
- 'GCP_PROJECT=${_GCP_PROJECT}'
- 'DATABASE_NAME=${_DATABASE_NAME}'
- 'DB_USER=${_DB_USER}'
- 'TARGET_ROOT=docs/en/getting-started/quickstart/python'
- 'TARGET_ROOT=docs/en/documentation/getting-started/quickstart/python'
- 'TARGET_LANG=python'
- 'TABLE_NAME=hotels_python'
- 'SQL_FILE=.ci/sample_tests/setup_hotels.sql'
Expand Down
7 changes: 3 additions & 4 deletions .github/header-checker-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ sourceFileExtensions:
- 'yaml'
- 'yml'
ignoreFiles:
- 'docs/en/getting-started/quickstart/**'
- 'docs/en/samples/**'
- '**/*oracle*'

- 'docs/en/documentation/**/*.go'
- 'docs/en/samples/**/*'
- '**/*oracle*'
Loading
Loading