Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9878a8a

Browse files
add in e2e and also try to get the LLM to call notifications off its own back
1 parentd49b7a6 commit9878a8a

File tree

2 files changed

+249
-1
lines changed

2 files changed

+249
-1
lines changed

‎e2e/e2e_test.go

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,3 +1525,251 @@ func TestPullRequestReviewDeletion(t *testing.T) {
15251525
require.NoError(t,err,"expected to unmarshal text content successfully")
15261526
require.Len(t,noReviews,0,"expected to find no reviews")
15271527
}
1528+
1529+
funcTestE2E_ListNotifications(t*testing.T) {
1530+
t.Parallel()
1531+
client:=setupMCPClient(t)
1532+
ctx:=context.Background()
1533+
1534+
request:= mcp.CallToolRequest{}
1535+
request.Params.Name="list_notifications"
1536+
request.Params.Arguments=map[string]any{}
1537+
1538+
resp,err:=client.CallTool(ctx,request)
1539+
require.NoError(t,err,"expected to call 'list_notifications' tool successfully")
1540+
require.False(t,resp.IsError,fmt.Sprintf("expected result not to be an error: %+v",resp))
1541+
require.Len(t,resp.Content,1,"expected content to have one item")
1542+
1543+
varnotifications []struct {
1544+
IDstring`json:"id"`
1545+
}
1546+
textContent,ok:=resp.Content[0].(mcp.TextContent)
1547+
require.True(t,ok,"expected content to be of type TextContent")
1548+
err=json.Unmarshal([]byte(textContent.Text),&notifications)
1549+
require.NoError(t,err,"expected to unmarshal text content successfully")
1550+
}
1551+
1552+
funcTestE2E_ManageNotificationSubscription(t*testing.T) {
1553+
t.Parallel()
1554+
client:=setupMCPClient(t)
1555+
ctx:=context.Background()
1556+
1557+
// List notifications to get a valid notificationID
1558+
listReq:= mcp.CallToolRequest{}
1559+
listReq.Params.Name="list_notifications"
1560+
listReq.Params.Arguments=map[string]any{}
1561+
resp,err:=client.CallTool(ctx,listReq)
1562+
require.NoError(t,err)
1563+
require.False(t,resp.IsError)
1564+
iflen(resp.Content)==0 {
1565+
returnt.Skip("No notifications available to test subscription management")
1566+
}
1567+
textContent,ok:=resp.Content[0].(mcp.TextContent)
1568+
require.True(t,ok)
1569+
varnotifications []struct {
1570+
IDstring`json:"id"`
1571+
}
1572+
err=json.Unmarshal([]byte(textContent.Text),&notifications)
1573+
require.NoError(t,err)
1574+
require.NotEmpty(t,notifications)
1575+
notificationID:=notifications[0].ID
1576+
1577+
// Ignore notification
1578+
ignoreReq:= mcp.CallToolRequest{}
1579+
ignoreReq.Params.Name="manage_notification_subscription"
1580+
ignoreReq.Params.Arguments=map[string]any{
1581+
"notificationID":notificationID,
1582+
"action":"ignore",
1583+
}
1584+
resp,err=client.CallTool(ctx,ignoreReq)
1585+
require.NoError(t,err)
1586+
require.False(t,resp.IsError)
1587+
textContent,ok=resp.Content[0].(mcp.TextContent)
1588+
require.True(t,ok)
1589+
require.Contains(t,textContent.Text,"ignored")
1590+
1591+
// Watch notification
1592+
watchReq:= mcp.CallToolRequest{}
1593+
watchReq.Params.Name="manage_notification_subscription"
1594+
watchReq.Params.Arguments=map[string]any{
1595+
"notificationID":notificationID,
1596+
"action":"watch",
1597+
}
1598+
resp,err=client.CallTool(ctx,watchReq)
1599+
require.NoError(t,err)
1600+
require.False(t,resp.IsError)
1601+
textContent,ok=resp.Content[0].(mcp.TextContent)
1602+
require.True(t,ok)
1603+
require.Contains(t,textContent.Text,"subscribed")
1604+
1605+
// Delete notification subscription
1606+
deleteReq:= mcp.CallToolRequest{}
1607+
deleteReq.Params.Name="manage_notification_subscription"
1608+
deleteReq.Params.Arguments=map[string]any{
1609+
"notificationID":notificationID,
1610+
"action":"delete",
1611+
}
1612+
resp,err=client.CallTool(ctx,deleteReq)
1613+
require.NoError(t,err)
1614+
require.False(t,resp.IsError)
1615+
textContent,ok=resp.Content[0].(mcp.TextContent)
1616+
require.True(t,ok)
1617+
require.Contains(t,textContent.Text,"deleted")
1618+
}
1619+
1620+
funcTestE2E_ManageRepositoryNotificationSubscription(t*testing.T) {
1621+
t.Parallel()
1622+
client:=setupMCPClient(t)
1623+
ctx:=context.Background()
1624+
1625+
// Use a well-known repo for the test (e.g., the user's own repo)
1626+
owner:="github"
1627+
repo:="github-mcp-server"
1628+
1629+
// Ignore repo notifications
1630+
ignoreReq:= mcp.CallToolRequest{}
1631+
ignoreReq.Params.Name="manage_repository_notification_subscription"
1632+
ignoreReq.Params.Arguments=map[string]any{
1633+
"owner":owner,
1634+
"repo":repo,
1635+
"action":"ignore",
1636+
}
1637+
resp,err:=client.CallTool(ctx,ignoreReq)
1638+
require.NoError(t,err)
1639+
require.False(t,resp.IsError)
1640+
textContent,ok:=resp.Content[0].(mcp.TextContent)
1641+
require.True(t,ok)
1642+
require.Contains(t,textContent.Text,"ignored")
1643+
1644+
// Watch repo notifications
1645+
watchReq:= mcp.CallToolRequest{}
1646+
watchReq.Params.Name="manage_repository_notification_subscription"
1647+
watchReq.Params.Arguments=map[string]any{
1648+
"owner":owner,
1649+
"repo":repo,
1650+
"action":"watch",
1651+
}
1652+
resp,err=client.CallTool(ctx,watchReq)
1653+
require.NoError(t,err)
1654+
require.False(t,resp.IsError)
1655+
textContent,ok=resp.Content[0].(mcp.TextContent)
1656+
require.True(t,ok)
1657+
require.Contains(t,textContent.Text,"subscribed")
1658+
1659+
// Delete repo notification subscription
1660+
deleteReq:= mcp.CallToolRequest{}
1661+
deleteReq.Params.Name="manage_repository_notification_subscription"
1662+
deleteReq.Params.Arguments=map[string]any{
1663+
"owner":owner,
1664+
"repo":repo,
1665+
"action":"delete",
1666+
}
1667+
resp,err=client.CallTool(ctx,deleteReq)
1668+
require.NoError(t,err)
1669+
require.False(t,resp.IsError)
1670+
textContent,ok=resp.Content[0].(mcp.TextContent)
1671+
require.True(t,ok)
1672+
require.Contains(t,textContent.Text,"deleted")
1673+
}
1674+
1675+
funcTestE2E_DismissNotification(t*testing.T) {
1676+
t.Parallel()
1677+
client:=setupMCPClient(t)
1678+
ctx:=context.Background()
1679+
1680+
// List notifications to get a valid threadID
1681+
listReq:= mcp.CallToolRequest{}
1682+
listReq.Params.Name="list_notifications"
1683+
listReq.Params.Arguments=map[string]any{}
1684+
resp,err:=client.CallTool(ctx,listReq)
1685+
require.NoError(t,err)
1686+
require.False(t,resp.IsError)
1687+
iflen(resp.Content)==0 {
1688+
returnt.Skip("No notifications available to test dismissal")
1689+
}
1690+
textContent,ok:=resp.Content[0].(mcp.TextContent)
1691+
require.True(t,ok)
1692+
varnotifications []struct {
1693+
IDstring`json:"id"`
1694+
}
1695+
err=json.Unmarshal([]byte(textContent.Text),&notifications)
1696+
require.NoError(t,err)
1697+
require.NotEmpty(t,notifications)
1698+
threadID:=notifications[0].ID
1699+
1700+
// Dismiss notification (mark as read)
1701+
dismissReq:= mcp.CallToolRequest{}
1702+
dismissReq.Params.Name="dismiss_notification"
1703+
dismissReq.Params.Arguments=map[string]any{
1704+
"threadID":threadID,
1705+
"state":"read",
1706+
}
1707+
resp,err=client.CallTool(ctx,dismissReq)
1708+
require.NoError(t,err)
1709+
require.False(t,resp.IsError)
1710+
textContent,ok=resp.Content[0].(mcp.TextContent)
1711+
require.True(t,ok)
1712+
require.Contains(t,textContent.Text,"read")
1713+
}
1714+
1715+
funcTestE2E_MarkAllNotificationsRead(t*testing.T) {
1716+
t.Parallel()
1717+
client:=setupMCPClient(t)
1718+
ctx:=context.Background()
1719+
1720+
// Limit to notifications updated within the last hour
1721+
oneHourAgo:=nowMinusOneHourRFC3339()
1722+
markAllReq:= mcp.CallToolRequest{}
1723+
markAllReq.Params.Name="mark_all_notifications_read"
1724+
markAllReq.Params.Arguments=map[string]any{
1725+
"since":oneHourAgo,
1726+
}
1727+
resp,err:=client.CallTool(ctx,markAllReq)
1728+
require.NoError(t,err)
1729+
require.False(t,resp.IsError)
1730+
textContent,ok:=resp.Content[0].(mcp.TextContent)
1731+
require.True(t,ok)
1732+
require.Contains(t,textContent.Text,"All notifications marked as read")
1733+
1734+
}
1735+
1736+
// nowMinusOneHourRFC3339 returns the RFC3339 timestamp for one hour ago from now (UTC)
1737+
funcnowMinusOneHourRFC3339()string {
1738+
returntime.Now().UTC().Add(-1*time.Hour).Format(time.RFC3339)
1739+
}
1740+
1741+
funcTestE2E_GetNotificationDetails(t*testing.T) {
1742+
t.Parallel()
1743+
client:=setupMCPClient(t)
1744+
ctx:=context.Background()
1745+
1746+
// List notifications to get a valid notificationID
1747+
listReq:= mcp.CallToolRequest{}
1748+
listReq.Params.Name="list_notifications"
1749+
listReq.Params.Arguments=map[string]any{}
1750+
resp,err:=client.CallTool(ctx,listReq)
1751+
require.NoError(t,err)
1752+
require.False(t,resp.IsError)
1753+
textContent,ok:=resp.Content[0].(mcp.TextContent)
1754+
require.True(t,ok)
1755+
varnotifications []struct {
1756+
IDstring`json:"id"`
1757+
}
1758+
err=json.Unmarshal([]byte(textContent.Text),&notifications)
1759+
require.NoError(t,err)
1760+
require.NotEmpty(t,notifications)
1761+
notificationID:=notifications[0].ID
1762+
1763+
// Get notification details
1764+
detailsReq:= mcp.CallToolRequest{}
1765+
detailsReq.Params.Name="get_notification_details"
1766+
detailsReq.Params.Arguments=map[string]any{
1767+
"notificationID":notificationID,
1768+
}
1769+
resp,err=client.CallTool(ctx,detailsReq)
1770+
require.NoError(t,err)
1771+
require.False(t,resp.IsError)
1772+
textContent,ok=resp.Content[0].(mcp.TextContent)
1773+
require.True(t,ok)
1774+
require.Contains(t,textContent.Text,notificationID)
1775+
}

‎pkg/github/notifications.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const (
2424
// ListNotifications creates a tool to list notifications for the current user.
2525
funcListNotifications(getClientGetClientFn,t translations.TranslationHelperFunc) (tool mcp.Tool,handler server.ToolHandlerFunc) {
2626
returnmcp.NewTool("list_notifications",
27-
mcp.WithDescription(t("TOOL_LIST_NOTIFICATIONS_DESCRIPTION","List current notifications for the authenticated GitHub user")),
27+
mcp.WithDescription(t("TOOL_LIST_NOTIFICATIONS_DESCRIPTION","List current notifications for the authenticated GitHub user, check these from time to time, especially if you know the user is involved in discussions, issues or pull requests.")),
2828
mcp.WithToolAnnotation(mcp.ToolAnnotation{
2929
Title:t("TOOL_LIST_NOTIFICATIONS_USER_TITLE","List notifications"),
3030
ReadOnlyHint:toBoolPtr(true),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp