Speakeasy Logo
Skip to Content
Gram DocumentationConceptsTool Sources

Tool Sources

Sources are the starting point for creating tools that can be utilized by AI agents via MCP servers. A source is any input that describes available functionality, such as:

  • Gram Functions (Node.js), and
  • OpenAPI documents.

These sources can be uploaded to Gram via the web UI, or using the Gram CLI. Once uploaded, a deployment creates tool definitions. These tools can then be curated into toolsets, which are organized collections tailored to specific use cases or workflows. Each toolset is exposed as an MCP server, which can be installed into LLM clients for automated usage.

Gram Functions

Gram Functions are snippets of code written in TypeScript that enable you to define arbitrary tasks for AI agents to execute via MCP servers. Unlike OpenAPI-based tools that map to existing REST API endpoints, Gram Functions can call multiple APIs, connect to remote databases over TCP/HTTP, and perform complex data transformations with third-party libraries.

Functions are particularly useful when:

  • You need to perform calculations, data transformations, or complex business logic that doesn’t map to a single API endpoint.
  • You want to orchestrate multiple API calls within a single tool to create workflow-based operations.
  • You need to integrate third-party services or databases that don’t have OpenAPI documents.
  • You want to implement conditional logic, iteration, or other control flow that can’t be expressed in a declarative API specification.

Basic Structure

At its core, a Gram Function is a zip file containing two files:

manifest.json - A metadata file describing your tools:

The manifest includes each tool’s name, description, JSON Schema for input validation, and any required environment variables.

functions.js - A bundled JavaScript file that exports a handleToolCall function:

When you upload this zip file to Gram, the platform uses the manifest to expose your tools and invokes handleToolCall to execute them.

Environment Variables

Environment variables defined in your Gram project can be accessed within functions using the process.env object. For example, if you define an environment variable named MY_MCP_MULTIPLIER, you can access it in a function like this:

Using the SDK

While you can manually create these files, the @gram-ai/functions TypeScript framework simplifies the entire workflow. The SDK handles manifest generation, bundling, input validation, and packaging automatically.

To create a new function project using the SDK, use the scaffolding tool:

Here’s a basic example using the SDK:

The SDK automatically generates the manifest and bundles your code when you run pnpm build.

For more details on using the SDK to create and deploy Gram Functions, check out the framework’s GitHub Repository .

OpenAPI Documents

OpenAPI documents describe the functionality of REST APIs in a standardized format known as the OpenAPI Specification. These files are widely used to generate API documentation, SDKs, and client libraries. Similarly, Gram leverages OpenAPI documents to generate tools that enable LLMs to interact with REST APIs. OpenAPI-sourced tools are especially useful when:

  • You want to make it easy for end-users to leverage your REST API via AI agents.
  • You want to automate workflows that involve multiple API calls.
  • You want to enhance LLMs with real-time data and functionality from your API.

Though most users upload these documents for their own REST APIs, tools may be generated using an OpenAPI document for any API. Some examples of public APIs that have OpenAPI documents include:

API
Asana
OpenAPI Document
GitHub REST API
National Weather Service

Optimizing OpenAPI Documents

Because Gram generates tools directly from endpoint descriptions in your OpenAPI document, it’s essential that those descriptions are accurate and informative. However, writing descriptions that serve both humans and LLMs can be challenging.

Short descriptions may be readable for humans, but LLMs often require more context to interpret intent and usage correctly. To bridge this gap, Gram supports the x-gram extension in OpenAPI documents, allowing you to provide LLM-optimized metadata specifically for tool generation and usage.

Without the x-gram extension, the generated tool would be named ecommerce_e_commerce_v1_product, and have the description "Get a product by its ID", resulting in a poor quality tool. The x-gram extension allows you to customize a tool’s name and description without altering the original information in the OpenAPI document.

The x-gram extension also supports response filtering through the responseFilterType property, which helps LLMs process API responses more effectively.

Using the x-gram extension is optional. With Gram’s tool variations feature, you can modify a tool’s name and description when curating tools into toolsets. However, it might be worth using the x-gram extension to make your OpenAPI document clean, descriptive, and LLM-ready before bringing it into Gram, so your team doesn’t need to fix tool names and descriptions later.

Limitations of OpenAPI 3.0.x

Many LLMs don’t support the JSON Schema version used in OpenAPI 3.0.x documents. When these documents are uploaded to Gram, they are transparently upgraded to 3.1.0 using the steps defined in Migrating from OpenAPI 3.0 to 3.1.0 . When this happens you might notice that line numbers no longer match the original OpenAPI document. It’s recommended to upgrade your OpenAPI documents to 3.1.x to have a more streamlined experience.

Last updated on