openvibers/openvibe.search Commits

agent.json names the MCP server and OpenAPI document Search already serves (AGT-2) (#213)

OP OpenVibers committed 10 days ago · 0c290b50c5 · 2 files, +11 −1

/mcp (the Search Fabric's two read-only tools) and /openapi.json both answer, but the manifest said
neither was published, so an agent reading agent.json never found them.

Changes

ddiff --git a/server/agent-descriptor.js b/server/agent-descriptor.js
iindex 49393af..65cb57e 100644
---- a/server/agent-descriptor.js
++++ b/server/agent-descriptor.js
@@@ -1,7 +1,9 @@
'use strict';
// What search.openvibe.network tells an agent about itself (openvibe-shared/agent-layer): /.well-known/agent.json.
// The public pages are the search page (front, and results for anonymous callers) and the update log; the JSON
--// API is /api/v1. No separate documentation page, OpenAPI document or MCP endpoint is published, so none is named.
++// API is /api/v1, its OpenAPI 3.1 document is /openapi.json (server/openapi.js), and the Search Fabric is an MCP server
++// at /mcp (server/api/mcp.js: two read-only tools, anonymous or with a Network token). No separate documentation page
++// is published, so none is named.
module.exports = {
id: 'search',
name: 'OpenVibe.Search',
@@@ -9,6 +11,8 @@ module.exports = {
home: 'https://search.openvibe.network',
site: 'search.openvibe.network',
api: '/api/v1',
++ openapi: '/openapi.json',
++ mcp: { url: '/mcp' },
policy: {
auth: ['none', 'Network OIDC'],
rateLimit: '120 read API requests a minute and 3,000 an hour per caller; the Search Fabric query 30 a minute and 600 an hour; the HTML page follows nginx\'s address limits',
ddiff --git a/test/discovery.test.js b/test/discovery.test.js
iindex e1c386f..bb516b1 100644
---- a/test/discovery.test.js
++++ b/test/discovery.test.js
@@@ -130,6 +130,12 @@ t('the agent layer: manifest, twins, and the pages that name them', async () =>
assert.strictEqual(d.home, 'https://search.openvibe.network');
assert.strictEqual(d.api, 'https://search.openvibe.network/api/v1');
assert.deepStrictEqual(d.policy.auth, ['none', 'Network OIDC']);
++ // The OpenAPI document and the MCP server it names are the ones this service answers (AGT-2).
++ assert.strictEqual(d.openapi, 'https://search.openvibe.network/openapi.json');
++ assert.deepStrictEqual([d.mcp.url, d.mcp.transport], ['https://search.openvibe.network/mcp', 'streamable-http']);
++ const init = await request(svc.base, 'POST', '/mcp', { body: { jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'test', version: '1' } } } });
++ assert.strictEqual(init.status, 200, 'the named MCP endpoint answers an initialize');
++ assert.ok(/"protocolVersion"/.test(init.text));
// A twin of the front page and of the update log, from the pages' own render. The twin's canonical is the
// manifest's home (the site's public address), not the test server's own base URL.
for (const [p, canonical] of [['/index.md', 'https://search.openvibe.network/'], ['/updates.md', 'https://search.openvibe.network/updates']]) {