Buff Development
Connector

Tools and the model

How an integration’s tools reach the model, why writing ones never do and where this is visible.

An integration declares tools — what the model can call in your system: find issues, read a ticket, get a pull request diff. This page is about how they reach the model and what limits them.

The connector registers them, not you

Nothing needs to be set up. A connection that has started reports its list of tools to the platform by itself, along with which of them only read. The platform starts one tool server per connection, not per connector: for a team with two trackers the model must see which one it is addressing.

Addressing the bot from a tracker or a page is optional. As soon as the connection’s “Development project” field holds the name of your project (or space), the model sees its tools in every “Ask” question and every deep research of that project — including those asked from the app, next to the code. The tracker then becomes a source: the model finds a ticket, reads a discussion or a pull request diff by itself if the answer needs it. The development stages of tasks — formulation, development, review — do not get the connection’s tools.

The connection’s name (the slug) goes into the server name — connector_<slug> — and therefore into the names of the tools the model sees. So it is worth keeping the slug meaningful: jira_prod and jira_sandbox read better in a run log than two jira.

The app shows what is running, which tools are given to the model and where the connection may go.

Writing tools are never given to the model

There is no “the model may write to the tracker” mode. The stages where the model works with your systems (“Ask”, deep research) get only the tools marked as read-only; the other stages get nothing.

This is checked twice and from two sides: the platform asks only for read-only ones, and the connector checks the requested tool against the list on its side and refuses if it is a writing one. The decision must not depend on the calling side having asked correctly.

Why so strict: a stage that can change the tracker is a stage that text written in that tracker by anyone at all has reached. The “reading allowed, writing not” rule exists precisely so that these two things never meet.

Then who writes the answer in the ticket

The connector writes the answer to the tracker, at a separate command from the platform, not the model with its tool. The difference is fundamental: the model does not decide what to write where — it answers the question, and the platform sends the finished answer back to where it came from, to the same ticket and the same discussion thread.

That is why the integration’s list of tools contains add_comment, but the model does not get it at any stage.

Notes for the AI

Tool descriptions say what a tool does, but not what your system is: which project is billing and which is operations; what you call releases; where to look first. You know this, so every connection has a “Notes for the AI” field — free text you write on the connector (on its page, in the command line or in YAML).

The text goes to the model together with the connection’s tools, in two ways: as the instructions of the connector_<slug> tool server — they go into the run’s system prompt — and at the start of the description of each of this connection’s tools. This way the model sees your notes both while planning and at the moment it chooses a tool. An empty field adds nothing to the prompt.

By default the notes are limited to 2048 characters. The limit can be lifted with a checkbox, but only after confirming that you understand the consequences: excess text in the prompt makes instruction-following worse, raises the cost of every run and does not make the model smarter. While the limit is lifted, the connection is marked with a warning — both on the connector and in the app. The connector truncates nothing: the volume is your decision.

The notes are third-party text in a system prompt, so the connector and the platform strip service markup from them that the model could mistake for the run’s own speech; the words stay, the tags do not.

Limits and accounting

  • No more than 120 calls per minute per connection. The connector holds the limit: exceeding it is an error for the caller, not silently dropped calls.
  • Every call is recorded: tool, duration, error — visible in the connection’s log on the connector; the platform keeps an account of calls per connection. Within the connection it also logs which outgoing request the tool made: method, address, response code and the name of the credentials (not the value).
  • Charges go to the connection, not to a person: the users of your tracker are not Buff users.

A tool that answers with a picture

Not every model reads images — most models Buff runs on are text-only. So a tool whose answer is a picture (for example, Figma’s render_node) is declared separately in the manifest (vision: true), and the platform gives it only to a model that reads images. The flag is taken from the model’s description — at the provider or on the dedicated machine — of what it accepts as input, without manual setup. A text model does not see such a tool at all: a tool that is named is a tool that gets called, and a picture handed to a model that cannot look is a confident answer based on nothing. Everything else the integration gives as parameters, and it works with any model. At the moment only “Ask” gets the picture; deep research works from the mock-up’s parameters.

What is visible in the app

In the “Connectors” section each connection shows: the status, the integration and its version, the development project, the allowed addresses, the full list of tools marked “read” (and “image” for the one that answers with a picture), the notes for the AI (collapsed and read-only; they are edited on the connector) and the time of the last report. If the notes’ length limit is lifted, the same warning mark as on the connector’s page sits next to the status. This is the same list the model sees — not a description from the documentation but what has actually been given.

On this page