Today marks the finish line of an intense coding sprint. I am excited to share my project: AppSheet2Agent (available at github.com/mhawksey/appsheet2agent).
If you are an AppSheet creator, you have already built amazing, structured databases and workflows. But what if your users want to interact with that same data conversationally, without leaving their chat?
Usually, connecting business applications to large language models is a massive headache:
You lose security context, often forcing you to rely on a single, risky service account.
You get flat, uninspiring text dumps that make structured data hard to read.
You waste hours writing manual boilerplate code.
AppSheet2Agent is an experimental solution designed specifically for existing AppSheet app creators. It allows them to rapidly create brand-new, highly interactive custom agents to interact with their existing apps. This makes it possible to use your AppSheet app directly inside platforms like Gemini Enterprise.
Web Interface to Design Agents for AppSheet
Example card view in Gemini Enterprise
Example form view in Gemini Enterprise
Example form view in AppSheet
Here is what the MVP delivers:
🤖 Powered by Google Antigravity SDK Under the hood, it uses Google’s new Antigravity SDK to build the agent based on a conversation with the AppSheet creator. As part of this the user can provide the existing Application Definition and OpenAPI spec for their app, so Antigravity has the context if their app.
🎨 Rich Interactive Layouts (A2UI v0.8) Nobody wants walls of boring markdown text. The agent automatically renders search results and forms as beautiful, structured visual cards directly in the Gemini Enterprise chat window. It automatically reorders columns to put primary labels first, hides messy system rows, and maps data types to native elements like checklists and date pickers.
🔐 True User Identity Delegation (RunAsUserEmail) Security is paramount. The agent uses OAuth to request and access the users email address which is used directly in the AppSheet API. Every single query and update runs strictly under the identity of the person chatting with the model. No shared credentials. No security compromises.
Where the Project Stands (The Reality Check) Because this was a sprint, it is a work in progress! I have successfully compiled, registered, and deployed custom AppSheet agents to Gemini Enterprise. Right now, I am still ironing out the automated “Creator Studio” wizard workflow that compiles the packaging on the fly.
I would love to hear your thoughts! If you are an AppSheet creator, how would your users benefit from interacting with your apps inside Gemini Enterprise?
Google Cloud credits are provided for this project.
No-Code Business Automation – Made Simple. This channel is here to help you learn the basics of AppSheet so that you can make your business more efficient.
Many AppSheet creators are likely familiar with the AppSheet Training YouTube channel and its associated materials. Managed by QREW Technologies, a business specialising in AppSheet consulting from the early days of the platform, the channel offers hundreds of videos covering all aspects of building and managing applications.
A particularly useful addition is a “NOCODE NEWS” segment, where the QREW team highlights the latest platform updates and community contributions. Given that founder Stefan Quartemont and several team members, including Cam Lupton, hold Google Developer Expert status, this segment offers an authoritative view. This segment is also included in their wider regular live broadcasts, so hit like and subscribe to stay informed.
To get a flavour of what is included, I have picked out a few recent highlights:
Shift to Platform Stability [2 July 2026] – The QREW team highlights a recent community update where the AppSheet team openly acknowledged developer frustration and announced they are pausing new feature releases, including the highly anticipated Gantt chart view, and cancelling upcoming office hours. This hard choice is their way of finally tackling the bug backlog and system stability issues that creators have been pushing for.
User Limits Surfacing [2 July 2026] – The hosts discuss a wave of anxiety on the AppSheet community forum as Google actively enforces the 10-user limit on free-tier and prototype accounts, which includes guest users. They walk through how this sudden enforcement is temporarily blocking application access, leaving creators scrambling to either clean up user lists or upgrade to a paid licence.
Domain Authenticated Email Beta [18 June 2026] – The team shares details on a new “Bring Your Own Email” closed beta for Google Workspace customers. This is a massive relief for developers after AppSheet blocked external emails from the default [email protected] address to combat phishing, which broke many existing workflows. This new beta uses Google OAuth to let developers send automated emails directly from their own authenticated domains.
The QREW team does an excellent job of translating policy updates into practical developer steps, saving you the time of digging through the forums yourself. For all of these updates check out the video descriptions for additional links and resources.
Following my previous look at the Google Sheets canvas tool I wanted to explore how we can push past single-tab data limits by using the =AI() function to generate structured JSON. If you are new to JSON, it is just a clean, standardised way of packaging information using plain text and clear labels. This technique is universally applicable to any workflow where you need to extract, evaluate and format complex data in a single step.
One of the key design rules of the new Canvas tool is that it can only build interfaces using data from a single sheet tab. If you want to show a detailed breakdown of multiple metrics, a standard spreadsheet setup would force you to create dozens of separate columns to hold every rating, piece of feedback and recommendation. This quickly becomes messy and difficult to manage.
By instructing the =AI() function to bundle all our evaluation data into a single, structured JSON block, we can squeeze a complete relational database into a single cell. This keeps our spreadsheet clean while giving the Canvas tool all the deep metadata it needs to build a rich, interactive dashboard.
What we will be making
When helping customers adopt generative AI tools in their daily workflows, one of the biggest challenges for new users is prompting. To solve this, we are going to build a personalised prompt coaching directly inside Google Sheets. Our tool will automatically analyse any draft prompt, grade its structure, highlight which key elements are missing and provide instant, actionable advice on how to improve it.
The finished, interactive Prompt Coach Dashboard rendering directly over your spreadsheet cells, complete with colour coded status badges, highlighting and a copyable master prompt. Click here to view the readonly version
Persona: The specific role, voice or professional perspective assigned to the model (e.g., “You are an expert technical writer”).
Task: The core instruction or action verb directing the model (e.g., “Draft an onboarding guide”). This is the only non-negotiable component.
Context: Relevant documents, emails, file identifiers or situational details that ground the model in accurate facts (e.g. referencing ambient tags like “@UAT_Results”).
Format: The layout, style, length limits or output type requested for the final response (e.g., “Output as a bulleted list of 5 steps”).
By checking draft prompts against these pillars, our Sheets-based coach can pinpoint exactly what a user needs to add to get a great result on their first try. Let us look at how to set up this workflow to parse, score and visualise your prompting templates using dynamic JSON.
Step 1: Set Up the Prompt Auditor Formula
Open your Google Sheet and prepare your columns. Label Column A as “Raw Prompt” and Column B as “JSON Evaluation”.
Enter a draft prompt in cell A2, such as: “Draft an email to my colleague who is running this UAT and explain what they need to do next.”
To construct a prompt to return structured JSON data from the Google Sheet =AI() function I used Gemini to draft and refine our system instructions. Developing a complex, multi-layered instruction that outputs strict JSON without broken formatting is an iterative process. Here is the system prompt I came up with (select cell B2 and write the following formula to analyse the prompt against the four prompting pillars):
=AI("Analyse the draft prompt provided against the Google Prompting Guide 101 framework, which utilises 4 pillars: Persona, Task, Context and Format.
### THE SYNERGY-BASED COACHING BLUEPRINT:
Your goal is to evaluate if the user's prompt is structurally matched to their operational goal, rather than strictly checking off all the components of a prompt. Always recommend including a strong verb or command as part of the prompt task; this is the most important part of a prompt.
1. Task Classification:
- Identify if the task is primarily CREATIVE/WRITTEN (e.g., drafting emails, brainstorming, translating, slide content) or DATA/OPERATIONAL/ANALYTICAL (e.g., summarising documents, extracting metrics, creating task lists, setting limits).
2. Core vs. Enhancer Logic:
- 'Task' is the only non-negotiable core pillar.
- The other 3 pillars (Persona, Context, Format) are optional 'Enhancers'. Evaluate if the user chose the RIGHT enhancers for their specific goal:
- For CREATIVE/WRITTEN goals: Look primarily for 'Persona', 'Tone' or 'Context' enhancers. Creative prompts do not strictly need constraints or format grids.
- For DATA/OPERATIONAL goals: Look primarily for 'Format', 'Context' (referencing active file context) or 'Constraints'. Analytical prompts do not strictly need a persona or a tone.
3. Dynamic Tier Ratings:
Based on the synergy check above, assign one of these three ratings:
- Foundation: The prompt has a core command but lacks appropriate enhancers (leaving the AI guessing on essential details or voice).
- Effective: The prompt provides a clear task accompanied by relevant enhancers (e.g., standard persona or basic format), but lacks precise structural boundaries, styling constraints or negative limitations.
- Masterful: The prompt is highly optimised. It features a strong command, targeted context (or active ambient tags) and multiple precise constraints (such as explicit word counts, custom layout instructions, specific tone rules or negative exclusions). It is designed to get the perfect result on the first run with zero back-and-forth iteration.
### PILLAR MAPPING:
For each of the 4 pillars (task, persona, context, format), status must be exactly 'found', 'weak' or 'missing'.
- Ambient references like 'this document', 'the open email' or '@Roadmap' represent strong contextual grounding. Mark them 'found'.
- Format and Constraints: Note that 'Format' governs structural layout, timing rules, explicit constraints and negative exclusions (e.g., 'Do not suggest...'). You MUST map these structural guidelines and behavioral boundaries to the 'format' pillar text array.
- Highlight Substrings: When extracting text substrings for the 'text' array, you must copy them EXACTLY as they appear in the original draft prompt. Do not correct spelling, alter punctuation, adjust capitalisation or paraphrase, as this will break the frontend highlighting engine.
### RULE OF COMPLETENESS:
- 'improvedPrompt' MUST NEVER BE EMPTY. You must upgrade the original prompt so that it strictly qualifies for the Masterful rating. To do this, you MUST enrich the original request by injecting:
1. A highly tailored, expert persona suited to the task.
2. Explicit structural and formatting guidelines (such as a markdown table with designated column headings or a multi-part layout).
3. Precise constraints and absolute metrics (such as explicit time limits, word limits or step limits).
4. At least one negative constraint or exclusion (such as what the model should avoid or ignore).
- 'keyRecommendations' MUST NEVER BE EMPTY. It must contain exactly 3 concrete, actionable pieces of advice explaining what they should add or adjust to improve their prompt's effectiveness inside Google Workspace apps.
### ANALYSIS DIRECTIVES:
- Not every prompt requires all 4 pillars. Think of it like a stool: it only needs 3 or 4 strong legs to stand. DO NOT force or hallucinate a pillar if it is not explicitly present. If a pillar is missing, status must be 'missing' and the text array should be empty.
- A single pillar may appear more than once in a prompt (for example, a prompt can have multiple distinct constraints or background contexts). Return ALL matched case-sensitive substrings for that pillar inside the 'text' string array.
You MUST respond with a single, raw, valid JSON object. Do not include markdown wraps, backticks or preamble text. Use this exact schema. Ratings must be one of these exact strings: [`Foundation` | `Effective` | `Masterful`].
{
""rating"": ""Effective"",
""improvedPrompt"": ""[Rewritten optimised prompt here]"",
""keyRecommendations"": [
""First action recommendation"",
""Second action recommendation"",
""Third action recommendation""
],
""pillars"": {
""task"": {""status"": ""found"", ""text"": [""[substring 1]"", ""[substring 2]""], ""feedback"": ""[guidance]""},
""persona"": {""status"": ""missing"", ""text"": [], ""feedback"": ""[guidance]""},
""context"": {""status"": ""weak"", ""text"": [""[substring]""], ""feedback"": ""[guidance]""},
""format"": {""status"": ""found"", ""text"": [""[substring]""], ""feedback"": ""[guidance]""}
}
}", B2)
Writing a prompt that outputs perfectly formatted data every single time might feel intimidating, but there are two key features built into this instruction that helps with consistency:
Strict JSON Directives: We explicitly tell Gemini to return a single, raw, valid JSON object without any conversational filler or markdown formatting (like triple backticks ```). This ensures that the cell gets only the clean code it needs to be parsed, with nothing extra to cause formatting errors.
Exemplar Output: At the very end of the prompt, we provide an empty example structure of the exact JSON we expect. By providing this template, Gemini does not have to guess what keys or structures to use, it simply swaps our placeholder text with its actual evaluation, improving the consistency of the output.
Drag this formula down your column. The =AI() function processes the input text and outputs structured JSON directly into the cell:
{
"rating": "Foundation",
"improvedPrompt": "You are a Senior QA Lead and Project Management Expert. Based on the UAT results in this document, draft a professional and encouraging email to my colleague who is running this UAT. Explain the next steps required to reach sign-off, specifically outlining the bug triaging process and the re-testing cycle. Format the email with a clear 'Action Items' bulleted list and a 'Timeline' section. Constraints: The email should be under 200 words and maintain a collaborative tone. Do not include technical jargon that might confuse non-technical stakeholders.",
"keyRecommendations": [
"Define a professional persona, such as a Senior QA Lead, to establish the right tone and authority for the email.",
"Specify exactly what the 'next steps' are (e.g., bug triaging or re-testing) to reduce ambiguity for the AI.",
"Incorporate structural constraints like word counts and specific section headers to ensure the output is ready to send."
],
"pillars": {
"task": {
"status": "found",
"text": [
"Draft an email to my colleague who is running this UAT and explain what they need to do next."
],
"feedback": "The task is clear and uses a strong verb, though the specific 'next steps' are left for the AI to guess."
},
"persona": {
"status": "missing",
"text": [],
"feedback": "Adding an expert persona like a QA Lead would help set a professional and authoritative tone."
},
"context": {
"status": "found",
"text": [
"this UAT"
],
"feedback": "There is a brief mention of context, but it doesn't explicitly reference the specific document or data the AI should use."
},
"format": {
"status": "missing",
"text": [],
"feedback": "Providing structural guidelines, such as using bullet points for steps, would improve the email's clarity."
}
}
}
This formula pulls out the key parts of each prompt, giving us a neat, organised set of details to display.
What the structured JSON output looks like inside your Google Sheets cell after dragging the =AI() formula down Column B.
Step 2: Create Your Sheets Canvas
Once your evaluation column is populated, open the canvas creation tool to build your custom interface. For this your account needs to be in the Gemini Alpha or if using a personal Gmail account paying for Google AI Ultra or Google AI Pro.
Select Insert from the top menu bar.
Click Create a canvas.
This action opens the Gemini side panel directly inside your spreadsheet.
Step 3: Link Your JSON Data to the Canvas Layout
This is where the magic happens. Since Canvas can read data directly from your active sheet tab, we can instruct Gemini to build visual dashboard elements that bind directly to our JSON column.
To help Gemini understand how to split our single-cell JSON block into distinct UI elements (like progress cards, recommendation lists and copyable text blocks), we provide it with a clear design spec. This spec defines the visual layout and includes a sample set of mock data to show Gemini exactly how our JSON keys map to each display card.
Enter this layout instruction into the side panel prompt box to construct the dashboard:
### **FRONTEND REQUIREMENTS**
The application must feature a modern, minimalist Dashboard interface. Use the **Inter** font family, soft shadows, rounded borders (rounded-2xl), and a clean layout featuring:
1. **Sidebar or Dropdown Selector:** * A select dropdown or list of prompts loaded dynamically from the Google Sheet.
* On change, it loads the selected prompt's diagnostic metrics into the main canvas.
2. **Interactive Highlight Map:** * A container displaying the selected original prompt text with color-coded, underlined highlights representing found pillars.
* It MUST support multiple occurrences per pillar (i.e., if pillars[key].text is an array of strings, loop through and highlight every substring occurrence).
* If a highlighted segment is clicked, it highlights that specific pillar in the Diagnostic View below.
3. **Pillar Diagnostic Matrix:** * A 4-column visual status strip with colored indicators showing which pillars are Found (Green), Weak (Amber), or Not Included (Red).
* Below the status strip, a card showing details of the active/selected pillar: its definition, the specific matched substring(s) extracted from the prompt, and actionable "Pillar Optimization Guide" feedback.
4. **Key Recommendations & Optimized Version:** * Displays the 3 top recommendations as numbered target boxes.
* Shows the final rewritten "Master Optimized Prompt" inside a clear, styled, copyable container with a one-click clipboard copy button.
### Sample Mock Data to pre-load as default state:
```json
{
"rating": "Effective",
"improvedPrompt": "As an expert copywriter, draft a warm, professional thank-you email to @Client for attending the Q3 planning workshop, highlighting our next steps to finalize the product roadmap by Friday.",
"keyRecommendations": [
"Specify a persona like 'expert copywriter' to give the email's tone a more distinct and polished feel.",
"Add a constraint limiting the length of the email to keep it concise and easy to read.",
"Clarify the format if you want specific sections or a bulleted summary of the next steps."
],
"pillars": {
"task": {
"status": "found",
"text": ["draft a warm, professional thank-you email"],
"feedback": "Strong core instruction with clear action verbs."
},
"persona": {
"status": "missing",
"text": [],
"feedback": "No explicit role or persona defined. Gemini will write from a generic baseline."
},
"context": {
"status": "found",
"text": ["@Client", "attending the workshop"],
"feedback": "Excellent use of ambient context referencing a client and specific workshop."
},
"format": {
"status": "weak",
"text": [],
"feedback": "You didn't specify length or structure. Consider adding constraints like 'under 150 words' or 'in 3 paragraphs'."
}
}
}
```
Gemini hopefully processes your prompt, compiles the interactive layout and renders the dynamic dashboard directly over your spreadsheet cells, similar to this readonly version
Summary
This workflow hopefully demonstrates an easy approach to make more powerful Google Sheets canvas apps. Instead of managing sprawling, hard-to-maintain tables with dozens of columns, or writing hundreds of lines of Google Apps Script to parse text, we can use a single, well-structured formula to run the entire analytical process. The =AI() function does not just gather raw data, it simultaneously classifies tasks, maps dynamic structures, extracts exact highlights and packages this data into a single, clean cell.
Have you ever woken up to a massive Google Cloud bill because a developer accidentally left a cluster… Tagged with googlecloud, appsheet, finops, cloudbilling.
We’ve probably all been there, creating and forgetting a test Google Cloud project. Here is a nice solution published by Google Developer Expert Aryan Irani knitting together various Google Cloud / Workspace services. In a guide Aryan walks through how to set up an event-driven workflow, using Cloud Pub/Sub to help prevent unwanted Google Cloud spend right from your phone. Instead of waiting for an email notification, this system uses Google Sheets, AppSheet and Google Cloud Functions to monitor your budget and give you a push notification and easy way to shut down a project.
If you want to simplify this architecture further you can replace the webhook target with a Google Apps Script function. By using the auto-generated Cloud Resource Manager client library from the Google API Client Library Generator for Apps Script, you can programmatically shut down the entire target project directly from your app. Configuring the single cloud-platform OAuth scope in your script manifest allows you to delegate security control directly to Google Cloud IAM roles. Moving the project to a soft-delete state instantly stops all active billing across all services, databases and compute instances, providing a complete emergency stop-switch.
This project is a fantastic example of using low-code tools to solve real infrastructure problems. You can read the full step-by-step tutorial and learn how to configure this for your own projects.
Fix slow JDBC in Google Apps Script V8. Learn the native SQL JSON trick to boost throughput from 3 to 142 records/sec and bypass the 30-min timeout.
We have regularly featured solutions for connecting external databases to Google Workspace using the JDBC service. Our most recent example include a guide on connecting PostgreSQL to Apps Script [JDBC Guide, February 2026]. While this guide help establish connections, developers running large-scale synchronisations under the modern V8 engine frequently encounter severe performance drops. A detailed post from Pablo Felip analyses this runtime performance gap and provides a helpful workaround that can reduce execution times by over 98%.
Standard database queries in Google Apps Script suffer from severe performance degradation when using the JDBC service because the V8 runtime adds significant latency. To resolve this, Pablo highlights how developers can offload data processing to the database server by using native SQL features like FOR JSON PATH or JSON aggregation functions to bundle query results into a single, efficient JSON string. This approach dramatically reduces the processing, allowing the Apps Script code to fetch data as chunks and use V8’s native JSON parsing to reconstruct the table in memory. By using this approach, developers can achieve massive speed improvements and stay well within execution time limits.
Head over to Pablo’s blog to read the complete post, view the underlying benchmark metrics and see if this approach can speed up your database synchronisation workflows!
If, like me, you’ve often struggled with the pain of coding user interfaces with the CardService in Google Workspace, things are about to change. Using the new, open Agent2UI (A2UI) specification, agents can autonomously decide how to structure and render their own native interfaces in real time.
In a recent Pulse post, The Evolution of Google Chat: Exploring the New Wave of Developer Quickstarts, we highlighted a new Google tutorial that implements Agent2UI (A2UI) inside Google Chat. This guide shows you how to build a hybrid solution using Apps Script as a secure, lightweight gateway to Python-based agents running on the Vertex AI Agent Engine.
The Architecture: Apps Script as the Orchestrator
A common challenge when working with modern AI toolkits like the Agent Development Kit (ADK) is that they are not designed to run natively inside Apps Script. The quickstart bridges this divide by turning Apps Script into a lightweight, secure orchestration layer.
Instead of running heavy processing directly inside the script, Apps Script handles the Google Chat event, manages secure server-to-server authentication, and sends the payload out to an agent running on the Vertex AI Agent Engine.
Under the Hood
A look at the script provided in the quickstart shows how the Python backend passes UI layout instructions back to the Workspace front-end. When a user asks a question, the Python script processes the request, calls any backend tools and returns a single text stream structured like this:
When this response is returned to Google Apps Script, it triggers the extractA2UIParts() function which splits this raw payload on the ---a2ui_JSON--- separator. The text before the delimiter (e.g., “Hello! I found the profile…”) is taken and posted straight to the user and the raw JSON array after the delimiter is to make the card.
Something to keep in mind is that this framework is not yet a wholesale replacement for the entire CardService library, as you will see in the script it uses a basic render to convert the A2UI JSON into CardService elements:
switch (Object.keys(component)[0]) {
case 'Text':
const textParagraph = CardService.newTextParagraph();
textParagraph.setText(extractTextValue(component["Text"].text, dataModel));
widgetWithIds.push({ id: c.id, widget: textParagraph });
break;
case 'Image':
const image = CardService.newImage();
image.setImageUrl(extractTextValue(component["Image"].url, dataModel));
widgetWithIds.push({ id: c.id, widget: image});
break;
case 'Button':
// Maps inline labels or child text components to TextButtons
// and packages them into a trailing ButtonSet...
break;
default:
console.warn(`Could not render component: ${JSON.stringify(c)}`);
}
This means that for the time being, the script example is only able to handle basic UI elements rather than handling heavy, structured data-entry flows.
Future Directions
While the quickstart provides a foundational v0.8 entry point for developers, community members are already looking at how A2UI responses can be used in Google Workspace interfaces.
An excellent example of this is Curtis Krygier’s open-source a2ui-catalogue project. Curtis has started a component library designed to build agent-driven interfaces for Google Workspace starting with Google Meet and Google Chat.
Instead of trying to bundle complex, pre-composed UI elements on the backend, Curtis advocates for a substrate model:
Atomic Philosophy: Developers define a fixed visual vocabulary of atomic “primitives” once on the client side (such as TypeScript Lit web components).
Token Efficiency: The AI agent reasons entirely within this stable vocabulary. It passes raw state updates rather than inventing presentation layouts on every conversational turn. This reduces token overhead and eliminates slow backend container redeployment loops.
Interchangeability: By completely decoupling primitives from the transport layer, the exact same v0.9 component tree can reflow dynamically across completely different containers. A layout originally designed for a fullscreen stage in a Google Meet iframe can seamlessly stack and reflow to fit inside a compact Google Chat card or side panel.
Summary
For Google Workspace developers, the base A2UI Agent quickstart serves as an excellent hands-on starting point to experiment with agent integrations in Google Workspace. The underlying frameworks are evolving rapidly, as are the solution wrappers like a2ui-catalogue. Given a speed of change don’t expect a completely frictionless, single-click deployment out of the box, and you’ll likely need to lean into a little “Gemini-powered” fault finding should sort things out.
gas-fakes server enables local development and testing of GAS webapps and Add-ons on Node with support for templating and server side calls
Bruce Mcpherson has updated his gas-fakes command-line tool, adding a local web server command to emulate Google Apps Script Web Apps and user interfaces:
At the heart of this update is the new gas-fakes serve command. This command spins up a local HTTP endpoint that routes requests directly to your doGet or doPost and other server side functions. This emulates the Apps Script environment, enabling a “save and refresh” workflow that was previously impossible without constant cloud deployments.
For those tracking the project, this update joins a deep archive of local execution experiments. We first examined the library’s foundational role as a secure sandbox for running AI-generated code [September 2025]. Since then, we have explored how to containerise Apps Script logic for Google Cloud Run [February 2026] and how to implement securing local execution via agentic automation [April 2026]. This latest release targets local web development. It eliminates the constant friction of saving, pushing and redeploying code to the cloud just to test minor visual tweaks.
How the Local Emulator Operates
The local emulator runs a lightweight Node.js process to mimic the Google Apps Script environment directly on your machine. When you run the server, the utility instantly parses your HTML templates and directs client-side google.script.run calls straight to local JavaScript function exports. This workflow lets you debug your interface and server logic in real time with zero latency, saving hours of deployment downtime.
Sandbox and Security Considerations
One thing to keep in mind is that your local machine does not enforce Google’s strict iframe security restrictions. Developing with this in mind will prevent broken features if your project is deployed to Google Apps Script. To find out more and view the complete setup code, read Bruce Mcpherson’s complete guide.
Sheets canvas allows users to conversationally build interactive, read-write mini-apps directly from their spreadsheet data. At this time, Sheets canvas is limited to supporting only single-table and single-header tables.
The new Sheets canvas is undeniably a powerful tool for creating interactive applications directly from spreadsheet data. It removes a lot of friction for rapid app creation and allows the building of visual interfaces through simple conversation beyond the current tools in Google Sheets. It is an impressive leap forward.
One question I had was how Sheets Canvas compares to other no-code tools like AppSheet. To help explore this, I thought it would be useful to run a practical comparison. In this post, we will build a Kanban board using the same project management dataset, allowing us to evaluate the new Sheets canvas against Google AppSheet.
Because we are using a template, there is zero setup required. A look at the underlying data structure and you’ll see this app has five distinct tables connecting projects to tasks and workstreams, while mapping people to specific notes. Whilst it still uses a standard Google Sheet as a data source, AppSheet allows us to use true relational data. For example, projects can have related tasks, assigned team members, and detailed histories.
Sheets canvas takes a different approach. Inside your spreadsheet, you open the Gemini side panel, enable the canvas tool, and provide an instruction like “Can you turn this data into a kanban board app?”, which you can view (readonly) here.
This experience is similar to the existing AppSheet ‘Gemini for App Creation’ with two key differences: in the Sheet canvas we are starting with existing data and the development process is iterative; and if you do continue to ask Gemini to update the canvas, for example, to pull sub-tasks and user avatars from other tabs, something to be aware of is that the result is a clever illusion. Because canvas only ingests the active sheet, you cannot dynamically query other tabs. This is a known current limitation:
Currently, canvases only use data from a single Sheet tab. The canvas provides a read-write interface for your spreadsheet data. If you have edit access, you can edit, delete, or add data directly within the canvas as an alternative to the grid view. If you have comment or view access, you can’t modify the canvas.
Under the Hood: Actions vs Bespoke Code
Comparing how these tools actually generate the interface provides another stark contrast. Asking Gemini to build the board generated hundreds of lines of custom React code. It imported standard web development libraries to render a bespoke interface directly over the spreadsheet cells. You are quite literally prompting an AI front-end developer to build a miniature web application that sits on top of your grid.
Data Integrity: Strict Rules vs Surface Forms
AppSheet enforces data integrity at the system level. You can configure deep initial value formulas that populate fields dynamically based on user context or timestamps. You can deploy strict validation rules that prevent a user from selecting a date in the past or entering a mismatched email address. The application simply will not save the record until the conditions are met.
Sheets canvas handles data entry through surface-level web forms. Looking at the generated code for our Kanban board reveals that the AI used standard HTML form attributes to require certain fields and injected fallback text into the React state to mimic initial values. It is functional. It works well for simple applications; however, the canvas interface does not natively inherit the data validation rules you build into the underlying spreadsheet cells. If you want strict input controls, you must explicitly prompt the AI to write custom JavaScript to catch those errors in the browser.
Security, Governance, and Shadow IT
The biggest difference between Sheets canvas and AppSheet emerges when you look at it at an enterprise level. A Sheets canvas is simply a file formatting layer. Its security model relies entirely on standard Google Drive permissions. If a user has edit access to the spreadsheet, they have edit access to the canvas.
AppSheet operates as a true enterprise platform. It lives behind a dedicated Admin Console where IT teams maintain oversight over every application built across the organisation. For teams using AppSheet Enterprise Plus licences, administrators can define governance policies that automatically enforce corporate compliance across hundreds of independent projects. An administrator might create a rule that instantly blocks deployment if a user attempts to connect an unapproved external database or fails to mandate strict domain authentication.
The Feature Comparison
To help you decide which tool fits your current project, here is a breakdown of their core capabilities.
Feature
Sheets Canvas (Alpha)
AppSheet
Primary Purpose
Building custom interfaces to visualise and update single-sheet data.
Building robust business applications with a dedicated desktop mode.
Data Source
A single Google Sheet tab.
Multiple sources including Sheets, SQL, and external APIs.
Data Structure
Flat. Cannot access other tabs dynamically. AI relies on faking relationships with hardcoded static data.
Relational.
Data Validation
Basic HTML/React form rules. Requires custom JavaScript for complex logic.
Deep system-level validation and computed initial values.
Read/Write Access
Editors can edit, delete, or add data. Viewers cannot.
High. Requires structured logic and intentional design.
Security & Governance
Relies on standard Google Drive file permissions.
Centralised admin console with strict policy-driven enterprise governance.
The Verdict
If you need a quick dashboard to track your team’s weekly tasks, use Sheets canvas. It is fast, intuitive, and keeps everyone working within a familiar spreadsheet environment while the AI handles the complex front-end code.
If your workflows are growing, if you need to connect multiple data sources like mapping notes and users to specific projects reliably, or if your IT department requires strict visibility over internal tools, AppSheet remains the undisputed choice.
A Comparative Study of Agentic Frameworks and Multi-Agent Orchestration
Earlier this week, we explored how Bruce Mcpherson’s gas-fakes agent provides a secure, sandboxed alternative to my initial experiments with the Workspace CLI. While securing local execution is a necessary step, it surfaces an entirely new operational headache. As we build out these agentic behaviours, what happens when your AI has access to too many tools?
As Kanshi Tanaike identifies, these systems hit a cognitive wall known as ‘Tool Space Interference’, a concept recently detailed by Microsoft researchers, which is widely recognised across the industry as context bloat. As noted in Google’s recent engineering piece on architecting context-aware frameworks, “single-agent systems struggle with context bloat; multi-agent systems amplify it.” If you load an agent’s active memory with 160 different Workspace functions, its reasoning accuracy degrades significantly; your token costs also spiral out of control.
Tanaike tackles this phenomenon head-on in his latest comparative study. He contextualises my own CLI skill-based prototyping and Bruce’s local emulation, mapping them against the architecture of the newly announced Gemini Enterprise Agent Platform at Google Cloud Next ’26.
I must admit, while I was proudly figuring out how to chain a few CLI commands together without crashing my terminal, Tanaike was already designing complex orchestration networks using multiple autonomous agents to resolve this friction.
Delegating to Sub-Agents
To combat Tool Space Interference, Tanaike proposes dynamic tool creation. Rather than pre-loading an agent with functions, a primary orchestrator delegates tasks to sub-agents that write, test, and deploy custom Google Apps Script code on the fly. This entirely removes the need to store static skills in the agent’s memory.
Alternatively, he suggests using the Agent-to-Agent (A2A) protocol to shift large libraries of predefined skills onto remote Apps Script Web Apps. By bypassing complex cross-domain authentication using local agent cards, this method clears the main agent’s active memory while retaining frictionless access to legacy macros.
The Conscious Expert: Zero-Trust Routing and Caching
To safely manage these multi-agent delegations, Tanaike introduces two advanced frameworks: the Federated Context-Aware Routing Architecture (Federated CARA) and the Self-Optimising Tool Caching Network (SOTCN). From a data governance perspective, these concepts provide a fascinating blueprint for enterprise security when combined.
Federated CARA acts as a zero-trust architecture that evaluates the classification of the data involved in any given prompt. Based on this sensitivity, it dynamically routes the AI task to either a containerised emulation environment or a remote A2A subagent. This design maps perfectly to the Agent Gateway and Agent Identity features introduced within the Gemini Enterprise Agent Platform, ensuring that native IAM access control policies are strictly enforced to guard against data exfiltration.
Building on this secure routing pipeline, SOTCN functions as an additional security perimeter by treating skills as modular assets kept in “cold storage”. By using semantic search, the network programmatically retrieves and inserts only the necessary capabilities into the agent’s prompt during a given session. This approach has just been validated by the launch of Google’s official Agent Skills repository at Next ’26. By publishing compact, agent-first Markdown files to be loaded entirely on demand, Google is signalling a wider industry push towards “Context Engineering”.
Tanaike’s synthesis offers a highly scalable roadmap for multi-agent orchestration. I highly recommend reading his full paper and watching the accompanying explanatory video to see how these architectures align with Google’s new enterprise standards.
gf_agent is an interactive automation agent for Gemini CLI that enables users to access and manupulate workspace resources conversationally.
The automation of Google Workspace is advancing rapidly. We are moving away from static scripts and rigid cloud triggers towards environments where AI agents autonomously orchestrate complex tasks. Recently, I shared a recipe exploring how we could use the Workspace CLI to call the Apps Script Execution API. I was quite pleased with it, however, a recent email exchange with Bruce Mcpherson quickly highlighted a much more efficient path.
Bruce pointed out that his new gf_agent for the Gemini CLI bypasses the need to write these intermediary scripts entirely. By using his gas-fakes emulation environment, the agent accepts plain English requests, generates the required Apps Script logic dynamically, and executes it securely on your local machine. It is a brilliant piece of work. You simply ask the agent to summarise your latest emails or resize images in a document, and it handles the heavy lifting without using the Apps Script runtime.
To illustrate this capability, Bruce shared an excerpt from a recent run demonstrating a complete web to document flow, similar to the Workspace CLI / Apps Script Execution API example. The log captures the moment the system activates the local skill, maps the available resources, and then executes the required logic directly from the terminal:
✦ I will activate the gf_agent skill to access specialized guidance for Google Workspace automation.
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ Activate Skill "gf_agent": Specialized agent for automating Google Workspace tasks locally using gas-fakes. Gener… │
│ │
│ Skill gf_agent activated. Resources loaded from /Users/brucemcpherson/.gemini/skills/gf_agent: │
│ │
│ Showing up to 200 items (files + folders). │
│ │
│ /Users/brucemcpherson/.gemini/skills/gf_agent/ │
│ ├───documentation.md │
│ ├───index.md │
│ ├───README.md │
│ ├───SKILL.md │
│ ├───scripts/ │
│ │ └───builder.js │
│ └───skills/ │
│ ├───base.md │
│ ├───cache.md │
│ ├───calendar.md │
│ ├───charts.md │
│ ├───document.md │
│ ├───drive.md │
│ ├───forms.md │
│ ├───gmail.md │
│ ├───jdbc.md │
│ ├───lock.md │
│ ├───properties.md │
│ ├───script.md │
│ ├───slides.md │
│ ├───spreadsheet.md │
│ ├───urlfetch.md │
│ ├───utilities.md │
│ └───xml.md │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ I will use the workspace_agent to fetch the content from the URL, create a Google Document from the HTML, copy it, and then
resize the images in the copy using the recommended Docs API workaround, as setWidth/setHeight are not supported in the
local environment.
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ workspace_agent (gas-fakes-mcp MCP Server) {"script":"\nconst url = 'https://ramblings.mcpher.com/resurrecting-sc… │
│ │
│ 2026-04-24T11:49:08.017Z ...using env file in │
│ /Users/brucemcpherson/Documents/repos/empty/recipe-web-to-doc-gf/scripts/.env │
│ 2026-04-24T11:49:08.763Z ...gas-fakes version 2.3.9 │
│ 2026-04-24T11:49:08.763Z Fetching content from: │
│ https://ramblings.mcpher.com/resurrecting-scriptdb-nosql-database-for-apps-script/ │
│ 2026-04-24T11:49:09.451Z [Worker] ...authorized backends: google via DWD ([email protected]) │
│ 2026-04-24T11:49:09.451Z [Worker] ...using scriptId: ab9c5881-...-2bc29a0c8834 (source: env) │
│ 2026-04-24T11:49:14.788Z Created original document with ID: 1sQ7oGqKm9XOQzsYQF10fM6uiAoD2_OSJ6uAJgunPnbE │
│ 2026-04-24T11:49:17.980Z Created copy document with ID: 1Labz...ZSSo │
│ 2026-04-24T11:49:19.052Z Found 12 images in the document. │
│ 2026-04-24T11:49:19.053Z Applying 24 updates to resize images... │
│ 2026-04-24T11:49:21.557Z Image resizing complete. │
│ 2026-04-24T11:49:21.557Z Original Doc URL: │
│ https://docs.google.com/document/d/1sQ7...PnbE/edit │
│ 2026-04-24T11:49:21.558Z Resized Doc URL: │
│ https://docs.google.com/document/d/1Labz...ZSSo/edit │
│ 2026-04-24T11:49:21.563Z ...terminating worker thread │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ I have successfully fetched the content from the specified URL and created the requested documents.
Weighing the Approaches: Broad CLI vs Sandboxed Emulation
Let us consider the practical realities of these two approaches. The Workspace CLI generally operates under the broad OAuth scopes granted during its initial setup. If you authorise full Google Drive access, any AI agent driving that CLI inherently possesses the same unrestricted permissions. Handing an autonomous reasoning engine the keys to your entire file system is risky. A simple mis-prompt could lead to data loss or unintended modifications.
Conversely, Bruce’s gas-fakes approach offers a much tighter, sandboxed environment. Rather than relying on global credentials, gas-fakes can be explicitly configured to operate only on specific Drive files or within isolated boundaries. By functioning as a Model Context Protocol (MCP) server, it allows the LLM to write native Apps Script syntax and immediately test it against Workspace resources, but it forces the execution to happen within a securely fenced area. The primary benefit here is safe, dynamic adaptability. You do not need to pre-write a specific skill to resize an image; the agent simply authors the script on the fly and the emulator runs it safely.
It is worth mentioning that gas-fakes is still in development so not all Apps Script methods are implemented yet, but the approach provides a robust sandbox for interacting with Workspace APIs. Click through to Bruce’s post to read more.