Configuring complex time-driven triggers in Google Apps Script—such as executing tasks exclusively on weekday mornings—is notoriously intractable programmatically and strictly impossible via the standard UI. TriggerApp mitigates this architectural friction through a declarative JSON engine, allowing developers to completely bypass granular date-math logic. Now, by embedding a native Model Context Protocol (MCP) server, we cross into a definitive paradigm shift. Developers can orchestrate complex, continuously looping GAS schedules using natural language via Generative AI (Vibe Coding), preserve the hard 20-trigger quota limit through an elegant recursive daisy-chain architecture, and bypass the strict 6-minute execution timeout by dynamically queuing future execution batches.
In Google Apps Script (GAS), Time-driven triggers are the absolute backbone of scheduled cloud automation within the Google Workspace ecosystem, allowing scripts to execute autonomously at defined intervals.
However, the native infrastructure is deeply flawed for advanced use cases. Attempting to schedule a trigger manually via the UI restricts you to elementary intervals (e.g., "every hour" or "every Tuesday"). If your operational logic demands a complex schedule—such as "every 30 minutes, strictly between 10:00 and 18:00, and exclusively on weekdays"—configuring this natively becomes a hostile experience. It forces the developer to hardcode brittle date-math and conditional abort statements directly into the business logic simply to suppress executions during off-hours or holidays.
This structural deficiency was the core catalyst for the development of TriggerApp. By introducing a deterministic, declarative JSON engine, TriggerApp abstracted the volatile date-math layer entirely away from the developer.
Today, I am advancing this automation into the autonomous era. TriggerApp now operates with an embedded, native Model Context Protocol (MCP) server. This establishes a fundamental shift toward "Intent-Driven Infrastructure." You no longer need to write JSON configurations manually. Through "Vibe Coding," you issue natural language directives to a Generative AI agent. The AI evaluates the constraints, interfaces directly with the GAS runtime via the MCP protocol, and autonomously installs, manages, and simulates your trigger infrastructure.
Below is a technical dissection of the MCP server architecture, how TriggerApp circumvents native GAS limits, and how you can leverage Agentic AI to manage your cloud environments.
To unlock these advanced orchestration capabilities, the TriggerApp library must be linked to your project environment.
+
icon to add a new library.1LihDPPHWBCcadYVBI3oZ4vOt7XqlowoHyBLdaDgRIx_5OpRBREA7Z1QB
TriggerApp
, and execute To permit an autonomous AI agent to manipulate your triggers, you must expose TriggerApp as a secure MCP Server. This requires deploying a GAS Web App acting as an HTTP endpoint to route JSON-RPC payloads directly into the TriggerApp core.
Inject the following foundational code into your Code.gs
file. This intercepts incoming requests, enforces cryptographic boundaries via an access key, and establishes the daemon orchestrator (mcpTriggerHandler
) responsible for sustaining the recursive trigger cycles.
/**
* Web App Entry Point: Routes incoming MCP JSON-RPC payloads.
* Enforces authentication and context isolation.
*
* @param {GoogleAppsScript.Events.DoPost} e - The incoming POST event payload.
* @returns {GoogleAppsScript.Content.TextOutput} The executed MCP JSON-RPC response.
*/
const doPost = (e) => {
return TriggerApp.mcp({
e: e,
accessKey: "YOUR_SUPER_SECRET_KEY", // CRITICAL: Must be a high-entropy string to prevent unauthorized remote execution.
// log: true, // Automatically streams JSON-RPC payloads to a designated sheet for audit trails.
// spreadsheetId: "YOUR_SPREADSHEET_ID", // Required if logging is enabled.
lock: LockService.getScriptLock(), // Prevents race conditions during concurrent AI tool invocations.
properties: PropertiesService.getScriptProperties(), // Isolates configuration state natively within the project boundary.
});
};
/**
* MANDATORY: The Global Recursive Orchestrator.
* Acts as the daemon process. DO NOT manually delete this function or its triggers.
*
* @param {GoogleAppsScript.Events.TimeDriven} e - The time-driven trigger execution object.
*/
function mcpTriggerHandler(e) {
TriggerApp.executeMcpTriggers(e, PropertiesService.getScriptProperties());
}
// ============================================================================
// USER FUNCTIONS
// ============================================================================
function myTask1() {
console.log("myTask1: Executed perfectly on schedule!");
}
function myTask2() {
console.log("myTask2: Executed perfectly on schedule!");
}
Configure your local MCP client (e.g., Antigravity CLI, Claude Desktop) to target this deployment endpoint. Your authorized accessKey
must be appended as a query parameter.
Example mcp_config.json for Antigravity CLI:
{
"mcpServers": {
"set-trigge-test-project1": {
"serverUrl": "https://script.google.com/macros/s/{YOUR_DEPLOYMENT_ID}/exec?accessKey=YOUR_SUPER_SECRET_KEY"
}
}
}
Architectural Constraint: The 1:1 Project Mapping
The naming convention set-trigge-test-project1
highlights a strict structural limitation inherent to Google Apps Script. A Web App deployment evaluates code exclusively within the isolated boundary of its host project. Consequently, an MCP server deployed in this manner maintains a rigid 1:1 mapping to that specific GAS project. To orchestrate architecture across multiple distinct projects, you must deploy a separate Web App—and register a distinct MCP server entry—for each.
In standard GAS paradigms, fulfilling a requirement like "run every 30 minutes, strictly between 10:00 and 18:00 on weekdays" forces an architectural anti-pattern. Developers inject infrastructure constraints into business logic, yielding bloated functions that execute purely to evaluate: "It is Saturday, abort execution," or "It is 18:30, abort execution."
TriggerApp aggressively separates these domains utilizing a declarative JSON schema.
const config = [
{
functionName: "myTask1",
everyWeek: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
interval: 1800, // 30 minutes in seconds
fromTime: "10:00",
toTime: "18:00",
},
];
You declare when the execution occurs. The business function (processDataBatch
) remains hermetically sealed and focused on the workload. TriggerApp’s embedded computational engine processes the complexity of leap years, month boundaries, and timezone offsets natively. If the current time is 17:50 on Friday, the engine mathematically deduces the absolute next valid execution timestamp (10:00 on the subsequent Monday) without firing unnecessary script invocations.
Google Apps Script enforces an aggressive hard limit: a maximum of 20 active triggers per project. Attempting to schedule a high-frequency recurring task by mapping hundreds of future triggers will crash the project against this ceiling instantly.
TriggerApp entirely bypasses this constraint through a Recursive Daisy-Chain Algorithm (Just-In-Time scheduling). Even if a task is projected to execute millions of times over a decade, TriggerApp consumes a maximum of two physical trigger slots at any given moment.
Upon receiving the natural language directive, the AI executes the MCP installation request. TriggerApp computes the initial execution timestamp and installs a physical trigger. Simultaneously, it schedules a secondary, paired trigger for the mcpTriggerHandler
daemon, offset by one minute. The complex JSON ruleset is serialized securely into PropertiesService
.
The system achieves theoretical infinity once the execution cycle begins.
The mcpTriggerHandler
dynamically garbage-collects spent triggers—immediately freeing quota capacity—and recalculates the next chronological baton pass. The execution loop becomes self-sustaining.
TriggerApp elevates GAS from a lightweight scripting environment to the operational equivalence of enterprise event schedulers like AWS EventBridge.
When authorizing AI to manage production infrastructure, the immediate risk is AI hallucination: What if the model hallucinates and schedules a destructive script to execute at midnight on Sunday?
TriggerApp neuters this risk via the simulate_triggers
endpoint. Before any physical changes are committed, the AI mathematically simulates the schedule and outputs an exact array of ISO 8601 timestamps. The operator audits the dry-run output, and only upon human verification does the AI invoke the final install_triggers
command. This establishes a non-negotiable DevOps safety layer.
GAS imposes a fatal 6-minute execution timeout. Heavy workloads (e.g., iterating through massive datasets or bulk email dispatch) will forcefully terminate.
By leveraging TriggerApp’s installTriggersByData
method, GAS transforms into a dynamic queue-consumption batch pipeline. As script execution approaches the 5-minute threshold, the process can programmatically calculate the remaining payload and command TriggerApp to inject an ephemeral trigger exactly two minutes into the future. The script dynamically spawns future instances of itself, systematically chewing through massive datasets while ignoring the 6-minute ceiling entirely.
The fusion of TriggerApp's recursive engine with an MCP Server realizes true "Infrastructure as Conversation." You provide the AI agent with direct execution authority (the GAS runtime) and stateful persistence (the recursive loops).
The following are unedited, real-world executions performed by the Antigravity CLI.
Operator Directive: "Use the MCP server set-trigge-test-project1. I need to run the function myTask1 every Monday, Wednesday, and Friday at 09:00 and 15:00. Please simulate this first... If the simulated timing looks correct, proceed to install."
The AI leverages the simulate_triggers
tool, validates the complex conversions flawlessly, exposes the dry-run data to the user, and upon implied human consensus, autonomously triggers install_triggers
to finalize the deployment.
Operator Directive: "Use the MCP server set-trigge-test-project1. Install a continuous trigger for myTask2 that runs every 30 minutes from 10:00 to 18:00 on weekdays only."
The model evaluates the constraint density, translates the requirements perfectly into the underlying TriggerApp JSON schema, and executes the deployment. Highly conditional scheduling is deployed without manually authoring a single line of code.
Operator Directive: "Please delete the triggers associated with the function myTask1... I want to start fresh. Purge and delete all active triggers completely."
The AI surgically isolates the requested handler names and executes delete_triggers
, completely obliterating the configurations from both the GAS runtime and PropertiesService
. It then verifies the nuclear option via delete_all_triggers
.
GASADK operates as the definitive Agent Development Kit explicitly engineered for the Google Apps Script ecosystem.
Security & Zero-Trust Verification: GASADK invokes GAS Web Apps using standard OAuth/access tokens. This allows you to lock the Web App deployment settings to "Execute the app as": Me
and "Who has access to the app": Only myself
. The MCP server is thus strictly isolated behind Google’s identity perimeter, guaranteeing enterprise-grade security.
The execution harness using GASADK is implemented as follows. (Requires GASADK installation and injecting your Gemini API key into PropertiesService
as GEMINI_API_KEY
).
/**
* Centralized execution harness for GASADK autonomous operations.
* Integrates Gemini API to act as the primary infrastructure orchestrator.
*
* @param {string} prompt - The natural language instruction for the AI agent.
*/
function runGASADK_(prompt) {
const { LlmAgent } = GASADK;
const properties = PropertiesService.getScriptProperties();
const API_KEY = properties.getProperty("GEMINI_API_KEY");
if (!API_KEY)
throw new Error("CRITICAL: Missing GEMINI_API_KEY in script properties.");
// Define MCP endpoints targeting the restricted deployment architecture.
const mcpServers = [
{
"set-trigge-test-project1": {
httpUrl:
"https://script.google.com/macros/s/{YOUR_DEPLOYMENT_ID}/exec?accessKey=sample",
},
},
];
const agent = new LlmAgent({
apiKey: API_KEY,
name: "MasterOrchestrator",
description:
"You are the master orchestrator for Google Apps Script autonomous infrastructure.",
mcpServers: mcpServers,
});
// Inject native GAS services for execution safety and persistent state management
agent.setServices({
lock: LockService.getScriptLock(),
properties: properties,
});
const result = agent.run(prompt, (logEntry) => {
console.log(`[Log ${logEntry.timestamp}] ${logEntry.message}`);
if (logEntry.data?.plan) {
console.log("=== Autonomous Execution Plan (DAG) ===");
console.log(JSON.stringify(logEntry.data.plan, null, 2));
}
});
console.log("--- Final Synthesized Result ---");
console.log(result);
}
// ============================================================================
// AUTONOMOUS INVOCATION SAMPLES
// ============================================================================
function sample1() {
const prompt =
"Use the MCP server set-trigge-test-project1. I need to run the function `myTask1` every Monday, Wednesday, and Friday at 09:00 and 15:00. Please simulate this first... If the simulated timing looks correct, proceed to install.";
runGASADK_(prompt);
}
function sample2() {
const prompt =
"Use the MCP server set-trigge-test-project1. Install a continuous trigger for `myTask2` that runs every 30 minutes from 10:00 to 18:00 on weekdays only.";
runGASADK_(prompt);
}
function sample3() {
const prompt =
"Please delete the triggers associated with the function `myTask1`.";
runGASADK_(prompt);
}
function sample4() {
const prompt =
"I want to start fresh. Purge and delete all active triggers completely.";
runGASADK_(prompt);
}
You instruct the AI (GASADK): "Use the MCP server set-trigge-test-project1. I need to run the function myTask1 every Monday, Wednesday, and Friday at 09:00 and 15:00. Please simulate this first... If the simulated timing looks correct, proceed to install."
Agent Operational Return:
I have completed the simulation and installation of the triggers for your function `myTask1` on the `set-trigge-test-project1` server.
### 1. Simulation Results
The simulation correctly calculated the schedule for **Monday, Wednesday, and Friday at 09:00 and 15:00**. Based on the current date (Wednesday, June 3, 2026), the schedule is as follows:
* **Today (June 3):** 15:00
* **Friday, June 5:** 09:00, 15:00
* **Monday, June 8:** 09:00, 15:00
* *(Continuing through June 26, 2026)*
### 2. Installation and Verification
Since the simulation aligned with your requirements, I proceeded with the installation.
* **Triggers Installed:** A total of **2 triggers** have been successfully registered.
* **Verification:** The `get_triggers_list` tool confirms that these triggers are now active in the project under the unique ID: `422627799140925440`.
Your task is now fully configured and running according to the specified schedule.
***
### Execution Summary
**Capabilities Used:** `mcp_0` (MCP Server: set-trigge-test-project1)
**Execution Order & Details:**
1. **Task 1 (Simulation):**
* **Prompt:** "Please simulate the schedule for the function 'myTask1' using the 'simulate_triggers' tool on the 'set-trigge-test-project1' server. The function needs to run every Monday, Wednesday, and Friday at 09:00 and 15:00. Show me the calculated timing results."
* **Duration:** 25,152 ms
2. **Task 2 (Installation):**
* **Prompt:** "Now that the simulation is complete, please use the 'install_triggers_by_data' tool to officially install the triggers for 'myTask1' using the data generated in the previous task."
* **Duration:** 51,894 ms
3. **Task 3 (Verification):**
* **Prompt:** "Please run the 'get_triggers_list' tool to confirm that the triggers for 'myTask1' (Monday, Wednesday, Friday at 09:00 and 15:00) are active and correctly registered in the project."
* **Duration:** 19,810 ms
Architectural Analysis: Observe the multi-step reasoning protocol. The AI does not blindly mutate the production environment. It initially invokes simulate_triggers
as a deterministic dry-run, projecting the mathematical execution timeline into strict ISO 8601 timestamps. It then autonomously audits this projection against the operator's natural language intent. Only after mathematically validating that the intervals are correct does it invoke the state-mutating install_triggers_by_data
tool. It concludes by polling the live environment to verify the trigger IDs. The agent acts entirely as its own QA engineer, securing the deployment lifecycle.
You instruct the AI (GASADK): "Use the MCP server set-trigge-test-project1. Install a continuous trigger for myTask2 that runs every 30 minutes from 10:00 to 18:00 on weekdays only."
Agent Operational Return:
The trigger for function **`myTask2`** in the **` set-trigge-test-project1`** project has been successfully installed and verified.
The configuration details are as follows:
* **Trigger ID:** 7691379546938933248
* **Interval:** Every 30 minutes (1800 seconds)
* **Active Window:** 10:00 to 18:00
* **Schedule:** Weekdays only (Monday to Friday)
Verification via the system's trigger list confirms that the task is active and correctly matches the requested parameters.
### Execution Summary
| Order | Capability Used | Prompt | Duration (ms) | Result |
| :--- | :--- | :--- | :--- | :--- |
| 1 | `mcp_0` (MCP Server) | I need to set up a trigger for the function 'myTask2' in the 'set-trigge-test-project1' project. Please use the `install_triggers` tool to schedule it to run every 30 minutes between 10:00 and 18:00 on weekdays only. | 35,500 | Trigger installed successfully (ID: 7691379546938933248). |
| 2 | `mcp_0` (MCP Server) | Please use the `get_triggers_list` tool to verify that the 'myTask2' trigger was successfully installed and matches the requested weekday schedule. | 24,260 | Trigger verified as active and correctly configured. |
Architectural Analysis: This sequence demonstrates flawless semantic translation from complex human intent directly into a rigid declarative schema. The model ingests overlapping constraints (a 30-minute interval, a strict active operational window, and a boolean weekday restriction), synthesizes the corresponding JSON payload, and commits the deployment. Furthermore, it immediately initiates a post-deployment audit via get_triggers_list
, validating that the remote state structurally mirrors the intended infrastructure constraints without requiring human oversight.
You instruct the AI (GASADK): "Please delete the triggers associated with the function myTask1
."
Agent Operational Return:
The trigger associated with the function `myTask1` (ID: 422627799140925440) has been successfully deleted from the `set-trigge-test-project1` server.
I have verified the current status of your triggers to ensure the deletion was processed correctly. The function `myTask1` is no longer present. The remaining active triggers are:
* **myTask2** (ID: 7691379546938933248)
* **mcpTriggerHandler** (ID: 6335373846635347968)
### Execution Summary
| Order | Capability Used | Prompt | Duration (ms) | Status |
| :--- | :--- | :--- | :--- | :--- |
| 1 | `mcp_0` | Please delete the triggers associated with the function name 'myTask1' using the delete_triggers tool in the set-trigge-test-project1 server. | 23,406 | Success |
| 2 | `mcp_0` | Please use the get_triggers_list tool to verify the current status of triggers after the deletion process in the set-trigge-test-project1 server. | 20,831 | Success |
Architectural Analysis (Selective Deletion): The agent executes a surgical teardown of infrastructure. It successfully queries the live environment, maps the target function myTask1
to its specific unique ID, and terminates it exclusively. Crucially, it leaves the parallel myTask2
process and the vital mcpTriggerHandler
daemon untouched, proving its capability to manage modular micro-services within a shared runtime environment without causing collateral damage.
You instruct the AI (GASADK): "I want to start fresh. Purge and delete all active triggers completely."
Agent Operational Return:
I have successfully purged and deleted all active triggers associated with your project. To ensure a completely fresh start, I also verified the project's state, confirming that no time-driven triggers remain active.
**Execution Summary**
* **Task 1**
* **Capability Used:** mcp_0 (MCP Server)
* **Execution Order:** 1
* **Duration:** 30118 ms
* **Prompt:** Please purge and delete all active time-driven triggers bound to the current project using the delete_all_triggers tool.
* **Task 2**
* **Capability Used:** mcp_0 (MCP Server)
* **Execution Order:** 2
* **Duration:** 22081 ms
* **Prompt:** Please use the get_triggers_list tool to verify the updated state of the project and confirm that all triggers have been deleted.
Architectural Analysis (Complete Purge): When commanded to initiate a nuclear reset, the agent safely disintegrates the entire scheduled architecture. It invokes delete_all_triggers
to eliminate all physical hooks from the Google Cloud time engine and simultaneously purges the serialized persistence states from PropertiesService
. The subsequent verification confirms the environment has been successfully reverted to a pristine, zero-state baseline.
TriggerApp decisively shifts the paradigm of Google Apps Script automation. What originated as a mechanism to eradicate volatile date-math via a declarative JSON runtime has evolved into a fully autonomous, enterprise-grade cloud scheduling pipeline. By native integration with the Model Context Protocol (MCP), TriggerApp unleashes true "Intent-Driven Infrastructure"—empowering engineers to deploy, simulate, and orchestrate infinitely scaling execution loops using entirely natural language directives.
Architectural Takeaways:
mcpTriggerHandler
). By dynamically generating only the explicit next execution state and systematically garbage-collecting spent nodes, the system sustains theoretically infinite scale utilizing exactly two quota slots.simulate_triggers
safeguard. The AI agent must project exact ISO 8601 execution arrays for explicit human audit before physical server-side commits are permitted.installTriggersByData
. The execution thread can calculate remaining compute requirements immediately before termination and inject targeted, ephemeral future triggers to seamlessly resume the workload queue.