MCP Code Mode and Erlang: Building a true Google Workspace Universal "MCP"
(hattip to my coworker Eric O’Connor for 100% of this)
One of the benefits of the current MCP vs Skills war of words is smart people sharing creative solutions. The MCP tool context explosion is less of an issue than it used to be, but it’s still inspiring creative takes. Cloudflare’s Code Mode MCP is a fascinating example.
Cloudflare’s API has over 2,500 endpoints. The naive approach with MCP is to expose each endpoint as a tool, which would overwhelm all but the largest context windows.
Cloudflare found that LLMs are much better at writing code than at tool calling — probably because training data contains orders of magnitude more real TypeScript than nascent tool-call examples. So instead of giving the model 2,500 tool definitions to reason about, you give it a typed SDK and let it write programs. Cloudflare’s Code Mode MCP has two tools: search() and execute().
execute()runs JavaScript to make the actual API call. The agent writes code against a typed SDK, and it runs in an isolated Worker. Theexecute()endpoint doesn’t know what API call it will make until the agent tells it. It’s a blank container that receives its behavior at runtime.search()runs JavaScript against the full Cloudflare OpenAPI spec to find relevant endpoints. The 2-million-token API spec never leaves the server. The agent sends a small program to find what it needs and gets back a few hundred tokens of results. Both are sandboxed code execution.
Erlang’s Universal Server
This idea has a name. In 2013, Joe Armstrong — creator of Erlang — wrote a short blog post about his favorite Erlang program: a universal server. It was five lines:
universal_server() ->
receive
{become, F} ->
F()
end.
A server that does nothing until it’s told what it is. It waits for a message telling it what to become, then it becomes that thing. No behavior is baked in. The server receives its purpose at runtime.
Aside: If you’re not familiar with Erlang (I wasn’t!), I recommend walking through this example with your favorite LLM. Not surprisingly, it’s a very dense window into the novel constructs of the language!
Cloudflare’s code mode is this pattern:
| Erlang | Cloudflare |
|---|---|
universal_server() |
execute() tool (sandboxed Worker) |
{become, F} |
Generated JavaScript |
F() |
Sandboxed execution |
This pattern is powerful enough that Cloudflare followed on with dedicated Dynamic Workers to stand up sandboxes for your own SDK.
Building a Universal Server for Google Workspace
A few months ago, a Google Dev Rel Engineer shipped a Google Workspace CLI and everyone was excited until the moment they needed to fight with GCP’s cloud console and OAuth registration to get it to work.
Similarly, you could use Cloudflare’s dynamic workers to build a Google Workspace integration but you’d have to:
- Create a GCP project (may require approval at your company)
- Enable each API you want (Drive, Docs, Sheets…)
- Set up OAuth credentials
- Install client libraries
- Handle token refresh (tokens expire daily)
- Manage scopes and permissions per API
It turns out that every single Google Workspace in existence today offers you a dynamic worker for free with Google App Script, a sandbox, hosted JavaScript runtime in Google Workspaces that includes built in ability to act as a web app.
And using JavaScript’s eval(), we can build a universal server for Google’s entire API surface on Apps Script with about 20 lines of code:
// Code.gs — deploy once, never touch again
function doPost(e) {
var params = e.parameter || {};
if (params.token !== getConfig_().token) {
return jsonResponse_({ status: 'error', message: 'Invalid token' });
}
try {
var body = JSON.parse(e.postData.contents);
var result = eval(body.code);
return jsonResponse_({ status: 'ok', result: result });
} catch (err) {
return jsonResponse_({ status: 'error', message: err.toString() });
}
}
Deploy this as a web app on Apps Script, and you have a universal server sitting in Google’s cloud. It does nothing until you send it JavaScript. The deploying Google account has already authorized the script — your laptop (or your agent) just sends code to it.
# What's in my Drive?
curl -L -H 'Content-Type: application/json' \
-d '{"code": "DriveApp.getFiles().next().getName()"}' \
'$WEBAPP_URL?token=$SECRET_TOKEN'
# Search for a document
curl -L -H 'Content-Type: application/json' \
-d '{"code": "var files = DriveApp.searchFiles(\"fullText contains \\\"quarterly\\\"\"); var results = []; while (files.hasNext()) results.push(files.next().getName()); results;"}' \
'$WEBAPP_URL?token=$SECRET_TOKEN'
No OAuth dance on your laptop. No refreshing tokens every day. No GCP project. The code runs with whatever permissions the deploying account has — Drive, Docs, Sheets, Gmail, Calendar.
Sending whole scripts
The one-liners are useful, but the pattern gets more interesting when you send entire scripts. Your agent writes JavaScript on your laptop but it executes in the App Script sandbox:
// spreadsheet-reporter.js — lives on your laptop, never deployed
function summarizeSheet(id) {
var ss = SpreadsheetApp.openById(id);
var sheets = ss.getSheets();
return sheets.map(function(s) {
return {
name: s.getName(),
rows: s.getDataRange().getNumRows(),
headers: s.getDataRange().getValues()[0]
};
});
}
summarizeSheet("1a2b3c...");
Then send the whole file:
curl -L -H 'Content-Type: application/json' \
-d "{\"code\": $(cat spreadsheet-reporter.js | jq -Rs)}" \
'$WEBAPP_URL?token=$SECRET_TOKEN'
The server evals the code — defining the functions and executing the call at the end. For that invocation, the universal server has become a spreadsheet reporter. Next time you might send it a document exporter, or a Drive search tool, or a Gmail analyzer.
There’s nothing to deploy. The original Code.gs is a shell that never changes. The code is written just in time as the requirements change and as good patterns are discovered, they can be saved as templates and examples.
Accessing any Google API
Apps Script doesn’t just give you the convenience layer (DriveApp, SpreadsheetApp). It also gives you ScriptApp.getOAuthToken() — an OAuth token for the deploying user, for free, no refresh logic needed. Combined with UrlFetchApp, you can call any Google REST API:
var token = ScriptApp.getOAuthToken();
var resp = UrlFetchApp.fetch(
'https://www.googleapis.com/drive/v3/files?q=name+contains+%27report%27',
{ headers: { 'Authorization': 'Bearer ' + token } }
);
JSON.parse(resp.getContentText());
And Google publishes a machine-readable Discovery API that describes all 500+ Google REST APIs — endpoints, parameters, schemas — accessible without authentication. The universal server can fetch these specs at runtime and search them, the same way Cloudflare’s search() searches the OpenAPI spec:
var spec = JSON.parse(UrlFetchApp.fetch(
'https://sheets.googleapis.com/$discovery/rest?version=v4'
).getContentText());
var results = [];
function walk(resources) {
for (var name in resources) {
var r = resources[name];
if (r.methods) {
for (var m in r.methods) {
if (m.match(/append/i)) {
results.push({ resource: name, method: m,
path: r.methods[m].path,
description: r.methods[m].description });
}
}
}
if (r.resources) walk(r.resources);
}
}
walk(spec.resources);
results;
The Result
So the Apps Script universal server has the full Cloudflare code mode pattern available to it: search a spec to discover capabilities, then execute code that uses them — with auth handled automatically.
The universal server collapses the entire Google Workspace functionality into: deploy once, send code. For a personal productivity tool, a small team’s internal workflow, or an AI agent that needs a handle into Google’s APIs — this is a pragmatic tradeoff.
As our auth is a very straightforward obfuscated URL and secret token, and it’s not meant for production distribution, we don’t actually need MCP at all here. In this case, with a few env variables and well constructed curls, we have a universal Google service. After all that, this is a much better fit for an agent skill and so you’ll find that in the example repo.
The Idea
Obviously the universal server is never the final implementation or the production service. But it’s often the first useful thing you can build. The pattern — a blank receiver that gets its behavior at runtime — keeps showing up because it solves a real problem: the cost of adding a new capability should be “write a function,” not “deploy a service.”
It shows up anywhere that sending code to where the data lives beats bringing the data to where the code runs. Data warehouses do this with SQL execution. Joe Armstrong discovered it programming distributed systems. Cloudflare discovered this for building flexible agent tools, and now can use it too.