The real power of agentic AI comes from turning your everyday code into durable, stateful tools that modern AI clients can discover and use automatically. With Golem 1.5, you write normal code — and it becomes a tool that Claude Desktop, ChatGPT Agents, Gemini, Cursor, and other AI tools can intelligently call whenever they need it. No extra glue code.
We’ll build a hands-on use case: a Durable Image Studio Agent. You’ll see Golem 1.5’s special data types come to life as we let AI clients like Claude Desktop, ChatGPT Agents, Google Gemini, Cursor, Continue.dev, and Windsurf automatically discover the agent methods and intelligently decide when to use it - — all while the agent stays fully stateful and restart-proof - thanks to Golem.
Under The Hood
Golem 1.5’s MCP integration is what makes this work. You don’t need to know the protocol in depth — just bring curiosity. By the end, you’ll see how normal code becomes reusable AI tools, and why MCP matters.
A quick note on MCP: It is an open standard that lets LLMs and AI tools (Claude Desktop, ChatGPT Agents, Google Gemini, Cursor, Continue.dev, Windsurf, and more) seamlessly discover and use external capabilities.
Even if you have never heard of MCP tools, you might have already used them — like when you ask ChatGPT to “what’s the weather today” and it does so by calling an MCP tool which is web-search.
MCP exposure is automatic via a small manifest section. We will use Claude Desktop as the AI client, but the same agent will work with any MCP-compatible client without any changes.
The Example: Image Studio Agent
On a high level, we are going to do the following:
- Write a simple TypeScript code that can upload and edit an image.
- Deploy this in Golem that will automatically expose a MCP server for AI tools to interact with.
- Configure the server URL in
Claude Desktop - In Claude’s chat window, we will ask Claude to create an image and upload it in plain english.
- Later we ask to edit the same image with some instructions.
We will use only LLM chats to interact with your agent methods. No manual invocations.
Setup your project
Install golem from here: https://github.com/golemcloud/golem/releases/tag/v1.5.0-rc1, and then:
> golem new
> Select "TypeScript Agent" template
> Name it "image-studio-agent"
> cd image-studio-agent
> golem build
Write agent code
Now let’s replace the CounterAgent code with the following: Mostly it is self explanatory as it is regular type-script code.
The only difference here is usage of @agent() and @description() to label your class as an agent in golem runtime, and a description that will help AI clients.
Click to expand the full TypeScript agent code
import {
BaseAgent,
agent,
description,
} from '@golemcloud/golem-ts-sdk';
import { UnstructuredBinary, UnstructuredText } from '@golemcloud/golem-ts-sdk';
@agent()
export class ImageStudioAgent extends BaseAgent {
private projectId: string;
// Let's store the images with an image-id and this is automatically persistent with Golem
private images: Map<string, Uint8Array> = new Map();
constructor(projectId: string) {
super();
this.projectId = projectId;
}
@description("Upload a new image to the project. Returns a unique image_id.")
async uploadImage(
name: string,
// The UnstructuredBinary type allows for flexible binary data input (inline or URL) with MIME type constraints
// Here we specify you can upload JPEG, PNG, or WebP images
data: UnstructuredBinary<['image/jpeg', 'image/png', 'image/webp']>
): Promise<string> {
const imageId = `img_${Date.now()}_${name.replace(/[^a-z0-9]/gi, '_')}`;
const binaryData = this.extractBinary(data);
this.images.set(imageId, binaryData);
return imageId;
}
@description("Edit an image with natural language instructions and return the result as PNG.")
async editImage(
imageId: string,
instructions: UnstructuredText<['en']>
): Promise<UnstructuredBinary<['image/png']>> {
const original = this.images.get(imageId);
if (!original) {
throw new Error(`Image not found: ${imageId}`);
}
const edited = await this.applyEdits(original, instructions);
// Store the edited version for future reference
this.images.set(`${imageId}_edited`, edited);
return {
tag: 'inline',
val: edited,
mimeType: 'image/png' as const,
};
}
/**
* Helper to safely extract Uint8Array from UnstructuredBinary
*/
private extractBinary(
data: UnstructuredBinary<['image/jpeg', 'image/png', 'image/webp']>
): Uint8Array {
if (data.tag === 'inline') {
return data.val;
} else if (data.tag === 'url') {
// In a real implementation, you could fetch the URL here.
// For simplicity in this demo, we'll throw (or you can add fetch logic).
throw new Error(`Remote URL support not implemented in this demo: ${data.val}`);
}
throw new Error('Unsupported UnstructuredBinary format');
}
private async applyEdits(
data: Uint8Array,
instructions: UnstructuredText<['en']>
): Promise<Uint8Array> {
console.log(`Applying edits with instructions: "${instructions}"`);
// For now, just return the original (so the demo works)
return data;
}
}Try building it again using golem build just to ensure everything is intact.
Expose MCP Server
Open golem.yaml and add the following section:
mcp:
deployments:
local:
- domain: mcp-image-studio.localhost:9007
agents:
ImageStudioAgent: {}
Please do remove the httpApi block since we are not using it
Once configured, deploy your agent with golem deploy
Now your agent is available in Golem runtime. Not only that, it exposes as an MCP server at mcp-image-studio.localhost:9007.
Configure Claude Desktop
Regardless of the AI client, you must configure the MCP server URL. If you use a different client, follow that client’s MCP setup docs.
Click to expand the Claude Desktop MCP config JSON
{
"mcpServers": {
"golem": {
"command": "npx",
"args": [
"mcp-remote",
"http://mcp-image-studio.localhost:9007/mcp",
"--header",
"Host: mcp-image-studio.localhost:9007",
"--allow-http"
]
}
}
}
You just edited claude_desktop_config.json in Claude’s configuration file.
Restart Claude Desktop, to pick the configuration changes.
Open a chat in Claude Desktop
From now on we can interact with our agent methods using plain english from within the chat.
Before that, you can cross verify if the AI tool can interact with your agent. Within the chat, go to the + sign and there you can see your MCP server in action as given below:
You can even ask Claude itself using plain english “list the tools in golem” and it gets it. golem is the name we used when configuring Claude Desktop in the previous step.
Claude automatically describing your agent methods
Ask Claude to generate and upload an image
I was lazy to select and upload, so I asked Claude itself to generate one and upload in the chat
Claude automatically calls exact agent method to upload image
Claude knows your agent method expects base64 encoded image. We can also see the image-id that was created. See uploadImage function in our code.
Ask Claude to edit the image
Claude automatically calls exact agent method to edit image
Claude knowing the available tools and it’s right usage
Claude does a lot under the hood. Golem exposes what Claude needs so it can pass the right parameters in the right format.
You can inspect the exact request Claude sent directly in the chat.
Claude sending the right parameters
Durability
Even if the agent restarts after a crash right after upload, Golem’s durability keeps the image state intact, so you can still edit it in the next prompt.
Reference
Please refer to Vigoo’s post on how to build MCP server with OIDC authentication and validate the server using MCP Inspector.