@@ -298,8 +298,152 @@ Test prompt with compact mode`
298298 if len (config .MCPServers ) != 1 {
299299 t .Errorf ("Expected 1 MCP server, got %d" , len (config .MCPServers ))
300300 }
301+ }
302+
303+ func TestParseScriptContentMCPServersNewFormat (t * testing.T ) {
304+ content := `---
305+ model: "anthropic:claude-sonnet-4-20250514"
306+ mcpServers:
307+ filesystem:
308+ type: "local"
309+ command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
310+ environment:
311+ NODE_ENV: "production"
312+ remote-server:
313+ type: "remote"
314+ url: "https://example.com/mcp"
315+ builtin-todo:
316+ type: "builtin"
317+ name: "todo"
318+ options:
319+ storage: "memory"
320+ ---
321+ Test prompt with new format MCP servers`
322+
323+ variables := make (map [string ]string )
324+ config , err := parseScriptContent (content , variables )
325+ if err != nil {
326+ t .Fatalf ("parseScriptContent() failed: %v" , err )
327+ }
328+
329+ if len (config .MCPServers ) != 3 {
330+ t .Errorf ("Expected 3 MCP servers, got %d" , len (config .MCPServers ))
331+ }
332+
333+ // Test local server
334+ fs , exists := config .MCPServers ["filesystem" ]
335+ if ! exists {
336+ t .Error ("Expected filesystem server to exist" )
337+ }
338+ if fs .Type != "local" {
339+ t .Errorf ("Expected filesystem server type 'local', got '%s'" , fs .Type )
340+ }
341+ expectedCommand := []string {"npx" , "-y" , "@modelcontextprotocol/server-filesystem" , "/tmp" }
342+ if len (fs .Command ) != len (expectedCommand ) {
343+ t .Errorf ("Expected filesystem server command length %d, got %d" , len (expectedCommand ), len (fs .Command ))
344+ }
345+ for i , expected := range expectedCommand {
346+ if i >= len (fs .Command ) || fs .Command [i ] != expected {
347+ t .Errorf ("Expected filesystem server command %v, got %v" , expectedCommand , fs .Command )
348+ break
349+ }
350+ }
351+ if fs .Environment ["node_env" ] != "production" {
352+ t .Errorf ("Expected node_env=production, got %s" , fs .Environment ["node_env" ])
353+ }
354+
355+ // Test remote server
356+ remote , exists := config .MCPServers ["remote-server" ]
357+ if ! exists {
358+ t .Error ("Expected remote-server to exist" )
359+ }
360+ if remote .Type != "remote" {
361+ t .Errorf ("Expected remote server type 'remote', got '%s'" , remote .Type )
362+ }
363+ if remote .URL != "https://example.com/mcp" {
364+ t .Errorf ("Expected remote server URL 'https://example.com/mcp', got '%s'" , remote .URL )
365+ }
366+
367+ // Test builtin server
368+ builtin , exists := config .MCPServers ["builtin-todo" ]
369+ if ! exists {
370+ t .Error ("Expected builtin-todo server to exist" )
371+ }
372+ if builtin .Type != "builtin" {
373+ t .Errorf ("Expected builtin server type 'builtin', got '%s'" , builtin .Type )
374+ }
375+ if builtin .Name != "todo" {
376+ t .Errorf ("Expected builtin server name 'todo', got '%s'" , builtin .Name )
377+ }
378+ }
379+
380+ func TestParseScriptContentMCPServersLegacyFormat (t * testing.T ) {
381+ content := `---
382+ model: "anthropic:claude-sonnet-4-20250514"
383+ mcpServers:
384+ legacy-stdio:
385+ transport: "stdio"
386+ command: "npx"
387+ args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
388+ env:
389+ node_env: "development"
390+ legacy-sse:
391+ transport: "sse"
392+ url: "https://legacy.example.com/mcp"
393+ headers: ["Authorization: Bearer token"]
394+ ---
395+ Test prompt with legacy format MCP servers`
301396
302- if config .MCPServers ["todo" ].Type != "builtin" {
303- t .Errorf ("Expected todo server type 'builtin', got '%s'" , config .MCPServers ["todo" ].Type )
397+ variables := make (map [string ]string )
398+ config , err := parseScriptContent (content , variables )
399+ if err != nil {
400+ t .Fatalf ("parseScriptContent() failed: %v" , err )
401+ }
402+
403+ if len (config .MCPServers ) != 2 {
404+ t .Errorf ("Expected 2 MCP servers, got %d" , len (config .MCPServers ))
405+ }
406+
407+ // Test legacy stdio server - Note: Viper parsing doesn't trigger custom UnmarshalJSON
408+ // so legacy format has limited support in script frontmatter
409+ stdio , exists := config .MCPServers ["legacy-stdio" ]
410+ if ! exists {
411+ t .Error ("Expected legacy-stdio server to exist" )
412+ }
413+ if stdio .Transport != "stdio" {
414+ t .Errorf ("Expected legacy stdio transport 'stdio', got '%s'" , stdio .Transport )
415+ }
416+ // Command field only gets the single command value, not combined with args
417+ if stdio .Command [0 ] != "npx" {
418+ t .Errorf ("Expected legacy stdio command to start with 'npx', got %v" , stdio .Command )
419+ }
420+ expectedArgs := []string {"-y" , "@modelcontextprotocol/server-filesystem" , "/tmp" }
421+ if len (stdio .Args ) != len (expectedArgs ) {
422+ t .Errorf ("Expected legacy stdio args length %d, got %d" , len (expectedArgs ), len (stdio .Args ))
423+ }
424+ for i , expected := range expectedArgs {
425+ if i >= len (stdio .Args ) || stdio .Args [i ] != expected {
426+ t .Errorf ("Expected legacy stdio args %v, got %v" , expectedArgs , stdio .Args )
427+ break
428+ }
429+ }
430+ // Env field should contain the environment variables (with lowercase keys due to Viper)
431+ if stdio .Env ["node_env" ] != "development" {
432+ t .Errorf ("Expected legacy stdio env node_env=development, got %v" , stdio .Env ["node_env" ])
433+ }
434+
435+ // Test legacy SSE server
436+ sse , exists := config .MCPServers ["legacy-sse" ]
437+ if ! exists {
438+ t .Error ("Expected legacy-sse server to exist" )
439+ }
440+ if sse .Transport != "sse" {
441+ t .Errorf ("Expected legacy sse transport 'sse', got '%s'" , sse .Transport )
442+ }
443+ if sse .URL != "https://legacy.example.com/mcp" {
444+ t .Errorf ("Expected legacy sse URL 'https://legacy.example.com/mcp', got '%s'" , sse .URL )
445+ }
446+ if len (sse .Headers ) != 1 || sse .Headers [0 ] != "Authorization: Bearer token" {
447+ t .Errorf ("Expected legacy sse headers [Authorization: Bearer token], got %v" , sse .Headers )
304448 }
305449}
0 commit comments