budget

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package budget provides MCP response budget enforcement utilities.

MCP tool servers commonly need to keep list-style responses within a model-context-friendly token budget. This package wraps results in an Envelope with pagination and truncation metadata, and provides small helpers for extracting paging arguments from untyped MCP parameter maps and rendering MCP tool-response JSON.

The defaults target ~2000 tokens (~8000 bytes of serialized JSON), a reasonable starting point for tool responses consumed inline by an LLM. Callers override the limits via Config.

The package is dependency-free (stdlib only).

Index

Examples

Constants

View Source
const (
	// DefaultLimit is the default number of items returned in a list response.
	DefaultLimit = 10
	// MaxLimit is the maximum number of items a caller can request.
	MaxLimit = 25
	// DefaultMaxTokens is the target token budget for a single response (~2000 tokens).
	DefaultMaxTokens = 2000
	// DefaultMaxBytes is the target byte budget for a single response (~8000 bytes).
	DefaultMaxBytes = 8000
)

Variables

This section is empty.

Functions

func Clamp

func Clamp(v, min, max int) int

Clamp bounds v between min and max (inclusive).

func EstimateTokens

func EstimateTokens(payload []byte) int

EstimateTokens approximates the token count from a byte payload. It uses a conservative ~4 characters per token heuristic, which is reasonable for JSON payloads where punctuation and short keys dominate.

func EstimateTokensFromString

func EstimateTokensFromString(s string) int

EstimateTokensFromString is a convenience wrapper around EstimateTokens.

func ExtractLimit

func ExtractLimit(params map[string]any, defaultVal int) int

ExtractLimit gets the "limit" parameter from a map, clamped between 1 and MaxLimit. If the key is missing or not a valid number, defaultVal is returned (itself clamped).

func ExtractPagination

func ExtractPagination(params map[string]any) (limit, offset int)

ExtractPagination gets limit and offset from a params map. Limit is clamped to [1, MaxLimit] and offset is clamped to [0, max int]. Missing keys use DefaultLimit and 0 respectively.

Example
limit, offset := ExtractPagination(map[string]any{
	"limit":  7,
	"offset": 3,
})

fmt.Printf("%d %d\n", limit, offset)
Output:
7 3

func ToolError

func ToolError(code, message string) string

ToolError returns a JSON error response string with the given code and message. Callers wrap this in their MCP framework's error response type.

func ToolJSON

func ToolJSON(v any) string

ToolJSON marshals v to a JSON string suitable for MCP tool responses. On marshal failure it returns a JSON error object.

Example
env := Envelope{
	Items:     []string{"alpha"},
	Count:     1,
	Total:     1,
	Truncated: false,
}

fmt.Println(ToolJSON(env))
Output:
{"items":["alpha"],"count":1,"total":1}

Types

type Config

type Config struct {
	Limit     int // max items to include (default DefaultLimit, max MaxLimit)
	MaxBytes  int // max response bytes (default DefaultMaxBytes)
	MaxTokens int // max estimated tokens (default DefaultMaxTokens)
}

Config holds budget parameters for a response.

type Envelope

type Envelope struct {
	Items     any    `json:"items"`
	Count     int    `json:"count"`               // items in this response
	Total     int    `json:"total,omitempty"`     // total available (before truncation)
	Truncated bool   `json:"truncated,omitempty"` // true if items were omitted
	Hint      string `json:"hint,omitempty"`      // progressive disclosure hint
}

Envelope wraps list responses with pagination and truncation metadata. Callers serialize this to JSON via ToolJSON and return the resulting string in their MCP framework's response type.

func Apply

func Apply[T any](items []T, cfg Config, hintTemplate string) Envelope

Apply takes a slice of items and a hint template, and returns an Envelope that respects the budget config. Items beyond the limit are counted but not included in the response. The hintTemplate is a format string that receives the total count as its first %d argument (e.g., "%d tasks found. Use task_get for details.").

If hintTemplate is empty and the response is truncated, a generic hint is used.

Example
items := []string{"alpha", "beta", "gamma"}
env := Apply(items, Config{Limit: 2}, "%d items available. Add filters to narrow results.")

fmt.Printf("%d %d %t %s\n", env.Count, env.Total, env.Truncated, env.Hint)
Output:
2 3 true 3 items available. Add filters to narrow results.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL