Skip to content

Further iteration of the tool typing#391

Open
domarmstrong wants to merge 3 commits intotypesafetool_bugsnagfrom
dom/client_typesafe_tools
Open

Further iteration of the tool typing#391
domarmstrong wants to merge 3 commits intotypesafetool_bugsnagfrom
dom/client_typesafe_tools

Conversation

@domarmstrong
Copy link
Contributor

Goal

Make the api a bit nicer for defining type safe tools and resources.

With this change, the client classes have factory function that allow you to Client.createTool(...) Client.createResource(...)`.

Design

Make Client an abstract class and add factory functions to the base class. This allows us to use type inference without any explicit typing.

BugsnagClient.createTool({ ... }, async ({ client <- instance of BugsnagClient, args <- inferred from config }))

One thing required to be able to use this though is you need to use dynamic imports in the clients register functions. If you tried to do a static import of the tool files at the top of the client file the client class would not have been created yet and be undefined.

Changeset

Refactoring

Testing

@domarmstrong domarmstrong requested review from a team as code owners March 25, 2026 11:42
},
(client: BugsnagClient) => async (params, _extra) => {
const project = await client.getInputProject(params.projectId);
async ({ client, args }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stuck with the name args as that is in the mcp types and most other clients are using 'args'


// Fetches full details for a single error including aggregated stats, the latest event, pivots, and a dashboard URL.
export const getError = new TypesafeTool(
export default BugsnagClient.createTool(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could still use named exports, but consistently using default makes the imports a bit more straightforward.

readOnly: false,
idempotent: false,
},
(client: BugsnagClient, getInput: GetInputFunction) =>
Copy link
Contributor Author

@domarmstrong domarmstrong Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the current implementation, you have to also manually type any additional arguments to the handler factory. With this change you don't need any explicit typing or extra function nesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant