Skip to content

chore: Reactive resource support for debugging connectivity MCP-80 #413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 31, 2025

Conversation

kmruiz
Copy link
Collaborator

@kmruiz kmruiz commented Jul 30, 2025

Proposed changes

Resources can listen to events on the session and their arguments, and reduces the current state with the argument to provide a new state.

This way this is type safe and declarative, mimicking how tools work.

Checklist

It can listen to events on the session and their arguments, and
reduces the current state with the argument to provide a new state.
kmruiz added 5 commits July 31, 2025 10:26
Also add unit tests to show how to test resources.
We might be telling the user that they successfully connected to a
database and we haven't tested it, failing afterwards. By running
the hello command, we verify that the user does indeed connected.
@kmruiz kmruiz changed the title chore: Probe of concept for reactive resources based on the session MCP-80 chore: Reactive resource support for debugging connectivity MCP-80 Jul 31, 2025
The server might be closed because the connection made the
server die or because it's a unit test. In that case, do
not fail, just log the error and continue.

This is not a critical feature, in case that we couldn't
sync once, we will try again at some point or just let
it be.
@kmruiz kmruiz marked this pull request as ready for review July 31, 2025 11:42
@kmruiz kmruiz requested a review from a team as a code owner July 31, 2025 11:42
@kmruiz kmruiz enabled auto-merge (squash) July 31, 2025 11:42
applyProxyToOIDC: true,
});

await this.serviceProvider?.runCommand?.("admin", { hello: 1 });
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

NodeDriverServiceProvider.connect, despite it's name, does not in fact connect. This behaviour is likely inherited from the driver.

By forcing a ping (by using hello) we force a connection and validate that it's in fact correct.

Copy link
Collaborator

Choose a reason for hiding this comment

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

we have a ping on atlas cluster connect tool where we added a ping, should we drop it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I see that it's used for answering the client with the connection status. I think we can keep it for now and then when we remove this logic to the new ConnectionManager (Tech Design) we can refactor and use the same code for both connections.

How do you feel about this strategy?


type ResourceConfiguration = { name: string; uri: string; config: ResourceMetadata };

export function ReactiveResource<Value, RelevantEvents extends readonly (keyof SessionEvents)[]>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

[q] any reason to use the function returning class pattern instead of using a class straight away?

export class ReactiveResource<...>

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My understanding is that resource metadata is immutable and by using this pattern I feel it's more convenient to specify the configuration once and still be type-safe. I think using normal classes where everything is specified in properties makes more sense when you want to change the state. With this pattern, it's not possible, as the metadata is hidden in the closure.

Copy link
Collaborator

@himanshusinghs himanshusinghs left a comment

Choose a reason for hiding this comment

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

LGTM with small suggestions 🚀

this.server.mcpServer.sendResourceListChanged();
} catch (error: unknown) {
logger.warning(
LogId.serverClosed,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This most likely needs a new log id?

Comment on lines +19 to +21
reduce(eventName: undefined, event: undefined): UserConfig {
void eventName;
void event;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could possibly be avoided by having reduce without any params?

eventName: "connect" | "disconnect" | "close" | "connection-error",
event: string | undefined
): ConnectionStateDebuggingInformation {
void event;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this necessary anymore, now that you're using event in connection-error case?

@kmruiz kmruiz merged commit e6615c3 into main Jul 31, 2025
17 checks passed
@kmruiz kmruiz deleted the chore/mcp-resource-refactor branch July 31, 2025 12:24
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.

3 participants