@@ -9,6 +9,7 @@ describe("prepareMcpConfig", () => {
99 let consoleWarningSpy : any ;
1010 let setFailedSpy : any ;
1111 let processExitSpy : any ;
12+ let fetchSpy : any ;
1213
1314 // Create a mock context for tests
1415 const mockContext : ParsedGitHubContext = {
@@ -66,6 +67,10 @@ describe("prepareMcpConfig", () => {
6667 processExitSpy = spyOn ( process , "exit" ) . mockImplementation ( ( ) => {
6768 throw new Error ( "Process exit" ) ;
6869 } ) ;
70+ // Mock fetch so checkActionsReadPermission succeeds (returns 200 for actions API)
71+ fetchSpy = spyOn ( global , "fetch" ) . mockResolvedValue (
72+ new Response ( JSON . stringify ( { workflow_runs : [ ] } ) , { status : 200 } ) ,
73+ ) ;
6974
7075 // Set up required environment variables
7176 if ( ! process . env . GITHUB_ACTION_PATH ) {
@@ -78,6 +83,7 @@ describe("prepareMcpConfig", () => {
7883 consoleWarningSpy . mockRestore ( ) ;
7984 setFailedSpy . mockRestore ( ) ;
8085 processExitSpy . mockRestore ( ) ;
86+ fetchSpy . mockRestore ( ) ;
8187 } ) ;
8288
8389 test ( "should return comment server when commit signing is disabled" , async ( ) => {
@@ -263,6 +269,33 @@ describe("prepareMcpConfig", () => {
263269 expect ( parsed . mcpServers . github_ci ) . not . toBeDefined ( ) ;
264270 } ) ;
265271
272+ test ( "should not include github_ci server when actions:read permission is missing" , async ( ) => {
273+ process . env . DEFAULT_WORKFLOW_TOKEN = "workflow-token" ;
274+ // Simulate 403 from actions API
275+ fetchSpy . mockResolvedValue (
276+ new Response (
277+ JSON . stringify ( { message : "Resource not accessible by integration" } ) ,
278+ { status : 403 } ,
279+ ) ,
280+ ) ;
281+
282+ const result = await prepareMcpConfig ( {
283+ githubToken : "test-token" ,
284+ owner : "test-owner" ,
285+ repo : "test-repo" ,
286+ branch : "test-branch" ,
287+ baseBranch : "main" ,
288+ allowedTools : [ ] ,
289+ mode : "tag" ,
290+ context : mockPRContext ,
291+ } ) ;
292+
293+ const parsed = JSON . parse ( result ) ;
294+ expect ( parsed . mcpServers . github_ci ) . not . toBeDefined ( ) ;
295+
296+ delete process . env . DEFAULT_WORKFLOW_TOKEN ;
297+ } ) ;
298+
266299 test ( "should not include github_ci server when DEFAULT_WORKFLOW_TOKEN is missing" , async ( ) => {
267300 delete process . env . DEFAULT_WORKFLOW_TOKEN ;
268301
0 commit comments