Speakeasy Logo
Skip to Content

Product Updates

MCP

Gram Functions: A TypeScript-native framework for building agent tools

Nolan Di Mare Sullivan

Nolan Di Mare Sullivan

November 17, 2025 - 6 min read

Gram Functions: A TypeScript-native framework for building agent tools

Gram is the MCP cloud platform that makes building production-ready MCP servers fast and easy. Today, we’re making it even more powerful with Gram Functions, a TypeScript framework that lets you define agent tools in code without worrying about MCP protocol internals or managing infrastructure. Write your tool logic, deploy to Gram’s managed platform, and get production-grade MCP servers with enterprise performance, observability, and security built-in.

With Gram Functions, you can:

  1. Define agent tools using an intuitive TypeScript framework that abstracts away protocol complexity
  2. Deploy to managed infrastructure with one command
  3. Scale production MCP servers without operational overhead

Moving beyond APIs

In the 45 days since Gram launched, we’ve seen teams like Polar use Gram-hosted MCP servers to build amazing AI experiences. But we always knew that API-based MCP was only the beginning of the story.

Sometimes a company’s APIs are the right abstraction for an LLM to use, but often they’re not. The right API endpoints may not be present, or they don’t map cleanly to business operations, or, the LLM simply needs capabilities that go beyond HTTP (querying a DB).

Today, we’re taking care of all those use cases with Gram Functions.

An agent tool framework built for TypeScript developers

Functions TypeScript Framework

The Functions framework is open source. Check out Github to see how it works under the hood, contribute improvements, or adapt it for your own use cases. Give us a star!

View on GitHub

Gram Functions lets you compose TypeScript tools in code that are hosted as MCP servers. No need for OpenAPI. No need for detailed MCP protocol knowledge. No infrastructure to manage. Just define tools in code and deploy them securely as MCP servers in Gram’s serverless environment. Remix tools across different functions and OpenAPI into a single MCP server.

The Gram Functions API is designed to be intuitive and familiar to TypeScript developers. Each tool definition has four simple components:

  • name: A unique identifier for the tool that agents will use to call it
  • description: A human-readable explanation that helps agents understand when to use the tool
  • inputSchema: A Zod schema defining the expected parameters with type safety and validation
  • execute: An async function containing your business logic
functions.ts
import { Gram } from "@gram-ai/functions"; import * as z from "zod/mini"; const gram = new Gram().tool({ name: "greet", description: "Greet someone special", inputSchema: { name: z.string() }, async execute(ctx, input) { return ctx.text(`Hello, ${input.name}!`); }, });

That’s it. Upload this code to Gram, and it immediately becomes a tool that agents can use. Once uploaded, a tool can be used across multiple MCP servers.

A focused approach to MCP

Gram Functions isn’t trying to be an exhaustive implementation of the MCP protocol. Instead, we’re focused on making the core building blocks of MCP like tools and resources, as ergonomic as possible to work with through a high level API.

The tools you build with Gram are exposed as MCP servers and work with any MCP client, but they represent a carefully selected subset of what’s possible with the protocol. This tradeoff lets us deliver a dramatically better developer experience for the most common use cases while maintaining full compatibility with the MCP ecosystem.

For those who want to start with existing implementations we do support a complete pass through of natively implemented servers using the MCP SDK.

Functions in production

The above example was basic, but Gram Functions can handle complex workflows that call multiple APIs, query databases, and perform business logic:

investigate_failed_payment.ts
export const gram = new Gram().tool({ name: "investigate_failed_payment", description: "Investigate why a payment failed and check customer history", inputSchema: { paymentId: z.string(), }, async execute(ctx, input) { // Get payment details const payment = await fetchPaymentDetails(input.paymentId, ctx); // Query customer's payment history const history = await fetchPaymentHistory(payment.customerId, ctx); // Check if card is about to expire const cardStatus = await checkCardExpiry(payment.cardId, ctx); // Query risk score const riskScore = await getRiskScore(payment.customerId, ctx); return ctx.json({ failureReason: payment.errorMessage, customerHistory: { totalPayments: history.total, failureRate: history.failureRate, lastSuccessful: history.lastSuccess, }, cardExpiring: cardStatus.expiresWithin30Days, riskLevel: riskScore.level, recommendedAction: determineAction(payment, history, riskScore), }); }, });

Without a Gram function, an agent would need to make four separate API calls, construct each request correctly, parse responses, and synthesize the results. Each additional call multiplies the chance of failure. If each call has a 95% success rate, four calls drops overall success to 81%.

Gram Functions lets you encode this workflow once, correctly, and agents simply call investigate_failed_payment.

Getting started

Functions are available to users on every tier (including free). You can create a new Gram Functions project to start writing tools:

Create Gram project
npm create @gram-ai/function > npx > "create-function" Pick a framework Gram What do you want to call your project? demo-mcp Where do you want to create it? demo-mcp Initialize a git repository? Yes Install dependencies with npm? Yes All done! Jump in with cd demo-mcp. Some next steps: - Start a local development MCP server with npm run dev - Build your function with npm run build - Create MCP servers from your tools in the Gram dashboard: https://app.getgram.ai Have fun 🚀

This creates a project with example tools and our minimal framework:

src/gram.ts
import { Gram } from "@gram-ai/functions"; import * as z from "zod/mini"; export const gram = new Gram().tool({ name: "greet", description: "Greet someone special", inputSchema: { name: z.string(), }, async execute(ctx, input) { return ctx.json({ message: `Hello, ${input.name}!` }); }, });

Deploy to Gram:

deploy
npm run build npm run push

Your function is now live as an MCP tool, available at your Gram-hosted MCP server URL. Connect it to Claude Desktop, Cursor, or any MCP-compatible platform.

What’s next

We’re launching our TypeScript framework today and will be expanding its capabilities in the coming months

Looking ahead:

  • Support for ChatGPT Apps - providing a high level widget API in the functions framework for building ChatGPT apps.
  • Ability to stage and draft toolsets - add the ability to preview changes to your tools before they’re deployed into production We’re building Gram Functions to be the fastest path from code to production MCP. Whether you’re wrapping internal APIs, orchestrating complex workflows, or building entirely new capabilities, Gram Functions provides the infrastructure you need without the complexity you don’t.

Try it today: Sign up for Gram  and deploy your first function.


Questions about Gram Functions or need help getting started? Book time with our team

Last updated on

Organize your
dev universe,

faster and easier.

Try Speakeasy Now