@@ -192,4 +192,57 @@ describe("getSystemMcpServerNames", () => {
192192 rmSync ( userConfigPath , { force : true } )
193193 }
194194 } )
195+
196+ it ( "reads both ~/.claude.json and ~/.claude/.mcp.json for user scope" , async ( ) => {
197+ // given: simulate both user-level config files
198+ const userClaudeJson = join ( TEST_DIR , ".claude.json" )
199+ const claudeDir = join ( TEST_DIR , ".claude" )
200+ const claudeDirMcpJson = join ( claudeDir , ".mcp.json" )
201+
202+ mkdirSync ( claudeDir , { recursive : true } )
203+
204+ // ~/.claude.json has server-a
205+ writeFileSync ( userClaudeJson , JSON . stringify ( {
206+ mcpServers : {
207+ "server-from-claude-json" : {
208+ command : "npx" ,
209+ args : [ "server-a" ] ,
210+ } ,
211+ } ,
212+ } ) )
213+
214+ // ~/.claude/.mcp.json has server-b (CLI-managed)
215+ writeFileSync ( claudeDirMcpJson , JSON . stringify ( {
216+ mcpServers : {
217+ "server-from-mcp-json" : {
218+ command : "npx" ,
219+ args : [ "server-b" ] ,
220+ } ,
221+ } ,
222+ } ) )
223+
224+ const originalCwd = process . cwd ( )
225+ process . chdir ( TEST_DIR )
226+
227+ try {
228+ mock . module ( "os" , ( ) => ( {
229+ homedir : ( ) => TEST_DIR ,
230+ tmpdir,
231+ } ) )
232+
233+ // Also mock getClaudeConfigDir to point to our test .claude dir
234+ mock . module ( "../../shared" , ( ) => ( {
235+ getClaudeConfigDir : ( ) => claudeDir ,
236+ } ) )
237+
238+ const { getSystemMcpServerNames } = await import ( "./loader" )
239+ const names = getSystemMcpServerNames ( )
240+
241+ // Both sources should be merged
242+ expect ( names . has ( "server-from-claude-json" ) ) . toBe ( true )
243+ expect ( names . has ( "server-from-mcp-json" ) ) . toBe ( true )
244+ } finally {
245+ process . chdir ( originalCwd )
246+ }
247+ } )
195248} )
0 commit comments