mcp connection
This commit is contained in:
@@ -409,18 +409,42 @@ func (r *Registry) DispatchApproved(ctx context.Context, tc Context, token strin
|
||||
}, true
|
||||
}
|
||||
|
||||
// ToolInfo is what a tool looks like to somebody choosing one, rather than to
|
||||
// the model calling it.
|
||||
// ToolInfo is what a tool looks like to somebody choosing one, and — since the
|
||||
// MCP surface — to a client that must publish the schema before calling it.
|
||||
//
|
||||
// The InputSchema is deliberately absent: an author picks a capability, and the
|
||||
// schema is the model's business. Effect is present because it is the one thing
|
||||
// an author must understand — a write tool means their agent can propose
|
||||
// changes, which a person will then be asked to approve.
|
||||
// Effect is present because it is the one thing an author must understand: a
|
||||
// write tool means their agent can propose changes, which a person will then be
|
||||
// asked to approve.
|
||||
//
|
||||
// InputSchema used to be deliberately absent, on the reasoning that an author
|
||||
// picks a capability and the schema is the model's business. That is still true
|
||||
// of the authoring UI, which simply ignores the field. It stopped being true of
|
||||
// the catalogue as a whole once a second consumer appeared: MCP's tools/list
|
||||
// must publish a JSON Schema per tool, and the only alternative to carrying
|
||||
// this one is maintaining a copy. A copy is a second definition of the same
|
||||
// thing, and the way it fails is silent — a field renamed on the handler side
|
||||
// leaves a schema that still validates and no longer matches, so the call
|
||||
// succeeds and the argument is quietly ignored.
|
||||
//
|
||||
// Both new fields carry `omitempty`, but be clear about what that does and does
|
||||
// not buy: every currently registered tool declares a schema and a byte cap, so
|
||||
// GET /api/v1/tools genuinely does get larger — roughly 700 bytes per tool. The
|
||||
// change is additive rather than invisible. It is compatible because JSON
|
||||
// consumers ignore keys they do not read, and the one consumer that exists (the
|
||||
// agent editor's tool picker) reads name, description and effect; `omitempty`
|
||||
// covers the remaining case of a tool registered with neither field.
|
||||
type ToolInfo struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Effect string `json:"effect"`
|
||||
RequiresConfirmation bool `json:"requiresConfirmation"`
|
||||
|
||||
// InputSchema is the tool's JSON Schema, exactly as registered.
|
||||
InputSchema map[string]any `json:"inputSchema,omitempty"`
|
||||
|
||||
// MaxResultBytes is the cap Dispatch truncates at, so a caller can state
|
||||
// the limit rather than discover it by hitting it.
|
||||
MaxResultBytes int `json:"maxResultBytes,omitempty"`
|
||||
}
|
||||
|
||||
// Catalogue lists every registered tool, sorted, as choosable metadata.
|
||||
@@ -440,6 +464,8 @@ func (r *Registry) Catalogue() []ToolInfo {
|
||||
Description: t.Description,
|
||||
Effect: string(t.Effect),
|
||||
RequiresConfirmation: t.RequiresConfirmation,
|
||||
InputSchema: t.InputSchema,
|
||||
MaxResultBytes: t.MaxResultBytes,
|
||||
})
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name })
|
||||
|
||||
Reference in New Issue
Block a user