Skip to content

Commit 0dad5d6

Browse files
committed
Sync open source content 🐝 (from d9c61d3e8b46cac17a711c97c1b4f95565a1bdd9)
1 parent 1bf06a5 commit 0dad5d6

File tree

4 files changed

+152
-30
lines changed

4 files changed

+152
-30
lines changed

docs/gram/gram-functions/build-deploy.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ This will compile your tools into a zip file that can be deployed to Gram.
2525

2626
## Deploy
2727

28-
To deploy yout tools to Gram, run the following command:
28+
To deploy your tools to Gram, run the following command:
2929

3030
```bash
3131
npm run push

docs/gram/gram-functions/functions-framework.mdx

Lines changed: 123 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,41 +29,148 @@ const gram = new Gram().tool({
2929
export default gram;
3030
```
3131

32-
## Environment Variables
32+
## Tool definition
3333

34-
With Gram functions you can specify credentials or envrionment variable values that will need to be provided to your tool runner.
35-
These can be provided either by end user set MCP headers or with stored Gram environments.
34+
Each tool requires the following properties:
35+
36+
- **name**: Unique identifier for the tool
37+
- **description** (optional): Human-readable explanation of what the tool does
38+
- **inputSchema**: Zod schema defining the expected input parameters
39+
- **execute**: Async function that implements the tool logic
40+
41+
## Context object
42+
43+
The execute function receives a context object with several helper methods for handling responses and accessing configuration:
44+
45+
### Response methods
46+
47+
- **ctx.json(data)**: Returns a JSON response
48+
- **ctx.text(data)**: Returns a plain text response
49+
- **ctx.html(data)**: Returns an HTML response
50+
- **ctx.fail(data, options?)**: Throws an error response
51+
52+
```typescript
53+
const gram = new Gram().tool({
54+
name: "format_data",
55+
inputSchema: { format: z.enum(["json", "text", "html"]), data: z.string() },
56+
async execute(ctx, input) {
57+
if (input.format === "json") {
58+
return ctx.json({ data: input.data });
59+
} else if (input.format === "text") {
60+
return ctx.text(input.data);
61+
} else {
62+
return ctx.html(`<div>${input.data}</div>`);
63+
}
64+
},
65+
});
66+
```
67+
68+
### Additional context properties
69+
70+
- **ctx.signal**: AbortSignal for handling cancellation
71+
- **ctx.env**: Access to parsed environment variables
72+
73+
```typescript
74+
const gram = new Gram().tool({
75+
name: "long_running_task",
76+
inputSchema: { url: z.string() },
77+
async execute(ctx, input) {
78+
try {
79+
const response = await fetch(input.url, { signal: ctx.signal });
80+
return ctx.json(await response.json());
81+
} catch (error) {
82+
if (error.name === "AbortError") {
83+
return ctx.fail("Request was cancelled");
84+
}
85+
throw error;
86+
}
87+
},
88+
});
89+
```
90+
91+
## Input validation
92+
93+
The framework validates inputs against the provided Zod schema by default. For strict validation, inputs that don't match the schema will be rejected.
94+
95+
### Lax mode
96+
97+
To allow unvalidated inputs, enable lax mode:
98+
99+
```typescript
100+
const gram = new Gram({ lax: true }).tool({
101+
name: "flexible_tool",
102+
inputSchema: { required: z.string() },
103+
async execute(ctx, input) {
104+
// input may contain additional properties not in the schema
105+
return ctx.json({ received: input });
106+
},
107+
});
108+
```
109+
110+
## Environment variables
111+
112+
Specify credentials or environment variable values that need to be provided to the tool runner. These can be provided either by end user set MCP headers or with stored Gram environments.
36113

37114
```typescript
38115
const gram = new Gram({
39116
envSchema: {
40-
BASE_URL: z.string().check(z.url()),
117+
API_KEY: z.string().describe("API key for authentication"),
118+
BASE_URL: z.string().url().describe("Base URL for API requests"),
41119
},
42120
}).tool({
43121
name: "api_call",
44122
inputSchema: { endpoint: z.string() },
45123
async execute(ctx, input) {
124+
const apiKey = ctx.env?.["API_KEY"];
46125
const baseURL = ctx.env?.["BASE_URL"];
47-
// Use baseURL...
126+
127+
const response = await fetch(`${baseURL}${input.endpoint}`, {
128+
headers: { Authorization: `Bearer ${apiKey}` },
129+
});
130+
131+
return ctx.json(await response.json());
132+
},
133+
});
134+
```
135+
136+
For testing purposes, environment variables can be overridden via the `env` parameter. Otherwise, they default to `process.env`.
137+
138+
## Using fetch
139+
140+
Tools can make requests to downstream APIs and respond with the result:
141+
142+
```typescript
143+
const gram = new Gram().tool({
144+
name: "spacex-ships",
145+
description: "Get the latest SpaceX ship list",
146+
inputSchema: {},
147+
async execute(ctx) {
148+
const response = await fetch("https://api.spacexdata.com/v3/ships");
149+
return ctx.json(await response.json());
48150
},
49151
});
50152
```
51153

154+
## Response flexibility
52155

53-
## Using Fetch
156+
Tools can return responses in multiple formats:
54157

55-
With Gram functions you can make requests to downstream APIs and respond with the result.
158+
- JSON responses via `ctx.json()`
159+
- Plain text via `ctx.text()`
160+
- HTML content via `ctx.html()`
161+
- Custom Web API Response objects with specific headers and status codes
56162

57163
```typescript
58-
const gram = new Gram()
59-
.tool({
60-
name: "spacex-ships",
61-
description: "Get the latest SpaceX ship list",
62-
inputSchema: {},
63-
async execute(ctx) {
64-
return fetch("https://api.spacexdata.com/v3/ships");
65-
},
66-
});
164+
const gram = new Gram().tool({
165+
name: "custom_response",
166+
inputSchema: { code: z.number() },
167+
async execute(ctx, input) {
168+
return new Response("Custom response", {
169+
status: input.code,
170+
headers: { "X-Custom-Header": "value" },
171+
});
172+
},
173+
});
67174
```
68175

69176
## Next steps

docs/gram/gram-functions/introduction.mdx

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ title: "Gram Functions"
33
description: "Build custom tools with TypeScript functions for complete control over logic and dependencies."
44
---
55

6-
Gram Functions allow you to create tools from TypeScript code.
7-
Once deployed, they can be used just like any other tool in the Gram platform, allowing you to create and host MCP servers,
8-
combine them with other tools into toolsets, build multi-tool workflows, and more.
6+
Gram Functions are compact code units that represent LLM tools. They allow you to create tools from TypeScript code that can be deployed to Gram and exposed to language models via MCP servers. Once deployed, they can be used just like any other tool in the Gram platform, allowing you to create and host MCP servers, combine them with other tools into toolsets, build multi-tool workflows, and more.
97

108
```typescript filename="gram.ts"
119
import { Gram } from "@gram-ai/functions";
@@ -25,12 +23,20 @@ export default gram;
2523

2624
## Getting started
2725

28-
To get started with Gram Functions, follow the [Getting Started](/docs/gram/getting-started/typescript) guide.
26+
To get started with Gram Functions, scaffold a new project using the Gram template:
2927

3028
```bash
31-
npm create @gram-ai/function
29+
pnpm create @gram-ai/function@latest --template gram
3230
```
3331

32+
Install the required package:
33+
34+
```bash
35+
pnpm add @gram-ai/functions
36+
```
37+
38+
For a complete walkthrough, follow the [Getting Started](/docs/gram/getting-started/typescript) guide.
39+
3440
## Writing tools
3541

3642
Gram Functions can be written using the [Gram Functions Framework](/docs/gram/gram-functions/functions-framework) or the official [MCP SDK](/docs/gram/gram-functions/mcp-sdk).
@@ -63,12 +69,22 @@ npm run build
6369
npm run push
6470
```
6571

66-
## Functions vs. MCP Servers
72+
## Functions vs. MCP servers
73+
74+
Gram Functions are a way to create individual tools that can be used in MCP servers. However, creating tools in Gram is not the same as creating MCP servers.
75+
76+
The key distinction:
77+
78+
- **Functions**: Individual tools that represent specific capabilities or operations
79+
- **MCP Servers**: Collections of tools combined into a single server that can be accessed by LLM clients
80+
81+
Once you have created a tool (via Functions or OpenAPI), combine it with other tools into one or many MCP servers. This means you can:
82+
83+
- Split your Gram functions into multiple projects for convenience
84+
- Keep every tool in one file
85+
- Organize tools however makes sense for your workflow
6786

68-
Gram Functions are a great way to create tools that can be used in MCP servers.
69-
However, creating tools in Gram is not the same as creating MCP servers. Once you have created a tool (via Functions or OpenAPI), you can combine it with other tools into one (or many) MCP servers.
70-
You can therefore split your Gram functions into multiple projects for convenience, or keep every tool in one file. MCP servers will be created from [toolsets](/docs/gram/concepts/toolsets) later in the Gram dashboard.
71-
However, they are not the only way to create tools. You can also directly from OpenAPI documents.
87+
MCP servers are created from [toolsets](/docs/gram/concepts/toolsets) later in the Gram dashboard. Tools can also be created directly from OpenAPI documents.
7288

7389
### Local development
7490

docs/gram/gram-functions/mcp-sdk.mdx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,9 @@ server.registerResource(
8585
After running `push` simply select that resource to add it to a toolset.
8686
![Adding a Resource](/assets/docs/gram/img/functions/adding-resources.png)
8787

88-
## Environment Variables
88+
## Environment variables
8989

90-
You can specify credentials or envrionment variable values that will need to be made available in your tool runner envrionment.
91-
These can be provided either by end user set MCP headers or with stored Gram environments.
90+
Specify credentials or environment variable values that need to be made available in your tool runner environment. These can be provided either by end user set MCP headers or with stored Gram environments.
9291

9392
```typescript filename="gram.ts"
9493
import { withGram } from "@gram-ai/functions/mcp";

0 commit comments

Comments
 (0)