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.
Note
Gram Functions support TypeScript as well as JavaScript.
Bundle Size Limit
The zipped bundle (containing both manifest.json
and functions.js
) must not
exceed 700KB. Keep your functions lean by avoiding large dependencies and
using tree-shaking when bundling. For many use cases, this provides a lot of
headroom, especially when using the highest zip compression:
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:
Note
Gram works best with documents using OpenAPI
3.1.x
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
OpenAPI Resources
If you are looking for more information on how to write, understand and manage OpenAPI documents we recommend checking out our OpenAPI documentation.
We also provide a comprehensive OpenAPI Editor and CLI that help you edit, save and lint OpenAPI documents. You can login here
Last updated on