Skip to content
GlxymeshDocs
glxymesh.com
Select theme
Open console
Reading time 4 min

SDK reference

The ctx object every Glxymesh function tool receives, in Go, TypeScript and Python, for outbound HTTP, key placeholders, logs, the caller, the deadline and errors.

Every function tool receives a ctx. It’s the same in each language, shaped the way that language does things.

Language Package
Go glxymesh.com/sdk/glxy
TypeScript @glxymesh/sdk
Python glxymesh

gxmesh init sets the SDK up for you. A Go project’s go.mod requires glxymesh.com/sdk, and a TypeScript project’s package.json depends on @glxymesh/sdk; run npm install (or pnpm install) once for your editor and local runs. A Python project gets a copy in .glxy/ until the SDK is on PyPI. However you install it, the platform links its own matching copy when it builds, so a tool always runs against the SDK Glxymesh expects.

The SDKs are open source under Apache-2.0 at github.com/glxymesh/sdk, one folder per language: go get glxymesh.com/sdk (reference) and npm install @glxymesh/sdk (package).

tools/<name>/tool.ts
import type { Ctx } from '@glxymesh/sdk';
import type { Input } from './tool.gen';
export async function run(ctx: Ctx, input: Input) { ... }

Input is generated in tool.gen.ts, with the input names from tool.yml. Return anything JSON can hold.

TypeScript Go Python
HTTP ctx.fetch(url, init), the standard fetch ctx.HTTP() returns an *http.Client ctx.fetch(url, method=, params=, headers=, json=, data=)
Key placeholder secret('NAME'), imported from the SDK glxy.Secret("NAME") secret("NAME"), from glxymesh
Logs ctx.log.info/warn/error(message) ctx.Log().Info/Warn/Error(format, args...) ctx.log.info/warn/error(message)
Caller ctx.caller ctx.Caller ctx.caller
Deadline ctx.signal aborts at it; ctx.remaining() is milliseconds left ctx is a context.Context; ctx.Remaining() is a time.Duration ctx.remaining() is seconds left; a request gives up at the deadline
Error for the model throw new ToolError(message) return nil, glxy.Errorf(format, args...) raise ToolError(message)
TCP connection await ctx.connect('host:port'), a socket; await ctx.forward('host:port'), a local address ctx.DialContext(ctx, "tcp", "host:port"), a dial hook; ctx.Forward("host:port") ctx.connect("host:port"), a socket; ctx.forward("host:port"), a local address
Passed-in key await ctx.secretValue('NAME') ctx.SecretValue("NAME") ctx.secret_value("NAME")

In Python, ctx.fetch returns a response with .status, .headers (lowercase names), .content, .text, .json() and .raise_for_status(), which raises a ToolError naming the status unless it is 2xx.

Every request goes through the egress gateway, which checks the host against network.allow, adds the tool’s keys on their bound hosts, and records the request. A request to a host the tool may not reach fails with an error that names the host: an EgressError in TypeScript and Python, and an error from Do or Get in Go.

Pass the platform’s client to SDKs that accept one:

import { Octokit } from '@octokit/rest';
const gh = new Octokit({ request: { fetch: ctx.fetch } });

In Python, make requests with ctx.fetch. Libraries like requests and httpx open their own connections, so they can’t reach the internet from a deployed tool.

An SDK that opens its own connections can’t reach the internet from a deployed tool.

secret('NAME') returns a placeholder, not the key. Put it where the API expects the key, such as a JSON body, and the egress gateway swaps in the value on the key’s bound hosts only. Keys with a header or query in tool.yml need no placeholder. See Keys and network access.

Log lines ride back with the call’s result. They appear in gxmesh call and gxmesh test, and in the console’s Mesh Builder when you try a call. Up to 64 KB per call is kept; past that, lines are dropped and the result says so.

Who the call is for: org, project, userId, and clientId, the MCP client the person allowed, such as Claude or Cursor. In Go they’re Org, Project, UserID and ClientID; in Python, org, project, user_id and client_id. Never an email address or a token.

Return a tool error for anything the model can act on: a missing record, a bad argument, a rate limit. The model reads the message, so write it as advice. Any other error or exception is treated as a bug: the model gets a fixed sentence and you get the details.

Nothing survives between calls: don’t keep state in global variables. Key/value storage for function tools isn’t available yet.