@@ -170,3 +170,67 @@ describe('Refresh button (custom registry)', () => {
170170 expect ( screen . getByRole ( 'button' , { name : / r e f r e s h / i } ) ) . toBeVisible ( )
171171 } )
172172} )
173+
174+ describe ( 'Bug: search for "github" should match GitHub MCP servers' , ( ) => {
175+ it ( 'matches an MCP whose user-visible title contains the term ("github") even when name does not' , async ( ) => {
176+ // The Registry tab renders an MCP's `title` (falling back to `name`) as
177+ // the row label — see `table-registry.tsx` (`server.title ?? server.name`)
178+ // and `card-registry-server.tsx`. So a user reasonably expects that the
179+ // text they see in the UI is what the search input matches against.
180+ //
181+ // The bug report says searching "github" returns no MCP results. With the
182+ // production registry, the GitHub MCP server is displayed with the title
183+ // "GitHub" but is technically registered under a non-"github" name (a
184+ // packaged variant), so the current filter — which only checks
185+ // `name + description` — never sees the visible title and drops the row.
186+ mockedGetApiV1BetaRegistryByName . override (
187+ ( data ) =>
188+ ( {
189+ ...data ,
190+ registry : {
191+ ...( data as V1GetRegistryResponse ) . registry ,
192+ groups : [ ] ,
193+ } ,
194+ } ) as unknown as V1GetRegistryResponse
195+ )
196+ mockedGetApiV1BetaRegistryByNameServers . override ( ( ) => ( {
197+ servers : [
198+ {
199+ name : 'gh-mcp-server' ,
200+ title : 'GitHub' ,
201+ image : 'mcp/gh-server:latest' ,
202+ description : 'Official MCP server for accessing repos and PRs.' ,
203+ repository_url : 'https://github.com/github/github-mcp-server' ,
204+ } ,
205+ {
206+ name : 'time' ,
207+ image : 'mcp/time:latest' ,
208+ description : 'Time server.' ,
209+ } ,
210+ ] ,
211+ remote_servers : [ ] ,
212+ } ) )
213+
214+ renderRoute ( router )
215+
216+ await waitFor ( ( ) => {
217+ expect ( screen . queryByText ( 'GitHub' ) ) . toBeVisible ( )
218+ } )
219+
220+ const searchInput = screen . getByPlaceholderText ( 'Search...' )
221+ await userEvent . type ( searchInput , 'github' )
222+
223+ // The visible title "GitHub" must remain in the document after typing
224+ // "github" — this is the user-facing label of the row the user is looking
225+ // for. Currently fails because the filter only inspects name+description.
226+ await waitFor ( ( ) => {
227+ expect (
228+ screen . queryByText ( 'GitHub' ) ,
229+ 'MCP row labelled "GitHub" should remain visible when searching "github"'
230+ ) . toBeVisible ( )
231+ } )
232+
233+ // The unrelated MCP should be filtered out.
234+ expect ( screen . queryByText ( 'time' ) ) . not . toBeInTheDocument ( )
235+ } )
236+ } )
0 commit comments