# Tool frugality

Shared policy for data-pulling skills. Tool responses are the biggest context cost in these skills. Ask for what you'll use; don't bulk-pull and skim.

Named operations below (`jira_search`, `get_communications`, …) are top-level tools on interactive `/mcp/full`. Call them directly; existing facade calls remain supported.

## Owned tools now return compact by default

`jira_search`, `google_calendar_events`, `confluence_search`, and `confluence_get_page` project down to the fields the model actually reads. You get the lean shape automatically.

- `jira_search`: each issue is `{ key, fields: { ... } }` with `status`/`priority` as names, `assignee` as a display name, custom fields preserved. No `self`, `iconUrl`, `expand`, or `statusCategory` wrapper.
- `google_calendar_events`: each event is summary, start/end, attendees as `{email, responseStatus}`, organizer, description, attachment links, and one `conferenceJoinUrl`. No `conferenceData` block, HTML `notes`, `etag`, or `reminders`.
- `confluence_*`: HATEOAS addressing (`_links`, `_expandable`) stripped; body and content kept.

Pass `verbosity: "full"` only when you genuinely need the raw upstream payload (an export you'll summarize later, or debugging a missing field). Default is compact. Don't reach for `full` out of habit.

## Kepler comms (`list_communications`, `get_communications`, `semantic_context_search`)

Kepler is a passthrough; its responses are not reshaped here, so frugality is on you.

- **`get_communications` returns `body` and `transcript` as identical strings.** Read one, never both. Set `content_max_chars` (~6000) unless you are deliberately pulling a full transcript you will quote at length.
- **Hydrate only what you'll cite.** Pull the call/email list first, pick the handful you'll actually reference, then `get_communications` those by id. Do not full-fetch every item in the window.
- **`list_communications` is for discovery + preview scanning.** Bound `limit` to what you need (~15-20). Pulling 50 to cite 3 burns the window for nothing.
- **`semantic_context_search`**: bound `max_cards` (~5-8) and `snippet_chars` (~300-500). Use the returned source ids to hydrate, rather than asking for everything inline.

## Jira

Still pass explicit `fields` and a bounded `maxResults` (~20). Compact output trims the per-issue noise; you control how many issues and which fields.

## Granola

Start with `granola_list_meetings` for active-workspace meeting IDs, titles, dates, and attendees. Hydrate only selected IDs with `granola_get_meetings` (up to 10). Use `granola_get_meeting_transcript` only when exact wording matters. `query_granola_meetings` is for open-ended synthesis. Use `granola_list_notes` / `granola_get_notes` only when the active workspace misses evidence and explicit cross-workspace API-key coverage is required.

## Slack reads

Use `slack_find_conversations` for "messages/thread/channel with these people." Pass every known person in one `people` array; one person uses the same path. It resolves identities, checks DMs and group DMs before channels, uses recent authorship to discard generic channel co-membership, runs the in-process mini navigator over candidate metadata and snippets, hydrates the selected groups, and returns coverage in one call. If identity is ambiguous, repeat once with the returned user ID. Do not recreate this with `slack_users` + search guesses + unread snapshots + channel reads.

Use `slack_search`, `slack_read_channel`, and `slack_read_thread` for literal query or known-ID reads. `slack_channels(action=unreads)` is an unread snapshot, not targeted history. Bound result counts and stop paging once the requested evidence is present.

## Routing cost

Round-trips are context cost too: each one re-reads the whole prompt prefix. On interactive `/mcp/full`, call known named tools immediately and repair from returned argument errors. Tool schemas are already present in `tools/list`. Full routing rules: `compact-mcp-routing.md`.
