Merge pull request #3111 from Fibilisim-Tekno/fix/memory-initialized-metadata

fix(memory-mcp): accept metadata on initialized notifications
This commit is contained in:
Affaan Mustafa
2026-09-19 16:51:53 -04:00
committed by GitHub
2 changed files with 73 additions and 1 deletions
Executable → Regular
+3 -1
View File
@@ -383,10 +383,12 @@ function createMemoryMcpService(options = {}) {
const isNotification = !hasId;
if (isNotification) {
const params = message.params ?? {};
if (
message.method === 'notifications/initialized'
&& initializationRequested
&& Object.keys(message.params || {}).length === 0
&& (!Object.prototype.hasOwnProperty.call(params, '_meta') || isRecord(params._meta))
&& Object.keys(params).every(key => key === '_meta')
) {
initialized = true;
}
+70
View File
@@ -806,6 +806,76 @@ async function main() {
assert.strictEqual(invalidParams.error.code, -32600);
});
for (const [label, params] of [
['omitted params', undefined],
['empty params', {}],
['empty metadata', { _meta: {} }],
['extension metadata', { _meta: { 'example.com/trace': 'sample' } }],
]) {
await test(`accepts initialized notifications with ${label}`, async () => {
const { createMemoryMcpService } = await import(pathToFileURL(SERVER).href);
const service = createMemoryMcpService({ harness: 'claude' });
const initialized = await service.handle({
jsonrpc: '2.0', id: 1, method: 'initialize',
params: {
protocolVersion: '2025-11-25', capabilities: {},
clientInfo: { name: 'metadata-test', version: '1.0.0' },
},
});
assert.strictEqual(initialized.error, undefined);
const notification = await service.handle({
jsonrpc: '2.0', method: 'notifications/initialized',
...(params === undefined ? {} : { params }),
});
assert.strictEqual(notification, null);
const listed = await service.handle({ jsonrpc: '2.0', id: 2, method: 'tools/list' });
assert.strictEqual(listed.error, undefined);
assert.ok(listed.result.tools.some(tool => tool.name === 'memory_search'));
});
}
await test('ignores initialized notifications with malformed metadata or unknown params', async () => {
const { createMemoryMcpService } = await import(pathToFileURL(SERVER).href);
for (const params of [
...[null, [], 'invalid', 1, false].map(_meta => ({ _meta })),
{ _meta: {}, unexpected: true },
]) {
const service = createMemoryMcpService({ harness: 'claude' });
await service.handle({
jsonrpc: '2.0', id: 1, method: 'initialize',
params: {
protocolVersion: '2025-11-25', capabilities: {},
clientInfo: { name: 'metadata-test', version: '1.0.0' },
},
});
assert.strictEqual(await service.handle({
jsonrpc: '2.0', method: 'notifications/initialized', params,
}), null);
const listed = await service.handle({ jsonrpc: '2.0', id: 2, method: 'tools/list' });
assert.strictEqual(listed.error?.code, -32002, JSON.stringify(params));
}
});
await test('does not initialize from a metadata notification sent before initialize', async () => {
const { createMemoryMcpService } = await import(pathToFileURL(SERVER).href);
const service = createMemoryMcpService({ harness: 'claude' });
const notification = {
jsonrpc: '2.0', method: 'notifications/initialized', params: { _meta: {} },
};
assert.strictEqual(await service.handle(notification), null);
const before = await service.handle({ jsonrpc: '2.0', id: 1, method: 'tools/list' });
assert.strictEqual(before.error?.code, -32002);
await service.handle({
jsonrpc: '2.0', id: 2, method: 'initialize',
params: {
protocolVersion: '2025-11-25', capabilities: {},
clientInfo: { name: 'metadata-test', version: '1.0.0' },
},
});
const after = await service.handle({ jsonrpc: '2.0', id: 3, method: 'tools/list' });
assert.strictEqual(after.error?.code, -32002);
});
await test('bounds queued transport work under a single-chunk request flood', async () => {
const {
MAX_PENDING_MESSAGES,