diff --git a/.github/workflows/skills-validate-fallback.yml b/.github/workflows/skills-validate-fallback.yml
new file mode 100644
index 0000000..b49eb62
--- /dev/null
+++ b/.github/workflows/skills-validate-fallback.yml
@@ -0,0 +1,37 @@
+# Copyright 2026 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: lint
+
+on:
+  push:
+    paths-ignore:
+      - "skills/**"
+  pull_request:
+    paths-ignore:
+      - "skills/**"
+  pull_request_target:
+    types: [labeled]
+    paths-ignore:
+      - "skills/**"
+  workflow_dispatch:
+
+jobs:
+  skills-validate:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Skip Skill Validation
+        run: |
+          echo "No changes detected in 'skills/' directory. Skipping validation."
+          echo "This job ensures the required 'skills-validate' status check passes."
diff --git a/.github/workflows/skills-validate.yml b/.github/workflows/skills-validate.yml
new file mode 100644
index 0000000..c831e21
--- /dev/null
+++ b/.github/workflows/skills-validate.yml
@@ -0,0 +1,56 @@
+# Copyright 2026 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: Validate Skills
+
+on:
+  push:
+    paths:
+      - "skills/**"
+  pull_request:
+    paths:
+      - "skills/**"
+  pull_request_target:
+    types: [labeled]
+    paths:
+      - "skills/**"
+
+jobs:
+  skills-validate:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Set up Python
+        uses: actions/setup-python@v5
+        with:
+          python-version: "3.11"
+
+      - name: Install skills-ref
+        run: |
+          pip install "git+https://github.com/agentskills/agentskills.git#subdirectory=skills-ref"
+
+      - name: Validate Skills
+        run: |
+          failed=0
+          for skill_dir in skills/*/; do
+            if [ -d "$skill_dir" ]; then
+              echo "Validating $skill_dir..."
+              if ! skills-ref validate "$skill_dir"; then
+                echo "Validation failed for $skill_dir"
+                failed=1
+              fi
+            fi
+          done
+          exit $failed
diff --git a/CLOUD-SQL-POSTGRESQL.md b/CLOUD-SQL-POSTGRESQL.md
index c09d3ed..4cf31be 100644
--- a/CLOUD-SQL-POSTGRESQL.md
+++ b/CLOUD-SQL-POSTGRESQL.md
@@ -13,7 +13,7 @@ To install this extension, the Gemini CLI version must be v0.6.0 or above. The v
 
 This section covers connecting to a Cloud SQL for PostgreSQL instance.
 
-1. **Verify Environment Variables**: The extension requires the following environment variables to be set before the Gemini CLI is started:
+1. **Extension Configuration**: This extension requires several settings (e.g., Project ID, Instance ID, Database Name, User, and Password). These values are gathered via prompts when you first install or link the extension:
 
     * `CLOUD_SQL_POSTGRES_PROJECT`: The GCP project ID.
     * `CLOUD_SQL_POSTGRES_REGION`: The region of your Cloud SQL instance.
@@ -22,6 +22,8 @@ This section covers connecting to a Cloud SQL for PostgreSQL instance.
     * `CLOUD_SQL_POSTGRES_USER`: The database username.
     * `CLOUD_SQL_POSTGRES_PASSWORD`: The password for the database user.
 
+    If you need to update any of these values later, use the `gemini extensions config cloud-sql-postgresql` command.
+
 2. **Handle Missing Variables**: If a command fails with an error message containing a placeholder like `${CLOUD_SQL_POSTGRES_PROJECT}`, it signifies a missing environment variable. Inform the user which variable is missing and instruct them to set it.
 
 3. **Handle Permission Errors**: If you encounter permission errors, ensure the user has the **Cloud SQL Client** (`roles/cloudsql.client`) role and the correct database-level permissions.
@@ -39,9 +41,9 @@ This section covers administrative operations like managing clusters, instances,
 
 ---
 
-# Additional Tools
+# Additional Skills
 
-This section provides context on additional tools that can be recommended to the user based on their queries.
+This section provides context on additional skills that can be recommended to the user based on their queries.
 
 #### Observability Extension
 
@@ -58,12 +60,12 @@ This section provides context on additional tools that can be recommended to the
 
 ## Connecting to New Resources
 
-When you create a new Cloud SQL for PostgreSQL instance, or database using the available tools, the connection is not automatically established. You will need to perform the following steps:
+When you create a new Cloud SQL for PostgreSQL instance, or database using the available skills, the connection is not automatically established. You will need to perform the following steps:
 
 1.  **(Optional) Save your conversation:** To avoid losing your progress, save the current session by running the command: `/chat save <your-tag>`
-2.  **Stop the CLI:** Terminate the Gemini CLI.
-3.  **Update Environment Variables:** Set or update your environment variables (e.g. `CLOUD_SQL_POSTGRES_DATABASE`, `CLOUD_SQL_POSTGRES_INSTANCE`) to point to the new resource.
-4.  **Restart:** Relaunch the Gemini CLI
+2. **Stop the CLI**: Terminate the Gemini CLI.
+3. **Update Extension Configuration**: Use the command `gemini extensions config cloud-sql-postgresql` to update your settings (e.g. `CLOUD_SQL_POSTGRES_DATABASE`, `CLOUD_SQL_POSTGRES_INSTANCE`) to point to the new resource.
+4. **Restart**: Relaunch the Gemini CLI
 5.  **(Optional) Resume conversation:** Resume your conversation with the command: `/chat resume <your-tag>`
 
 **Important:** Do not assume a connection to a newly created resource is active. Always follow the steps above to reconfigure your connection.
@@ -77,12 +79,13 @@ Users may have set project environment variables:
 *   `CLOUD_SQL_POSTGRES_INSTANCE`: The ID of the Cloud SQL for PostgreSQL instance.
 *   `CLOUD_SQL_POSTGRES_DATABASE`: The name of the database.
 
-Instead of prompting the user for these values for specific tool calls, prompt the user to verify reuse a specific value.
-Make sure to not use the environment variable name like `CLOUD_SQL_POSTGRES_PROJECT`, `${CLOUD_SQL_POSTGRES_PROJECT}`, or `$CLOUD_SQL_POSTGRES_PROJECT`. The value can be found by using command: `echo $CLOUD_SQL_POSTGRES_PROJECT`.
+Instead of prompting the user for these values for specific skill calls, prompt the user to verify the reuse of a specific setting value.
+Make sure to not use the environment variable name like `CLOUD_SQL_POSTGRES_PROJECT`, `${CLOUD_SQL_POSTGRES_PROJECT}`, or `$CLOUD_SQL_POSTGRES_PROJECT`. 
+The value can be verified by the user using the `gemini extensions config cloud-sql-postgresql` command or by checking their local settings.
 
 ## Use Full Table Name Format "DATABASE_NAME.SCHEMA_NAME.TABLE_NAME"
 
-**ALWAYS** use the full table name format, `DATABASE_NAME.SCHEMA_NAME.TABLE_NAME` in the generated SQL when using the `execute_sql` or `cloud_sql_postgresql__execute_sql` tool.
+**ALWAYS** use the full table name format, `DATABASE_NAME.SCHEMA_NAME.TABLE_NAME` in the generated SQL when executing the `execute_sql` script.
 * Default to using "public" for the schema name.
 * Use command `echo $CLOUD_SQL_POSTGRES_DATABASE` to get the current database value.
 
@@ -92,7 +95,7 @@ When working with AI features like vector embeddings in Cloud SQL, leverage the
 
 Embeddings can be generated using the `embedding()` function. For example: `embedding(<model_name>, <text_column_or_variable>)`.
 
-As an agent, if you do not know which model to use, you should use your tools to search for available and appropriate text embedding models compatible with the `google_ml_integration` extension (e.g., by searching for "Cloud SQL google_ml_integration supported models").
+As an agent, if you do not know which model to use, you should use your skills to search for available and appropriate text embedding models compatible with the `google_ml_integration` extension (e.g., by searching for "Cloud SQL google_ml_integration supported models").
 
 When performing similarity searches, remember to cast the result of the `embedding` function to the `vector` type. For example:
 `ORDER BY description_vector <-> embedding(<model_name>, $1)::vector`
diff --git a/DEVELOPER.md b/DEVELOPER.md
index 34fe96d..07162e3 100644
--- a/DEVELOPER.md
+++ b/DEVELOPER.md
@@ -43,7 +43,7 @@ The core logic for this extension is handled by a pre-built `toolbox` binary. Th
     extension from your local directory.
 
     ```bash
-    gemini extensions link .
+    gemini extensions install .
     ```
     The CLI will prompt you to confirm the installation. Accept it to proceed.
 
diff --git a/README.md b/README.md
index 1bea7d5..3aff45c 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 > [!NOTE]
 > This extension is currently in beta (pre-v1.0), and may see breaking changes until the first stable release (v1.0).
 
-This Gemini CLI extension provides a set of tools to interact with [Cloud SQL for PostgreSQL](https://cloud.google.com/sql/docs/postgres) instances. It allows you to manage your databases, execute queries, explore schemas, and troubleshoot issues directly from the [Gemini CLI](https://google-gemini.github.io/gemini-cli/), using natural language prompts.
+This Gemini CLI extension provides a set of skills to interact with [Cloud SQL for PostgreSQL](https://cloud.google.com/sql/docs/postgres) instances. It allows you to manage your databases, execute queries, explore schemas, and troubleshoot issues directly from the [Gemini CLI](https://google-gemini.github.io/gemini-cli/), using natural language prompts.
 
 Learn more about [Gemini CLI Extensions](https://github.com/google-gemini/gemini-cli/blob/main/docs/extensions/index.md).
 > [!IMPORTANT]
@@ -58,7 +58,7 @@ You will be prompted to configure the following settings during installation. Th
 *   `CLOUD_SQL_POSTGRES_IP_TYPE`: (Optional) Type of the IP address: `PUBLIC`, `PRIVATE`, or `PSC`. Defaults to `PUBLIC`.
 
 > [!NOTE]
-> This configuration is primarily for the Data Plane tools (querying). The Admin toolset does not strictly require these to be pre-set if you provide them in your prompts, but it is recommended for a smoother experience.
+> This configuration is primarily for the Data Plane skills (querying). The Admin skillset does not strictly require these to be pre-set if you provide them in your prompts, but it is recommended for a smoother experience.
 
 To view or update your configuration:
 
@@ -87,7 +87,7 @@ export CLOUD_SQL_POSTGRES_IP_TYPE="PUBLIC" # Optional: `PUBLIC`, `PRIVATE`, `PSC
 > [!NOTE]
 > * Ensure [Application Default Credentials](https://cloud.google.com/docs/authentication/gcloud) are available in your environment.
 > * If your Cloud SQL for PostgreSQL instance uses private IPs, you must run Gemini CLI in the same Virtual Private Cloud (VPC) network.
-> * See [Troubleshooting](#troubleshooting) for debugging your configuration. 
+> * See [Troubleshooting](#troubleshooting) for debugging your configuration.
 
 ### Start Gemini CLI
 
@@ -116,43 +116,12 @@ Interact with Cloud SQL for PostgreSQL using natural language:
 * **Generate Code:**
   * "Generate a Python dataclass to represent the 'customers' table."
 
-## Supported Tools
-
-* **Admin:**
-    * `clone_instance`: Creates a clone for an existing Cloud SQL for PostgreSQL instance.
-    * `create_backup`: Creates a backup on a Cloud SQL instance.
-   	* `create_instance`: Use this tool to create an Postgres instance.
-   	* `create_user`: Use this tool to create Postgres-BUILT-IN or IAM-based users.
-    * `create_database`: Creates a new database in a Cloud SQL instance.
-   	* `get_instance`: Use this tool to get details about an Postgres instance.
-   	* `list_instances`: Use this tool to list instances in a given project and location.
-    * `list_databases`: Lists all databases for a Cloud SQL instance.
-    * `restore_backup`: Restores a backup of a Cloud SQL instance.
-    * `wait_for_operation`: Use this tool to poll the operations API until the operation is done.
-
-* **Data:**
-    * `list_tables`: Use this tool to lists tables in the database.
-    * `database_overview`: Use this tool to fetches the current state of the PostgreSQL server.
-    * `execute_sql`: Use this tool to executes a SQL query.
-    * `list_active_queries`: Use this tool to list currently running queries.
-    * `list_available_extensions`: Use this tool to list available extensions for installation.
-    * `list_installed_extensions`: Use this tool to list installed extensions.
-    * `get_query_plan`: Use this tool to get query plan.
-    * `list_autovacuum_configurations`: Use this tool to list autovacuum configurations and its value.
-    * `list_database_stats`: Use this tool to lists the key performance and activity statistics for each database in the postgreSQL instance.
-    * `list_indexes`: Use this tool to list available user indexes in a PostgreSQL database.
-    * `list_memory_configurations`: Use this tool to list memory configurations and its value.
-    * `list_pg_settings`: Use this tool to list configuration parameters for the PostgreSQL server.
-    * `list_publication_tables`: Use this tool to list publication tables in a PostgreSQL database.
-    * `list_replication_slots`: Use this tool to list replication slots.
-    * `list_roles`: Use this tool to lists all the user-created roles in PostgreSQL database.
-    * `list_schemas`: Use this tool to lists schemas in the database.
-    * `list_sequences`: Use this tool to list sequences in a PostgreSQL database.
-    * `list_tablespaces`: Use this tool to lists tablespaces in the database.
-    * `list_top_bloated_tables`: Use this tool to list top bloated tables.
-    * `list_triggers`: Use this tool to lists triggers in the database.
-    * `list_views`: Use this tool to lists views in the database from pg_views with a default limit of 50 rows.
-    * `list_invalid_indexes`: Use this tool to list invalid indexes.
+## Supported Skills
+
+This extension provides the following skills:
+
+* [Cloud SQL for PostgreSQL Admin](skills/cloudsql-postgres-admin/SKILL.md) - Manage Cloud SQL instances, databases, and users.
+* [Cloud SQL for PostgreSQL](skills/cloudsql-postgres/SKILL.md) - Query databases and manage extensions.
 
 ## Additional Extensions
 
diff --git a/gemini-extension.json b/gemini-extension.json
index f598696..d2ed872 100644
--- a/gemini-extension.json
+++ b/gemini-extension.json
@@ -2,24 +2,6 @@
   "name": "cloud-sql-postgresql",
   "version": "0.1.11",
   "description": "Create, connect, and interact with a Cloud SQL for PostgreSQL database and data.",
-  "mcpServers": {
-    "cloud_sql_postgresql_admin": {
-      "command": "${extensionPath}${/}toolbox",
-      "args": [
-        "--prebuilt",
-        "cloud-sql-postgres-admin",
-        "--stdio"
-      ]
-    },
-    "cloud_sql_postgresql": {
-      "command": "${extensionPath}${/}toolbox",
-      "args": [
-        "--prebuilt",
-        "cloud-sql-postgres",
-        "--stdio"
-      ]
-    }
-  },
   "contextFileName": "CLOUD-SQL-POSTGRESQL.md",
   "settings": [
     {
diff --git a/skills/cloudsql-postgres-admin/SKILL.md b/skills/cloudsql-postgres-admin/SKILL.md
new file mode 100644
index 0000000..a308060
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/SKILL.md
@@ -0,0 +1,193 @@
+---
+name: cloudsql-postgres-admin
+description: skill for performing administrative operations on cloudsql postgres
+---
+
+## Usage
+
+All scripts can be executed using Node.js. Replace `<param_name>` and `<param_value>` with actual values.
+
+**Bash:**
+`node <skill_dir>/scripts/<script_name>.js '{"<param_name>": "<param_value>"}'`
+
+**PowerShell:**
+`node <skill_dir>/scripts/<script_name>.js '{\"<param_name>\": \"<param_value>\"}'`
+
+Note: The scripts automatically load the environment variables from various .env files. Do not ask the user to set vars unless skill executions fails due to env var absence.
+
+## Scripts
+
+
+### clone_instance
+
+Clone an existing Cloud SQL instance into a new instance. The clone can be a direct copy of the source instance, or a point-in-time-recovery (PITR) clone from a specific timestamp. The call returns a Cloud SQL Operation object. Call wait_for_operation tool after this, make sure to use multiplier as 4 to poll the opertation status till it is marked DONE.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| sourceInstanceName | string | The name of the instance to be cloned. | Yes |  |
+| destinationInstanceName | string | The name of the new instance that will be created by cloning the source instance. | Yes |  |
+| pointInTime | string | The timestamp in RFC 3339 format to which the source instance should be cloned. | No |  |
+| preferredZone | string | The preferred zone for the new instance. | No |  |
+| preferredSecondaryZone | string | The preferred secondary zone for the new instance. | No |  |
+
+
+---
+
+### create_backup
+
+Creates a backup on a Cloud SQL instance.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| instance | string | Cloud SQL instance ID. This does not include the project ID. | Yes |  |
+| location | string | Location of the backup run. | No |  |
+| backup_description | string | The description of this backup run. | No |  |
+
+
+---
+
+### create_database
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| instance | string | The ID of the instance where the database will be created. | Yes |  |
+| name | string | The name for the new database. Must be unique within the instance. | Yes |  |
+
+
+---
+
+### create_instance
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| name | string | The name of the instance | Yes |  |
+| databaseVersion | string | The database version for Postgres. If not specified, defaults to the latest available version (e.g., POSTGRES_17). | No | `POSTGRES_17` |
+| rootPassword | string | The root password for the instance | Yes |  |
+| editionPreset | string | The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`. | No | `Development` |
+
+
+---
+
+### create_user
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| instance | string | The ID of the instance where the user will be created. | Yes |  |
+| name | string | The name for the new user. Must be unique within the instance. | Yes |  |
+| password | string | A secure password for the new user. Not required for IAM users. | No |  |
+| iamUser | boolean | Set to true to create a Cloud IAM user. | Yes |  |
+
+
+---
+
+### get_instance
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| projectId | string | The project ID | Yes |  |
+| instanceId | string | The instance ID | Yes |  |
+
+
+---
+
+### list_databases
+
+Lists all databases for a Cloud SQL instance.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| instance | string | The instance ID | Yes |  |
+
+
+---
+
+### list_instances
+
+Lists all type of Cloud SQL instances for a project.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+
+
+---
+
+### postgres_upgrade_precheck
+
+Analyzes a Cloud SQL PostgreSQL instance for major version upgrade readiness. Results are provided to guide customer actions:
+ERROR: Action Required. These are critical issues blocking the upgrade. Customers must resolve these using the provided actions_required steps before attempting the upgrade.
+WARNING: Review Recommended. These are potential issues. Customers should review the message and actions_required. While not blocking, addressing these is advised to prevent future problems or unexpected behavior post-upgrade.
+INFO: No Action Needed. Informational messages only. This pre-check helps customers proactively fix problems, preventing upgrade failures and ensuring a smoother transition.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| instance | string | The name of the instance to check | Yes |  |
+| targetDatabaseVersion | string | The target PostgreSQL version for the upgrade (e.g., POSTGRES_18). If not specified, defaults to the PostgreSQL 18. | No | `POSTGRES_18` |
+
+
+---
+
+### restore_backup
+
+Restores a backup on a Cloud SQL instance.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| target_project | string | The project ID | Yes |  |
+| target_instance | string | Cloud SQL instance ID of the target instance. This does not include the project ID. | Yes |  |
+| backup_id | string | Identifier of the backup being restored. Can be a BackupRun ID, backup name, or BackupDR backup name. Use the full backup ID as provided, do not try to parse it | Yes |  |
+| source_project | string | GCP project ID of the instance that the backup belongs to. Only required if the backup_id is a BackupRun ID. | No |  |
+| source_instance | string | Cloud SQL instance ID of the instance that the backup belongs to. Only required if the backup_id is a BackupRun ID. | No |  |
+
+
+---
+
+### wait_for_operation
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| project | string | The project ID | Yes |  |
+| operation | string | The operation ID | Yes |  |
+
+
+---
+
diff --git a/skills/cloudsql-postgres-admin/scripts/clone_instance.js b/skills/cloudsql-postgres-admin/scripts/clone_instance.js
new file mode 100755
index 0000000..df3f6aa
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/clone_instance.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "clone_instance";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/create_backup.js b/skills/cloudsql-postgres-admin/scripts/create_backup.js
new file mode 100755
index 0000000..bde7983
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/create_backup.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "create_backup";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/create_database.js b/skills/cloudsql-postgres-admin/scripts/create_database.js
new file mode 100755
index 0000000..b3ab345
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/create_database.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "create_database";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/create_instance.js b/skills/cloudsql-postgres-admin/scripts/create_instance.js
new file mode 100755
index 0000000..776fe06
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/create_instance.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "create_instance";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/create_user.js b/skills/cloudsql-postgres-admin/scripts/create_user.js
new file mode 100755
index 0000000..601d592
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/create_user.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "create_user";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/get_instance.js b/skills/cloudsql-postgres-admin/scripts/get_instance.js
new file mode 100755
index 0000000..a7113f5
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/get_instance.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "get_instance";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/list_databases.js b/skills/cloudsql-postgres-admin/scripts/list_databases.js
new file mode 100755
index 0000000..d5173b1
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/list_databases.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_databases";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/list_instances.js b/skills/cloudsql-postgres-admin/scripts/list_instances.js
new file mode 100755
index 0000000..557af1c
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/list_instances.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_instances";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/postgres_upgrade_precheck.js b/skills/cloudsql-postgres-admin/scripts/postgres_upgrade_precheck.js
new file mode 100755
index 0000000..3d94b38
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/postgres_upgrade_precheck.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "postgres_upgrade_precheck";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/restore_backup.js b/skills/cloudsql-postgres-admin/scripts/restore_backup.js
new file mode 100755
index 0000000..aa6105e
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/restore_backup.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "restore_backup";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres-admin/scripts/wait_for_operation.js b/skills/cloudsql-postgres-admin/scripts/wait_for_operation.js
new file mode 100755
index 0000000..24247a2
--- /dev/null
+++ b/skills/cloudsql-postgres-admin/scripts/wait_for_operation.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "wait_for_operation";
+const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/SKILL.md b/skills/cloudsql-postgres/SKILL.md
new file mode 100644
index 0000000..1f52cf0
--- /dev/null
+++ b/skills/cloudsql-postgres/SKILL.md
@@ -0,0 +1,398 @@
+---
+name: cloudsql-postgres
+description: skill for running tool operations in CloudSql postgres
+---
+
+## Usage
+
+All scripts can be executed using Node.js. Replace `<param_name>` and `<param_value>` with actual values.
+
+**Bash:**
+`node <skill_dir>/scripts/<script_name>.js '{"<param_name>": "<param_value>"}'`
+
+**PowerShell:**
+`node <skill_dir>/scripts/<script_name>.js '{\"<param_name>\": \"<param_value>\"}'`
+
+Note: The scripts automatically load the environment variables from various .env files. Do not ask the user to set vars unless skill executions fails due to env var absence.
+
+## Scripts
+
+
+### database_overview
+
+Fetches the current state of the PostgreSQL server, returning the version, whether it's a replica, uptime duration, maximum connection limit, number of current connections, number of active connections, and the percentage of connections in use.
+
+
+
+---
+
+### execute_sql
+
+Use this tool to execute sql.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| sql | string | The sql to execute. | Yes |  |
+
+
+---
+
+### get_column_cardinality
+
+Estimates the number of unique values (cardinality) quickly for one or all columns in a specific PostgreSQL table by using the database's internal statistics, returning the results in descending order of estimated cardinality. Please run ANALYZE on the table before using this tool to get accurate results. The tool returns the column_name and the estimated_cardinality. If the column_name is not provided, the tool returns all columns along with their estimated cardinality.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| schema_name | string | Optional: The schema name in which the table is present. | No |  |
+| table_name | string | Required: The table name in which the column is present. | Yes |  |
+| column_name | string | Optional: The column name for which the cardinality is to be found. If not provided, cardinality for all columns will be returned. | No |  |
+
+
+---
+
+### get_query_plan
+
+Generate a PostgreSQL EXPLAIN plan in JSON format for a single SQL statement—without executing it. This returns the optimizer's estimated plan, costs, and rows (no ANALYZE, no extra options). Use in production safely for plan inspection, regression checks, and query tuning workflows.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| query | string | The SQL statement for which you want to generate plan (omit the EXPLAIN keyword). | Yes |  |
+
+
+---
+
+### list_active_queries
+
+List the top N (default 50) currently running queries (state='active') from pg_stat_activity, ordered by longest-running first. Returns pid, user, database, application_name, client_addr, state, wait_event_type/wait_event, backend/xact/query start times, computed query_duration, and the SQL text.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| min_duration | string | Optional: Only show queries running at least this long (e.g., '1 minute', '1 second', '2 seconds'). | No | `1 minute` |
+| exclude_application_names | string | Optional: A comma-separated list of application names to exclude from the query results. This is useful for filtering out queries from specific applications (e.g., 'psql', 'pgAdmin', 'DBeaver'). The match is case-sensitive. Whitespace around commas and names is automatically handled. If this parameter is omitted, no applications are excluded. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. | No | `50` |
+
+
+---
+
+### list_autovacuum_configurations
+
+List PostgreSQL autovacuum-related configurations (name and current setting) from pg_settings.
+
+
+
+---
+
+### list_available_extensions
+
+Discover all PostgreSQL extensions available for installation on this server, returning name, default_version, and description.
+
+
+
+---
+
+### list_database_stats
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| database_name | string | Optional: A specific database name pattern to search for. | No | `` |
+| include_templates | boolean | Optional: Whether to include template databases in the results. | No | `false` |
+| database_owner | string | Optional: A specific database owner name pattern to search for. | No | `` |
+| default_tablespace | string | Optional: A specific default tablespace name pattern to search for. | No | `` |
+| order_by | string | Optional: The field to order the results by. Valid values are 'size' and 'commit'. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. | No | `10` |
+
+
+---
+
+### list_indexes
+
+Lists available user indexes in the database, excluding system schemas (pg_catalog, information_schema). For each index, the following properties are returned: schema name, table name, index name, index type (access method), a boolean indicating if it's a unique index, a boolean indicating if it's for a primary key, the index definition, index size in bytes, the number of index scans, the number of index tuples read, the number of table tuples fetched via index scans, and a boolean indicating if the index has been used at least once.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| schema_name | string | Optional: a text to filter results by schema name. The input is used within a LIKE clause. | No | `` |
+| table_name | string | Optional: a text to filter results by table name. The input is used within a LIKE clause. | No | `` |
+| index_name | string | Optional: a text to filter results by index name. The input is used within a LIKE clause. | No | `` |
+| only_unused | boolean | Optional: If true, only returns indexes that have never been used. | No | `false` |
+| limit | integer | Optional: The maximum number of rows to return. Default is 50 | No | `50` |
+
+
+---
+
+### list_installed_extensions
+
+List all installed PostgreSQL extensions with their name, version, schema, owner, and description.
+
+
+
+---
+
+### list_invalid_indexes
+
+Lists all invalid PostgreSQL indexes which are taking up disk space but are unusable by the query planner. Typically created by failed CREATE INDEX CONCURRENTLY operations.
+
+
+
+---
+
+### list_locks
+
+Identifies all locks held by active processes showing the process ID, user, query text, and an aggregated list of all transactions and specific locks (relation, mode, grant status) associated with each process.
+
+
+
+---
+
+### list_memory_configurations
+
+List PostgreSQL memory-related configurations (name and current setting) from pg_settings.
+
+
+
+---
+
+### list_pg_settings
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| setting_name | string | Optional: A specific configuration parameter name pattern to search for. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. | No | `50` |
+
+
+---
+
+### list_publication_tables
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| table_names | string | Optional: Filters by a comma-separated list of table names. | No | `` |
+| publication_names | string | Optional: Filters by a comma-separated list of publication names. | No | `` |
+| schema_names | string | Optional: Filters by a comma-separated list of schema names. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. | No | `50` |
+
+
+---
+
+### list_query_stats
+
+Lists performance statistics for executed queries ordered by total time, filtering by database name pattern if provided. This tool requires the pg_stat_statements extension to be installed. The tool returns the database name, query text, execution count, timing metrics (total, min, max, mean), rows affected, and buffer cache I/O statistics (hits and reads).
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| database_name | string | Optional: The database name to list query stats for. | No | `` |
+| limit | integer | Optional: The maximum number of results to return. Defaults to 50. | No | `50` |
+
+
+---
+
+### list_replication_slots
+
+List key details for all PostgreSQL replication slots (e.g., type, database, active status) and calculates the size of the outstanding WAL that is being prevented from removal by the slot.
+
+
+
+---
+
+### list_roles
+
+Lists all the user-created roles in the instance . It returns the role name, Object ID, the maximum number of concurrent connections the role can make, along with boolean indicators for: superuser status, privilege inheritance from member roles, ability to create roles, ability to create databases, ability to log in, replication privilege, and the ability to bypass row-level security, the password expiration timestamp, a list of direct members belonging to this role, and a list of other roles/groups that this role is a member of.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| role_name | string | Optional: a text to filter results by role name. The input is used within a LIKE clause. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. Default is 10 | No | `50` |
+
+
+---
+
+### list_schemas
+
+Lists all schemas in the database ordered by schema name and excluding system and temporary schemas. It returns the schema name, schema owner, grants, number of functions, number of tables and number of views within each schema.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| schema_name | string | Optional: A specific schema name pattern to search for. | No | `` |
+| owner | string | Optional: A specific schema owner name pattern to search for. | No | `` |
+| limit | integer | Optional: The maximum number of schemas to return. | No | `10` |
+
+
+---
+
+### list_sequences
+
+Lists sequences in the database. Returns sequence name, schema name, sequence owner, data type of the sequence, starting value, minimum value, maximum value of the sequence, the value by which the sequence is incremented, and the last value generated by the sequence in the current session
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| schema_name | string | Optional: A specific schema name pattern to search for. | No | `` |
+| sequence_name | string | Optional: A specific sequence name pattern to search for. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. Default is 50 | No | `50` |
+
+
+---
+
+### list_stored_procedure
+
+Retrieves stored procedure metadata returning schema name, procedure name, procedure owner, language, definition, and description, filtered by optional role name (procedure owner), schema name, and limit (default 20).
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| role_name | string | Optional: The owner name to filter the stored procedures by. Defaults to NULL. | No |  |
+| schema_name | string | Optional: The schema name to filter the stored procedures by. Defaults to NULL. | No |  |
+| limit | integer | Optional: The maximum number of stored procedures to return. Defaults to 20. | No | `20` |
+
+
+---
+
+### list_table_stats
+
+Lists the user table statistics in the database ordered by number of
+        sequential scans with a default limit of 50 rows. Returns the following
+        columns: schema name, table name, table size in bytes, number of
+        sequential scans, number of index scans, idx_scan_ratio_percent (showing
+        the percentage of total scans that utilized an index, where a low ratio
+        indicates missing or ineffective indexes), number of live rows, number
+        of dead rows, dead_row_ratio_percent (indicating potential table bloat),
+        total number of rows inserted, updated, and deleted, the timestamps
+        for the last_vacuum, last_autovacuum, and last_autoanalyze operations.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| schema_name | string | Optional: A specific schema name to filter by | No |  |
+| table_name | string | Optional: A specific table name to filter by | No |  |
+| owner | string | Optional: A specific owner to filter by | No |  |
+| sort_by | string | Optional: The column to sort by | No |  |
+| limit | integer | Optional: The maximum number of results to return | No | `50` |
+
+
+---
+
+### list_tables
+
+Lists detailed schema information (object type, columns, constraints, indexes, triggers, owner, comment) as JSON for user-created tables (ordinary or partitioned). Filters by a comma-separated list of names. If names are omitted, lists all tables in user schemas.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| table_names | string | Optional: A comma-separated list of table names. If empty, details for all tables will be listed. | No | `` |
+| output_format | string | Optional: Use 'simple' for names only or 'detailed' for full info. | No | `detailed` |
+
+
+---
+
+### list_tablespaces
+
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| tablespace_name | string | Optional: a text to filter results by tablespace name. The input is used within a LIKE clause. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. | No | `50` |
+
+
+---
+
+### list_top_bloated_tables
+
+List the top tables by dead-tuple (approximate bloat signal), returning schema, table, live/dead tuples, percentage, and last vacuum/analyze times.
+
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| limit | integer | The maximum number of results to return. | No | `50` |
+
+
+---
+
+### list_triggers
+
+Lists all non-internal triggers in a database. Returns trigger name, schema name, table name, whether its enabled or disabled, timing (e.g BEFORE/AFTER of the event), the  events that cause the trigger to fire such as INSERT, UPDATE, or DELETE, whether the trigger activates per ROW or per STATEMENT, the handler function executed by the trigger and full definition.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| trigger_name | string | Optional: A specific trigger name pattern to search for. | No | `` |
+| schema_name | string | Optional: A specific schema name pattern to search for. | No | `` |
+| table_name | string | Optional: A specific table name pattern to search for. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. | No | `50` |
+
+
+---
+
+### list_views
+
+Lists views in the database from pg_views with a default limit of 50 rows. Returns schemaname, viewname, ownername and the definition.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| view_name | string | Optional: A specific view name to search for. | No | `` |
+| schema_name | string | Optional: A specific schema name to search for. | No | `` |
+| limit | integer | Optional: The maximum number of rows to return. | No | `50` |
+
+
+---
+
+### long_running_transactions
+
+Identifies and lists database transactions that exceed a specified time limit. For each of the long running transactions, the output contains the process id, database name, user name, application name, client address, state, connection age, transaction age, query age, last activity age, wait event type, wait event, and query string.
+
+#### Parameters
+
+| Name | Type | Description | Required | Default |
+| :--- | :--- | :--- | :--- | :--- |
+| min_duration | string | Optional: Only show transactions running at least this long (e.g., '1 minute', '15 minutes', '30 seconds'). | No | `5 minutes` |
+| limit | integer | Optional: The maximum number of long-running transactions to return. Defaults to 20. | No | `20` |
+
+
+---
+
+### replication_stats
+
+Lists each replica's process ID, user name, application name, backend_xmin (standby's xmin horizon reported by hot_standby_feedback), client IP address, connection state, and sync_state, along with lag sizes in bytes for sent_lag (primary to sent), write_lag (sent to written), flush_lag (written to flushed), replay_lag (flushed to replayed), and the overall total_lag (primary to replayed).
+
+
+
+---
+
diff --git a/skills/cloudsql-postgres/scripts/database_overview.js b/skills/cloudsql-postgres/scripts/database_overview.js
new file mode 100755
index 0000000..c7e43ea
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/database_overview.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "database_overview";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/execute_sql.js b/skills/cloudsql-postgres/scripts/execute_sql.js
new file mode 100755
index 0000000..a30ae4e
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/execute_sql.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "execute_sql";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/get_column_cardinality.js b/skills/cloudsql-postgres/scripts/get_column_cardinality.js
new file mode 100755
index 0000000..12e429e
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/get_column_cardinality.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "get_column_cardinality";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/get_query_plan.js b/skills/cloudsql-postgres/scripts/get_query_plan.js
new file mode 100755
index 0000000..583f943
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/get_query_plan.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "get_query_plan";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_active_queries.js b/skills/cloudsql-postgres/scripts/list_active_queries.js
new file mode 100755
index 0000000..70f03c4
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_active_queries.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_active_queries";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_autovacuum_configurations.js b/skills/cloudsql-postgres/scripts/list_autovacuum_configurations.js
new file mode 100755
index 0000000..c3a3353
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_autovacuum_configurations.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_autovacuum_configurations";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_available_extensions.js b/skills/cloudsql-postgres/scripts/list_available_extensions.js
new file mode 100755
index 0000000..23039d2
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_available_extensions.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_available_extensions";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_database_stats.js b/skills/cloudsql-postgres/scripts/list_database_stats.js
new file mode 100755
index 0000000..e01362d
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_database_stats.js
@@ -0,0 +1,81 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_database_stats";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_indexes.js b/skills/cloudsql-postgres/scripts/list_indexes.js
new file mode 100755
index 0000000..44579bb
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_indexes.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_indexes";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_installed_extensions.js b/skills/cloudsql-postgres/scripts/list_installed_extensions.js
new file mode 100755
index 0000000..e6a9eea
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_installed_extensions.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_installed_extensions";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_invalid_indexes.js b/skills/cloudsql-postgres/scripts/list_invalid_indexes.js
new file mode 100755
index 0000000..274e514
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_invalid_indexes.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_invalid_indexes";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_locks.js b/skills/cloudsql-postgres/scripts/list_locks.js
new file mode 100755
index 0000000..b2056e6
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_locks.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_locks";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_memory_configurations.js b/skills/cloudsql-postgres/scripts/list_memory_configurations.js
new file mode 100755
index 0000000..31fef99
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_memory_configurations.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_memory_configurations";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_pg_settings.js b/skills/cloudsql-postgres/scripts/list_pg_settings.js
new file mode 100755
index 0000000..6d1d73d
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_pg_settings.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_pg_settings";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_publication_tables.js b/skills/cloudsql-postgres/scripts/list_publication_tables.js
new file mode 100755
index 0000000..398d792
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_publication_tables.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_publication_tables";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_query_stats.js b/skills/cloudsql-postgres/scripts/list_query_stats.js
new file mode 100755
index 0000000..61f2277
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_query_stats.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_query_stats";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_replication_slots.js b/skills/cloudsql-postgres/scripts/list_replication_slots.js
new file mode 100755
index 0000000..946a6bd
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_replication_slots.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_replication_slots";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_roles.js b/skills/cloudsql-postgres/scripts/list_roles.js
new file mode 100755
index 0000000..35e1107
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_roles.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_roles";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_schemas.js b/skills/cloudsql-postgres/scripts/list_schemas.js
new file mode 100755
index 0000000..1851d85
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_schemas.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_schemas";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_sequences.js b/skills/cloudsql-postgres/scripts/list_sequences.js
new file mode 100755
index 0000000..39cc4ba
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_sequences.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_sequences";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_stored_procedure.js b/skills/cloudsql-postgres/scripts/list_stored_procedure.js
new file mode 100755
index 0000000..2399cb5
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_stored_procedure.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_stored_procedure";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_table_stats.js b/skills/cloudsql-postgres/scripts/list_table_stats.js
new file mode 100755
index 0000000..ef37260
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_table_stats.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_table_stats";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_tables.js b/skills/cloudsql-postgres/scripts/list_tables.js
new file mode 100755
index 0000000..4778f19
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_tables.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_tables";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_tablespaces.js b/skills/cloudsql-postgres/scripts/list_tablespaces.js
new file mode 100755
index 0000000..1fa3780
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_tablespaces.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_tablespaces";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_top_bloated_tables.js b/skills/cloudsql-postgres/scripts/list_top_bloated_tables.js
new file mode 100755
index 0000000..739dc2a
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_top_bloated_tables.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_top_bloated_tables";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_triggers.js b/skills/cloudsql-postgres/scripts/list_triggers.js
new file mode 100755
index 0000000..cf83929
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_triggers.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_triggers";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/list_views.js b/skills/cloudsql-postgres/scripts/list_views.js
new file mode 100755
index 0000000..1483738
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/list_views.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "list_views";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/long_running_transactions.js b/skills/cloudsql-postgres/scripts/long_running_transactions.js
new file mode 100755
index 0000000..b16afb1
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/long_running_transactions.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "long_running_transactions";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
diff --git a/skills/cloudsql-postgres/scripts/replication_stats.js b/skills/cloudsql-postgres/scripts/replication_stats.js
new file mode 100755
index 0000000..4bc4d7e
--- /dev/null
+++ b/skills/cloudsql-postgres/scripts/replication_stats.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+
+const { spawn, execSync } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+const toolName = "replication_stats";
+const configArgs = ["--prebuilt", "cloud-sql-postgres"];
+
+function getToolboxPath() {
+    if (process.env.GEMINI_CLI === '1') {
+        const localPath = path.resolve(__dirname, '../../../toolbox');
+        if (fs.existsSync(localPath)) {
+            return localPath;
+        }
+    }
+    try {
+        const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
+        const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
+        if (globalPath) {
+            return globalPath.split('\n')[0].trim();
+        }
+        throw new Error("Toolbox binary not found");
+    } catch (e) {
+        throw new Error("Toolbox binary not found");
+    }
+}
+
+let toolboxBinary;
+try {
+    toolboxBinary = getToolboxPath();
+} catch (err) {
+    console.error("Error:", err.message);
+    process.exit(1);
+}
+
+function getEnv() {
+    const envPath = path.resolve(__dirname, '../../../.env');
+    const env = { ...process.env };
+    if (fs.existsSync(envPath)) {
+        const envContent = fs.readFileSync(envPath, 'utf-8');
+        envContent.split('\n').forEach(line => {
+            const trimmed = line.trim();
+            if (trimmed && !trimmed.startsWith('#')) {
+                const splitIdx = trimmed.indexOf('=');
+                if (splitIdx !== -1) {
+                    const key = trimmed.slice(0, splitIdx).trim();
+                    let value = trimmed.slice(splitIdx + 1).trim();
+                    value = value.replace(/(^['"]|['"]$)/g, '');
+                    if (env[key] === undefined) {
+                        env[key] = value;
+                    }
+                }
+            }
+        });
+    }
+    return env;
+}
+
+let env = process.env;
+if (process.env.GEMINI_CLI === '1') {
+    env = getEnv();
+}
+
+const args = process.argv.slice(2);
+const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
+
+const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
+
+child.on('close', (code) => {
+  process.exit(code);
+});
+
+child.on('error', (err) => {
+  console.error("Error executing toolbox:", err);
+  process.exit(1);
+});
