访问 GitHub

将您的代理连接到 GitHub 仓库,用于克隆、读取和创建拉取请求。


您可以将 GitHub 仓库挂载到会话容器中,并连接到 GitHub MCP 以创建拉取请求。

GitHub 仓库会被缓存,因此未来使用相同仓库的会话启动更快。

Note

所有托管代理 API 请求都需要 managed-agents-2026-04-01 beta 头。SDK 会自动设置该 beta 头。

GitHub MCP 和会话资源

首先,创建一个声明 GitHub MCP 服务器的代理。代理定义包含服务器 URL 但不包含认证令牌:

agent_id=$(curl -fsS https://api.anthropic.com/v1/agents \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "content-type: application/json" \
  --data @- <<JSON | jq -r '.id'
{
  "name": "Code Reviewer",
  "model": "claude-opus-4-7",
  "system": "You are a code review assistant with access to GitHub.",
  "mcp_servers": [
    {
      "type": "url",
      "name": "github",
      "url": "https://api.githubcopilot.com/mcp/"
    }
  ],
  "tools": [
    {"type": "agent_toolset_20260401"},
    {
      "type": "mcp_toolset",
      "mcp_server_name": "github"
    }
  ]
}
JSON
)
AGENT_ID=$(ant beta:agents create \
  --name "Code Reviewer" \
  --model '{id: claude-opus-4-7}' \
  --system "You are a code review assistant with access to GitHub." \
  --mcp-server '{type: url, name: github, url: https://api.githubcopilot.com/mcp/}' \
  --tool '{type: agent_toolset_20260401}' \
  --tool '{type: mcp_toolset, mcp_server_name: github}' \
  --transform id --raw-output)
agent = client.beta.agents.create(
    name="Code Reviewer",
    model="claude-opus-4-7",
    system="You are a code review assistant with access to GitHub.",
    mcp_servers=[
        {
            "type": "url",
            "name": "github",
            "url": "https://api.githubcopilot.com/mcp/",
        },
    ],
    tools=[
        {"type": "agent_toolset_20260401"},
        {
            "type": "mcp_toolset",
            "mcp_server_name": "github",
        },
    ],
)
const agent = await client.beta.agents.create({
  name: "Code Reviewer",
  model: "claude-opus-4-7",
  system: "You are a code review assistant with access to GitHub.",
  mcp_servers: [
    {
      type: "url",
      name: "github",
      url: "https://api.githubcopilot.com/mcp/",
    },
  ],
  tools: [
    { type: "agent_toolset_20260401" },
    {
      type: "mcp_toolset",
      mcp_server_name: "github",
    },
  ],
});
var agent = await client.Beta.Agents.Create(new()
{
    Name = "Code Reviewer",
    Model = new("claude-opus-4-7"),
    System = "You are a code review assistant with access to GitHub.",
    McpServers =
    [
        new() { Type = "url", Name = "github", Url = "https://api.githubcopilot.com/mcp/" },
    ],
    Tools =
    [
        new BetaManagedAgentsAgentToolset20260401Params
        {
            Type = "agent_toolset_20260401",
        },
        new BetaManagedAgentsMcpToolsetParams
        {
            Type = "mcp_toolset",
            McpServerName = "github",
        },
    ],
});
agent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
	Name: "Code Reviewer",
	Model: anthropic.BetaManagedAgentsModelConfigParams{
		ID: "claude-opus-4-7",
	},
	System: anthropic.String("You are a code review assistant with access to GitHub."),
	MCPServers: []anthropic.BetaManagedAgentsURLMCPServerParams{
		{
			Type: anthropic.BetaManagedAgentsURLMCPServerParamsTypeURL,
			Name: "github",
			URL:  "https://api.githubcopilot.com/mcp/",
		},
	},
	Tools: []anthropic.BetaAgentNewParamsToolUnion{
		{
			OfAgentToolset20260401: &anthropic.BetaManagedAgentsAgentToolset20260401Params{
				Type: anthropic.BetaManagedAgentsAgentToolset20260401ParamsTypeAgentToolset20260401,
			},
		},
		{
			OfMCPToolset: &anthropic.BetaManagedAgentsMCPToolsetParams{
				Type:          anthropic.BetaManagedAgentsMCPToolsetParamsTypeMCPToolset,
				MCPServerName: "github",
			},
		},
	},
})
if err != nil {
	panic(err)
}
var agent = client.beta().agents().create(AgentCreateParams.builder()
    .name("Code Reviewer")
    .model(BetaManagedAgentsModel.CLAUDE_OPUS_4_7)
    .system("You are a code review assistant with access to GitHub.")
    .addMcpServer(BetaManagedAgentsUrlMcpServerParams.builder()
        .type(BetaManagedAgentsUrlMcpServerParams.Type.URL)
        .name("github")
        .url("https://api.githubcopilot.com/mcp/")
        .build())
    .addTool(BetaManagedAgentsAgentToolset20260401Params.builder()
        .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
        .build())
    .addTool(BetaManagedAgentsMcpToolsetParams.builder()
        .type(BetaManagedAgentsMcpToolsetParams.Type.MCP_TOOLSET)
        .mcpServerName("github")
        .build())
    .build());
$agent = $client->beta->agents->create(
    name: 'Code Reviewer',
    model: 'claude-opus-4-7',
    system: 'You are a code review assistant with access to GitHub.',
    mcpServers: [
        [
            'type' => 'url',
            'name' => 'github',
            'url' => 'https://api.githubcopilot.com/mcp/',
        ],
    ],
    tools: [
        ['type' => 'agent_toolset_20260401'],
        [
            'type' => 'mcp_toolset',
            'mcpServerName' => 'github',
        ],
    ],
);
agent = client.beta.agents.create(
  name: "Code Reviewer",
  model: "claude-opus-4-7",
  system_: "You are a code review assistant with access to GitHub.",
  mcp_servers: [
    {
      type: "url",
      name: "github",
      url: "https://api.githubcopilot.com/mcp/"
    }
  ],
  tools: [
    {type: "agent_toolset_20260401"},
    {
      type: "mcp_toolset",
      mcp_server_name: "github"
    }
  ]
)

然后创建一个挂载 GitHub 仓库的会话:

session_id=$(curl -fsS https://api.anthropic.com/v1/sessions \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "content-type: application/json" \
  --data @- <<JSON | jq -r '.id'
{
  "agent": "$agent_id",
  "environment_id": "$environment_id",
  "resources": [
    {
      "type": "github_repository",
      "url": "https://github.com/org/repo",
      "mount_path": "/workspace/repo",
      "authorization_token": "ghp_your_github_token"
    }
  ]
}
JSON
)
SESSION_ID=$(ant beta:sessions create \
  --agent "$AGENT_ID" \
  --environment-id "$ENVIRONMENT_ID" \
  --transform id --raw-output <<'EOF'
resources:
  - type: github_repository
    url: https://github.com/org/repo
    mount_path: /workspace/repo
    authorization_token: ghp_your_github_token
EOF
)
session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    resources=[
        {
            "type": "github_repository",
            "url": "https://github.com/org/repo",
            "mount_path": "/workspace/repo",
            "authorization_token": "ghp_your_github_token",
        },
    ],
)
const session = await client.beta.sessions.create({
  agent: agent.id,
  environment_id: environment.id,
  resources: [
    {
      type: "github_repository",
      url: "https://github.com/org/repo",
      mount_path: "/workspace/repo",
      authorization_token: "ghp_your_github_token",
    },
  ],
});
var session = await client.Beta.Sessions.Create(new()
{
    Agent = agent.ID,
    EnvironmentID = environment.ID,
    Resources =
    [
        new BetaManagedAgentsGitHubRepositoryResourceParams
        {
            Type = "github_repository",
            Url = "https://github.com/org/repo",
            MountPath = "/workspace/repo",
            AuthorizationToken = "ghp_your_github_token",
        },
    ],
});
session, err := client.Beta.Sessions.New(ctx, anthropic.BetaSessionNewParams{
	Agent:         anthropic.BetaSessionNewParamsAgentUnion{OfString: anthropic.String(agent.ID)},
	EnvironmentID: environment.ID,
	Resources: []anthropic.BetaSessionNewParamsResourceUnion{
		{
			OfGitHubRepository: &anthropic.BetaManagedAgentsGitHubRepositoryResourceParams{
				Type:               anthropic.BetaManagedAgentsGitHubRepositoryResourceParamsTypeGitHubRepository,
				URL:                "https://github.com/org/repo",
				MountPath:          anthropic.String("/workspace/repo"),
				AuthorizationToken: "ghp_your_github_token",
			},
		},
	},
})
if err != nil {
	panic(err)
}
var session = client.beta().sessions().create(SessionCreateParams.builder()
    .agent(agent.id())
    .environmentId(environment.id())
    .addResource(BetaManagedAgentsGitHubRepositoryResourceParams.builder()
        .type(BetaManagedAgentsGitHubRepositoryResourceParams.Type.GITHUB_REPOSITORY)
        .url("https://github.com/org/repo")
        .mountPath("/workspace/repo")
        .authorizationToken("ghp_your_github_token")
        .build())
    .build());
$session = $client->beta->sessions->create(
    agent: $agent->id,
    environmentID: $environment->id,
    resources: [
        [
            'type' => 'github_repository',
            'url' => 'https://github.com/org/repo',
            'mountPath' => '/workspace/repo',
            'authorizationToken' => 'ghp_your_github_token',
        ],
    ],
);
session = client.beta.sessions.create(
  agent: agent.id,
  environment_id: environment.id,
  resources: [
    {
      type: "github_repository",
      url: "https://github.com/org/repo",
      mount_path: "/workspace/repo",
      authorization_token: "ghp_your_github_token"
    }
  ]
)

resources[].authorization_token 用于认证仓库克隆操作,不会在 API 响应中返回。

令牌权限

提供 GitHub 令牌时,请使用最低所需权限:

操作所需范围
克隆私有仓库repo
创建拉取请求repo
读取 issuesrepo(私有)或 public_repo
创建 issuesrepo(私有)或 public_repo
Warning

使用具有最低所需权限的细粒度个人访问令牌。避免使用对您的 GitHub 帐户具有广泛访问权限的令牌。

多个仓库

通过向 resources 数组添加条目来挂载多个仓库:

resources='[
  {
    "type": "github_repository",
    "url": "https://github.com/org/frontend",
    "mount_path": "/workspace/frontend",
    "authorization_token": "ghp_your_github_token"
  },
  {
    "type": "github_repository",
    "url": "https://github.com/org/backend",
    "mount_path": "/workspace/backend",
    "authorization_token": "ghp_your_github_token"
  }
]'
RESOURCES_BODY=$(cat <<'EOF'
resources:
  - type: github_repository
    url: https://github.com/org/frontend
    mount_path: /workspace/frontend
    authorization_token: ghp_your_github_token
  - type: github_repository
    url: https://github.com/org/backend
    mount_path: /workspace/backend
    authorization_token: ghp_your_github_token
EOF
)
resources = [
    {
        "type": "github_repository",
        "url": "https://github.com/org/frontend",
        "mount_path": "/workspace/frontend",
        "authorization_token": "ghp_your_github_token",
    },
    {
        "type": "github_repository",
        "url": "https://github.com/org/backend",
        "mount_path": "/workspace/backend",
        "authorization_token": "ghp_your_github_token",
    },
]
const resources = [
  {
    type: "github_repository",
    url: "https://github.com/org/frontend",
    mount_path: "/workspace/frontend",
    authorization_token: "ghp_your_github_token",
  },
  {
    type: "github_repository",
    url: "https://github.com/org/backend",
    mount_path: "/workspace/backend",
    authorization_token: "ghp_your_github_token",
  },
];
BetaManagedAgentsGitHubRepositoryResourceParams[] resources =
[
    new()
    {
        Type = "github_repository",
        Url = "https://github.com/org/frontend",
        MountPath = "/workspace/frontend",
        AuthorizationToken = "ghp_your_github_token",
    },
    new()
    {
        Type = "github_repository",
        Url = "https://github.com/org/backend",
        MountPath = "/workspace/backend",
        AuthorizationToken = "ghp_your_github_token",
    },
];
resources := []anthropic.BetaSessionNewParamsResourceUnion{
	{
		OfGitHubRepository: &anthropic.BetaManagedAgentsGitHubRepositoryResourceParams{
			Type:               anthropic.BetaManagedAgentsGitHubRepositoryResourceParamsTypeGitHubRepository,
			URL:                "https://github.com/org/frontend",
			MountPath:          anthropic.String("/workspace/frontend"),
			AuthorizationToken: "ghp_your_github_token",
		},
	},
	{
		OfGitHubRepository: &anthropic.BetaManagedAgentsGitHubRepositoryResourceParams{
			Type:               anthropic.BetaManagedAgentsGitHubRepositoryResourceParamsTypeGitHubRepository,
			URL:                "https://github.com/org/backend",
			MountPath:          anthropic.String("/workspace/backend"),
			AuthorizationToken: "ghp_your_github_token",
		},
	},
}
var resources = List.of(
    BetaManagedAgentsGitHubRepositoryResourceParams.builder()
        .type(BetaManagedAgentsGitHubRepositoryResourceParams.Type.GITHUB_REPOSITORY)
        .url("https://github.com/org/frontend")
        .mountPath("/workspace/frontend")
        .authorizationToken("ghp_your_github_token")
        .build(),
    BetaManagedAgentsGitHubRepositoryResourceParams.builder()
        .type(BetaManagedAgentsGitHubRepositoryResourceParams.Type.GITHUB_REPOSITORY)
        .url("https://github.com/org/backend")
        .mountPath("/workspace/backend")
        .authorizationToken("ghp_your_github_token")
        .build());
$resources = [
    [
        'type' => 'github_repository',
        'url' => 'https://github.com/org/frontend',
        'mountPath' => '/workspace/frontend',
        'authorizationToken' => 'ghp_your_github_token',
    ],
    [
        'type' => 'github_repository',
        'url' => 'https://github.com/org/backend',
        'mountPath' => '/workspace/backend',
        'authorizationToken' => 'ghp_your_github_token',
    ],
];
resources = [
  {
    type: "github_repository",
    url: "https://github.com/org/frontend",
    mount_path: "/workspace/frontend",
    authorization_token: "ghp_your_github_token"
  },
  {
    type: "github_repository",
    url: "https://github.com/org/backend",
    mount_path: "/workspace/backend",
    authorization_token: "ghp_your_github_token"
  }
]

在运行中的会话上管理仓库

创建会话后,您可以列出其仓库资源并轮换其授权令牌。每个资源在会话创建时(或通过 resources.list)返回一个 id,用于更新操作。仓库在会话的整个生命周期内附加;要更改挂载的仓库,请创建新会话。

# List resources on the session
repo_resource_id=$(curl -fsS "https://api.anthropic.com/v1/sessions/$session_id/resources" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "content-type: application/json" | jq -r '.data[0].id')
echo "$repo_resource_id"  # "sesrsc_01ABC..."

# Rotate the authorization token
curl -fsS "https://api.anthropic.com/v1/sessions/$session_id/resources/$repo_resource_id" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "content-type: application/json" \
  -o /dev/null \
  --data @- <<JSON
{
  "authorization_token": "ghp_your_new_github_token"
}
JSON
# List resources on the session
ant beta:sessions:resources list --session-id "$SESSION_ID"

# Rotate the authorization token on a specific resource
ant beta:sessions:resources update \
  --session-id "$SESSION_ID" \
  --resource-id "$RESOURCE_ID" \
  --authorization-token "ghp_your_new_github_token"
# List resources on the session
listed = client.beta.sessions.resources.list(session.id)
repo_resource_id = listed.data[0].id
print(repo_resource_id)  # "sesrsc_01ABC..."

# Rotate the authorization token
client.beta.sessions.resources.update(
    repo_resource_id,
    session_id=session.id,
    authorization_token="ghp_your_new_github_token",
)
// List resources on the session
const listed = await client.beta.sessions.resources.list(session.id);
const repoResourceId = listed.data[0].id;
console.log(repoResourceId); // "sesrsc_01ABC..."

// Rotate the authorization token
await client.beta.sessions.resources.update(repoResourceId, {
  session_id: session.id,
  authorization_token: "ghp_your_new_github_token",
});
// List resources on the session
var listed = await client.Beta.Sessions.Resources.List(session.ID);
string repoResourceId = null!;
await foreach (var entry in listed.Paginate())
{
    repoResourceId = entry.ID;
    break;
}
Console.WriteLine(repoResourceId); // "sesrsc_01ABC..."

// Rotate the authorization token
await client.Beta.Sessions.Resources.Update(repoResourceId, new()
{
    SessionID = session.ID,
    AuthorizationToken = "ghp_your_new_github_token",
});
// List resources on the session
listed, err := client.Beta.Sessions.Resources.List(ctx, session.ID, anthropic.BetaSessionResourceListParams{})
if err != nil {
	panic(err)
}
repoResourceID := listed.Data[0].ID
fmt.Println(repoResourceID) // "sesrsc_01ABC..."

// Rotate the authorization token
_, err = client.Beta.Sessions.Resources.Update(ctx, repoResourceID, anthropic.BetaSessionResourceUpdateParams{
	SessionID:          session.ID,
	AuthorizationToken: "ghp_your_new_github_token",
})
if err != nil {
	panic(err)
}
// List resources on the session
var listed = client.beta().sessions().resources().list(session.id());
var repoResourceId = listed.data().getFirst().asGitHubRepository().id();
IO.println(repoResourceId);  // "sesrsc_01ABC..."

// Rotate the authorization token
client.beta().sessions().resources().update(repoResourceId, ResourceUpdateParams.builder()
    .sessionId(session.id())
    .authorizationToken("ghp_your_new_github_token")
    .build());
// List resources on the session
$listed = $client->beta->sessions->resources->list($session->id);
$repoResourceId = $listed->data[0]->id;
echo $repoResourceId, PHP_EOL; // "sesrsc_01ABC..."

// Rotate the authorization token
$client->beta->sessions->resources->update(
    $repoResourceId,
    sessionID: $session->id,
    authorizationToken: 'ghp_your_new_github_token',
);
# List resources on the session
listed = client.beta.sessions.resources.list(session.id)
repo_resource_id = listed.data.first.id
puts repo_resource_id # "sesrsc_01ABC..."

# Rotate the authorization token
client.beta.sessions.resources.update(
  repo_resource_id,
  session_id: session.id,
  authorization_token: "ghp_your_new_github_token"
)

创建拉取请求

使用 GitHub MCP 服务器,代理可以创建分支、提交更改并推送:

curl -fsS "https://api.anthropic.com/v1/sessions/$session_id/events" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "content-type: application/json" \
  -o /dev/null \
  --data @- <<JSON
{
  "events": [
    {
      "type": "user.message",
      "content": [
        {
          "type": "text",
          "text": "Fix the type error in src/utils.ts, commit it to a new branch, and push it."
        }
      ]
    }
  ]
}
JSON
ant beta:sessions:events send \
  --session-id "$SESSION_ID" \
  > /dev/null <<'EOF'
events:
  - type: user.message
    content:
      - type: text
        text: Fix the type error in src/utils.ts, commit it to a new branch, and push it.
EOF
client.beta.sessions.events.send(
    session.id,
    events=[
        {
            "type": "user.message",
            "content": [
                {
                    "type": "text",
                    "text": "Fix the type error in src/utils.ts, commit it to a new branch, and push it.",
                },
            ],
        },
    ],
)
await client.beta.sessions.events.send(session.id, {
  events: [
    {
      type: "user.message",
      content: [
        {
          type: "text",
          text: "Fix the type error in src/utils.ts, commit it to a new branch, and push it.",
        },
      ],
    },
  ],
});
await client.Beta.Sessions.Events.Send(session.ID, new()
{
    Events =
    [
        new BetaManagedAgentsUserMessageEventParams
        {
            Type = "user.message",
            Content =
            [
                new BetaManagedAgentsTextBlock
                {
                    Type = "text",
                    Text = "Fix the type error in src/utils.ts, commit it to a new branch, and push it.",
                },
            ],
        },
    ],
});
_, err = client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
	Events: []anthropic.BetaManagedAgentsEventParamsUnion{
		{
			OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
				Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
				Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{
					{
						OfText: &anthropic.BetaManagedAgentsTextBlockParam{
							Type: anthropic.BetaManagedAgentsTextBlockTypeText,
							Text: "Fix the type error in src/utils.ts, commit it to a new branch, and push it.",
						},
					},
				},
			},
		},
	},
})
if err != nil {
	panic(err)
}
client.beta().sessions().events().send(session.id(), EventSendParams.builder()
    .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
        .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
        .addContent(BetaManagedAgentsTextBlock.builder()
            .type(BetaManagedAgentsTextBlock.Type.TEXT)
            .text("Fix the type error in src/utils.ts, commit it to a new branch, and push it.")
            .build())
        .build())
    .build());
$client->beta->sessions->events->send(
    $session->id,
    events: [
        [
            'type' => 'user.message',
            'content' => [
                [
                    'type' => 'text',
                    'text' => 'Fix the type error in src/utils.ts, commit it to a new branch, and push it.',
                ],
            ],
        ],
    ],
);
client.beta.sessions.events.send_(
  session.id,
  events: [
    {
      type: "user.message",
      content: [
        {
          type: "text",
          text: "Fix the type error in src/utils.ts, commit it to a new branch, and push it."
        }
      ]
    }
  ]
)