Merge branch 'main' into justin/simplified-api

This commit is contained in:
Justin Spahr-Summers 2025-01-13 20:34:08 +00:00
commit 2e35b15353
No known key found for this signature in database
4 changed files with 72 additions and 8 deletions

View file

@ -0,0 +1,28 @@
import { Server } from "../server/index.js";
import { StdioServerTransport } from "../server/stdio.js";
describe("Process cleanup", () => {
jest.setTimeout(5000); // 5 second timeout
it("should exit cleanly after closing transport", async () => {
const server = new Server(
{
name: "test-server",
version: "1.0.0",
},
{
capabilities: {},
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
// Close the transport
await transport.close();
// If we reach here without hanging, the test passes
// The test runner will fail if the process hangs
expect(true).toBe(true);
});
});

View file

@ -38,6 +38,7 @@ test("should accept latest protocol version", async () => {
name: "test server",
version: "1.0",
},
instructions: "Test instructions",
});
sendPromiseResolve(undefined);
}
@ -57,6 +58,7 @@ test("should accept latest protocol version", async () => {
tools: {},
logging: {},
},
instructions: "Test instructions",
},
);

View file

@ -34,6 +34,11 @@ export type ServerOptions = ProtocolOptions & {
* Capabilities to advertise as being supported by this server.
*/
capabilities?: ServerCapabilities;
/**
* Optional instructions describing how to use the server and its features.
*/
instructions?: string;
};
/**
@ -73,6 +78,7 @@ export class Server<
private _clientCapabilities?: ClientCapabilities;
private _clientVersion?: Implementation;
private _capabilities: ServerCapabilities;
private _instructions?: string;
/**
* Callback for when initialization has fully completed (i.e., the client has sent an `initialized` notification).
@ -88,6 +94,7 @@ export class Server<
) {
super(options);
this._capabilities = options?.capabilities ?? {};
this._instructions = options?.instructions;
this.setRequestHandler(InitializeRequestSchema, (request) =>
this._oninitialize(request),
@ -250,6 +257,7 @@ export class Server<
: LATEST_PROTOCOL_VERSION,
capabilities: this.getCapabilities(),
serverInfo: this._serverInfo,
...(this._instructions && { instructions: this._instructions }),
};
}

View file

@ -62,8 +62,19 @@ export class StdioServerTransport implements Transport {
}
async close(): Promise<void> {
// Remove our event listeners first
this._stdin.off("data", this._ondata);
this._stdin.off("error", this._onerror);
// Check if we were the only data listener
const remainingDataListeners = this._stdin.listenerCount('data');
if (remainingDataListeners === 0) {
// Only pause stdin if we were the only listener
// This prevents interfering with other parts of the application that might be using stdin
this._stdin.pause();
}
// Clear the buffer and notify closure
this._readBuffer.clear();
this.onclose?.();
}