Skip to content

Commit 5e37b19

Browse files
committed
Merge remote-tracking branch 'upstream/updates/screenshots-nov-2025-resolved' into updates/screenshots-nov-2025
2 parents 0e20f05 + 6cfdc9d commit 5e37b19

File tree

8 files changed

+149
-56
lines changed

8 files changed

+149
-56
lines changed

api-design/security.md

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description: "Implement robust security measures in your API to protect sensitiv
88
Creating an API is like opening a door to the outside world. Who is allowed
99
through, what they can carry, and where they're allowed to go is incredibly
1010
important. In this guide we'll see how design choices made early on impact the
11-
security of an API once it's built.
11+
security of an API once it's built.
1212

1313
Many API security problems come down to coding errors or misconfigured
1414
infrastructure, but this guide focuses more on the foundational API design
@@ -48,10 +48,10 @@ decisions can make or break an API's defenses before it's even built.
4848
**Every API consumer should only have access to what they need and nothing more.**
4949

5050
Imagine designing an API for an e-commerce platform. A customer should be
51-
able to view their order history, but not other customers' orders.
51+
able to view their order history, but not other customers' orders.
5252

5353
Similarly, a "staff" user might need access to refund functionality but shouldn't
54-
necessarily see sensitive payment details.
54+
necessarily see sensitive payment details.
5555

5656
**What Could Go Wrong**: Failure to verify this could lead
5757
to Insecure Direct Object References (IDOR), a common flaw where attackers can
@@ -67,7 +67,7 @@ Authorization: Bearer {access_token}
6767
```
6868

6969
The application should verify that the `orderId` belongs to the authenticated
70-
user, unless the user has a role like `admin`.
70+
user, unless the user has a role like `admin`.
7171

7272
Refund logic and payment details can be split onto their own endpoints:
7373

@@ -83,7 +83,7 @@ Authorization: Bearer {admin_access_token}
8383

8484
This allows staff handle refunds, but does not leak sensitive credit card
8585
information to as many people within the company, whilst still making it
86-
possible to escalate customer problems to a higher access user.
86+
possible to escalate customer problems to a higher access user.
8787

8888
Better yet, **the payments collection is not even on the API**, it's something only
8989
viewable in an admin backend system thats protected with a firewall and VPN.
@@ -94,17 +94,17 @@ viewable in an admin backend system thats protected with a firewall and VPN.
9494
"private".**
9595

9696
Any incoming API traffic could be compromised in some way, even if it's
97-
considered to be a trusted source.
97+
considered to be a trusted source.
9898

9999
An API could suddenly become public: either intentionally when infrastructure
100100
teams move things around, or accidentally when somebody de-compiles an iOS
101-
application or sniffs traffic to find an API that people thought was hidden.
101+
application or sniffs traffic to find an API that people thought was hidden.
102102

103103
Even if an API is firewalled off from public traffic, another API or service
104104
could have been hacked giving them access to the protected API.
105105

106106
It's best to treat everyone with suspicion, and validate all inputs as strictly
107-
as possible.
107+
as possible.
108108

109109
**What Could Go Wrong**: Malicious data could be introduced, or private
110110
information leaked, leading to any number of issues. People could delete invoice
@@ -113,13 +113,13 @@ wrong person. They could change passwords for users so they can log in as them
113113
to access information and processes not even available in the API.
114114

115115
**Design Decision**: Set strict rules for which properties are editable, which
116-
can be returned, and set strict validation rules for these properties.
116+
can be returned, and set strict validation rules for these properties.
117117

118118
This can be described in OpenAPI early on utilizing `readOnly`, `writeOnly`,
119119
`required`, setting `additionalProperties: false`. [Learn more about
120-
additionalProperties](https://www.speakeasy.com/guides/openapi/additionalproperties).
120+
additionalProperties](https://www.speakeasy.com/docs/sdks/customize/data-model/additionalproperties).
121121
This means when the API is developed the OpenAPI can be used for integration
122-
testing to poke and prod to see if extra properties can sneak though.
122+
testing to poke and prod to see if extra properties can sneak though.
123123

124124
Comical examples of this was somebody hacking GitHub and Rails to update the
125125
`created_at` date to have the year 3012. This attack is known as Bender from the
@@ -153,7 +153,7 @@ Authorization: Bearer my-secret-key
153153

154154
Using `Authorization` has the added benefit over generic custom headers like
155155
`X-API-Key` because it will alert HTTP caching tools to not reuse this response
156-
for other users by default.
156+
for other users by default.
157157

158158
This is not simply about authorization though, there are lots of other
159159
"sensitive" things which should not go into the URL. Email addresses, social
@@ -168,7 +168,7 @@ we're all looking for.
168168
## Principle #4: Limit one-time URLs
169169

170170
Logins and file uploads often involve allowing a user to pass in a URL, which
171-
will then be downloaded or redirected to.
171+
will then be downloaded or redirected to.
172172

173173
```http
174174
POST /products/{productId}/images
@@ -221,7 +221,7 @@ business might not want to expose, or allow outright theft of an entire dataset.
221221

222222
A startup tracking street art around the world (think Banksy, Bragga, and
223223
smaller artists) built an amazing unique database of user-generated photographs
224-
and locations of all sorts of graffiti, sculptures, installations, etc.
224+
and locations of all sorts of graffiti, sculptures, installations, etc.
225225

226226
This data was not available anywhere else on the Internet, but their website
227227
relied on two API endpoints:
@@ -240,10 +240,11 @@ number of how many active users versus inactive users, leaking a "churn rate"
240240
which could be embarrassing in the press of scare off investors.
241241

242242
Using the same approach a client can hit `GET /artworks/1` and loop through with `id
243-
+ 1` to grab a hold of all that data, which helped that company populate their
244-
own database, making a new competitor quite easily, and with a slightly better
245-
app as they didn't have to spend time or money building the dataset in the first
246-
place. This put the original startup out of business.
243+
244+
- 1` to grab a hold of all that data, which helped that company populate their
245+
own database, making a new competitor quite easily, and with a slightly better
246+
app as they didn't have to spend time or money building the dataset in the first
247+
place. This put the original startup out of business.
247248

248249
**Design Decision**: There are non-incremental or "hard to guess" system of
249250
identifiers instead. Standards like
@@ -282,7 +283,7 @@ thresholds for various user roles:
282283
- Paid users: 1,000 requests per hour
283284

284285
Communicate these limits clearly in API documentation and return appropriate
285-
status codes like `429 Too Many Requests` when limits are exceeded.
286+
status codes like `429 Too Many Requests` when limits are exceeded.
286287

287288
Learn more about [rate limiting](/api-design/rate-limiting).
288289

@@ -317,7 +318,7 @@ keeping up to date with new editions when they're released.
317318
## Tooling
318319

319320
Much of this advice and more can be applied to an OpenAPI automatically to help
320-
whole teams make good decisions early on in the API design process.
321+
whole teams make good decisions early on in the API design process.
321322

322323
- [Vacuum](https://quobix.com/vacuum/) via the built in [OWASP Ruleset](https://quobix.com/vacuum/rules/owasp/).
323324
- [Spectral](https://github.com/stoplightio/spectral) with the [Spectral OWASP Ruleset](https://github.com/stoplightio/spectral-owasp-ruleset).
@@ -330,10 +331,10 @@ many of the pitfalls outlined here and in the OWASP API Security Top 10 can be a
330331

331332
Remember, every design decision is a trade-off. Security measures often add
332333
complexity or impact usability. The goal is to strike the right balance,
333-
keeping the needs of both API consumers and the business in mind.
334+
keeping the needs of both API consumers and the business in mind.
334335

335336
There's no need to go to massive massive and intrusive lengths to secure
336337
information that is fine out in the public, but it is important to establish
337-
good practices for limiting interactions for more sensitive data.
338+
good practices for limiting interactions for more sensitive data.
338339

339340
Maybe this means creating more than one API.

docs/gram/build-mcp/dynamic-toolsets.mdx

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,54 +5,73 @@ description: Enable very large MCP servers by making a toolset dynamic
55

66
import { Callout } from "@/mdx/components";
77

8-
Dynamic toolsets enable very large MCP servers without overloading context windows. Instead of exposing all tools upfront like traditional MCP, dynamic toolsets provide "meta" tools that allow the LLM to discover only the tools it needs to complete specific tasks, optimizing token and context management.
8+
Dynamic toolsets enable very large MCP servers without overloading context windows. Instead of exposing all tools upfront like traditional MCP, dynamic toolsets provide "meta" tools that allow the LLM to discover only the tools it needs to complete specific tasks, delivering up to 160x token reduction while maintaining full functionality.
99

10-
Gram exposes two types of dynamic toolsets, both of which are experimental:
10+
Our refined Dynamic Toolsets approach combines the best of semantic search and progressive discovery into a unified system that exposes three core tools. For detailed technical insights and performance benchmarks, see our [blog post on how we reduced token usage by 100x](/blog/how-we-reduced-token-usage-by-100x-dynamic-toolsets-v2).
1111

12-
## Progressive Search
12+
## How Dynamic Toolsets work
1313

14-
Progressive Search uses a "progressive discovery" approach to surface tools. Tools are organized into groups that the LLM can inspect to gradually discover what tools are available to it. Details of tools are only exposed when needed, for example tool schemas (which represent a large portion of tool token use) are only surfaced when the LLM decides it actually wants to use a specific tool. The toolset is compressed into three tools that actually get exposed directly to the LLM:
14+
Dynamic toolsets follow the natural workflow an LLM needs: search → describe → execute. The system compresses large toolsets into three meta-tools:
1515

16-
### `list_tools`
16+
### `search_tools`
1717

18-
The LLM can discover available tools using prefix-based lookup (e.g., `list_tools(/hubspot/deals/*)`). This process is accelerated by providing the structure of available tools in the tool description, creating a hierarchy of available sources and tags. This allows the LLM full control over what tools it discovers and when.
18+
The LLM searches for relevant tools using natural language queries with embeddings-based semantic search. The tool description includes categorical overviews of available tools (e.g., "This toolset includes HubSpot CRM operations, deal management...") and supports filtering by tags like `source:hubspot` for precise discovery.
1919

2020
### `describe_tools`
2121

22-
The LLM can look up detailed information about specific tools, including input schemas. While this could be combined with `list_tools`, the input schemas represent a significant portion of tokens, so keeping them separate optimizes token and context management at the cost of speed.
22+
The LLM requests detailed schemas and documentation only for tools it intends to use. This separation optimizes token usage since input schemas represent 60-80% of total tokens in static toolsets.
2323

2424
### `execute_tool`
2525

26-
Execute the discovered and described tools as needed for the specific task.
26+
The LLM executes discovered and described tools with proper parameters.
2727

28-
## Semantic Search
28+
## Performance benefits
2929

30-
Semantic Search provides an embeddings-based approach to tool discovery. Embeddings are created in advance for all the tools in a toolset, then searched over to find relevant tools for a given task.
30+
Dynamic toolsets deliver significant advantages over static toolsets:
3131

32-
### `find_tools`
32+
**Massive token reduction**: Input tokens are reduced by an average of 96% for simple tasks and 91% for complex tasks, with total token usage dropping by 96% and 90% respectively.
3333

34-
The LLM can execute semantic search over embeddings created from all tools in the toolset, allowing for more intuitive tool discovery based on natural language descriptions of what it wants to accomplish. This is generally faster than Progressive Search especially for large toolsets, but has less complete coverage and may result in worse discovery. The LLM has no insight into what tools are available broadly and can only operate off of whatever the semantic search returns.
34+
**Consistent scaling**: Token usage remains relatively constant regardless of toolset size. A 400-tool dynamic toolset uses only ~8,000 tokens initially compared to 410,000+ for the same static toolset.
3535

36-
### `execute_tool`
36+
**Context window compatibility**: Large toolsets that exceed Claude's 200k context window limit with static approaches work seamlessly with dynamic toolsets.
37+
38+
**Perfect reliability**: Maintains 100% success rates across all toolset sizes and task complexities.
39+
40+
### Sample performance data
41+
42+
| Toolset Size | Mode | Simple Task Tokens | Tool Calls | Complex Task Tokens | Tool Calls |
43+
|-------------|------|-------------------|------------|-------------------|------------|
44+
| 100 tools | Static | 159,218 | 1 | 159,216 | 3 |
45+
| 100 tools | Dynamic | 8,401 | 3 | 18,095 | 7 |
46+
| 400 tools | Static | 410,738 | 1 | 410,661 | 3 |
47+
| 400 tools | Dynamic | 8,421 | 3 | 31,355 | 7.8 |
48+
49+
## Trade-offs
3750

38-
Execute the tools found through semantic search.
51+
While dynamic toolsets offer significant benefits, there are some considerations:
3952

40-
## Benefits
53+
**Increased tool calls**: Dynamic toolsets require 2-3x more tool calls (typically 6-8 for complex tasks vs 3 for static), following the search → describe → execute pattern.
4154

42-
Both dynamic toolset approaches share the same core benefit: they avoid dumping all tools into context upfront. Instead, they expose the LLM to only the tools actually needed for a given task, making it possible to work with very large toolsets while maintaining efficient context usage.
55+
**Potential latency**: Additional tool calls may introduce slight latency, though this is often offset by reduced token processing time.
4356

44-
This approach is particularly valuable when working with extensive APIs or large collections of tools where loading everything at once would exceed context limits or create unnecessary complexity.
57+
**Complexity**: The multi-step discovery process adds complexity compared to direct tool access, though this is handled automatically by the LLM.
4558

4659
## Enabling dynamic toolsets
4760

48-
Head to the `MCP` tab to switch your toolset to one of the above dynamic modes.
61+
Head to the **MCP** tab in your Gram dashboard and switch your toolset from "Static" to "Dynamic" mode.
4962

5063
<Callout title="Note" type="info">
51-
This setting only applies to MCP, and will not affect how your toolset is used in the playground.
64+
This setting only applies to MCP and will not affect how your toolset is used in the playground, where static tool exposure remains useful for testing and development.
5265
</Callout>
5366

54-
![enabling dynamic toolsets](/assets/docs/gram/img/dashboard/tool-selection-mode.png)
67+
Dynamic toolsets are particularly valuable for:
68+
- APIs with 100+ operations
69+
- Enterprise systems with comprehensive toolsets
70+
- Applications where context window limits are a concern
71+
- Production environments requiring predictable costs
5572

5673
## Additional reading
5774

75+
- [How we reduced token usage by 100x with Dynamic Toolsets](/blog/how-we-reduced-token-usage-by-100x-dynamic-toolsets-v2)
5876
- [Code Execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp)
77+
- [Previous Dynamic Toolsets implementation](/blog/100x-token-reduction-dynamic-toolsets)

docs/gram/clients/using-claude-code-with-gram-mcp-servers.mdx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,19 @@ gram install claude-code --toolset taskmaster
5555
This command automatically:
5656
- Fetches your toolset configuration from Gram
5757
- Derives the MCP URL and authentication settings
58-
- Creates the correct configuration (by default in user-level `~/.claude/settings.local.json`)
58+
- Creates the correct configuration (by default in user-level `~/.claude.json`)
5959

60-
**Configuration Scopes:**
60+
#### Setting up environment variables
61+
62+
If your toolset requires authentication, you'll need to set up environment variables. The `gram install` command will display the required variable names and provide the export command you need to run to set the variable value.
63+
64+
For the Taskmaster toolset, you'll need to set the `MCP_TASK_MASTER_API_KEY` environment variable to your Taskmaster API key. You can do this by running the following command:
65+
66+
```bash
67+
export MCP_TASK_MASTER_API_KEY='your-api-key-value'
68+
```
69+
70+
#### Configuration Scopes
6171

6272
You can control where the MCP server configuration is installed using the `--scope` flag:
6373

@@ -211,4 +221,3 @@ If Claude Code isn't calling the tools:
211221
You now have Claude Code connected to a Gram-hosted MCP server with task management capabilities.
212222

213223
Ready to build your own MCP server? [Try Gram today](/product/gram) and see how easy it is to turn any API into agent-ready tools.
214-

docs/gram/concepts/environments.mdx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,3 @@ On the environment page, add environment variables by clicking **New Variable**.
2525
Attach an environment to a toolset by clicking the **Fill for toolset** button, then selecting the specific toolset you want to configure. This allows you to pre-fill all required environment variables for that toolset, ensuring it's ready to use across the Playground, SDKs, and MCP clients.
2626

2727
![Attaching an environment to a toolset](/assets/docs/gram/img/concepts/environments/attaching-an-environment-to-a-toolset.png)
28-
29-
<div className="flex justify-center">
30-
<video controls muted={true}>
31-
<source src="/assets/docs/gram/videos/environments.mp4" type="video/mp4" />
32-
Your browser does not support the video tag.
33-
</video>
34-
</div>

docs/gram/concepts/tool-variations.md renamed to docs/gram/concepts/tool-variations.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ Similarly, to edit a tool's description, click the 3 dots and select **Edit desc
3232
src="/assets/docs/gram/videos/tool-variations/editing-tool-description.mp4"
3333
type="video/mp4"
3434
/>
35-
</video>
35+
</video>

0 commit comments

Comments
 (0)