Skip to content

Commit e65f52e

Browse files
committed
tool changes
1 parent 8c306ae commit e65f52e

File tree

3 files changed

+1
-259
lines changed

3 files changed

+1
-259
lines changed

pkg/github/instructions.go

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -62,79 +62,6 @@ Check 'list_issue_types' first for organizations to use proper issue types. Use
6262
return `## Discussions
6363
6464
Use 'list_discussion_categories' to understand available categories before creating discussions. Filter by category for better organization.`
65-
case "projects":
66-
return `## Projects
67-
68-
Workflow: 1) list_project_fields (get field IDs), 2) list_project_items (with pagination), 3) optional updates.
69-
70-
Field usage:
71-
- Call list_project_fields first to understand available fields and get IDs/types before filtering.
72-
- Use EXACT returned field names (case-insensitive match). Don't invent names or IDs.
73-
- Iteration synonyms (sprint/cycle) only if that field exists; map to the actual name (e.g. sprint:@current).
74-
- Only include filters for fields that exist and are relevant.
75-
76-
Pagination (mandatory):
77-
- Loop while pageInfo.hasNextPage=true using after=pageInfo.nextCursor.
78-
- Keep query, fields, per_page IDENTICAL on every page.
79-
- Use before=pageInfo.prevCursor only when explicitly navigating to a previous page.
80-
- Do not analyze until ALL pages fetched.
81-
82-
Counting rules:
83-
- Count items array length after full pagination.
84-
- If multi-page: collect all pages, dedupe by item.id (fallback node_id) before totals.
85-
- Never count field objects, content, or nested arrays as separate items.
86-
- item.id = project item ID (for updates/deletes). item.content.id = underlying issue/PR ID.
87-
88-
Summary vs list:
89-
- Summaries ONLY if user uses verbs: analyze | summarize | summary | report | overview | insights.
90-
- Listing verbs (list/show/get/fetch/display/enumerate) → enumerate + total.
91-
92-
Self-check before returning:
93-
- Paginated fully
94-
- Dedupe by id/node_id
95-
- Correct IDs used
96-
- Field names valid
97-
- Summary only if requested.
98-
99-
Return COMPLETE data or state what's missing (e.g. pages skipped).
100-
101-
list_project_items query rules:
102-
Query string - For advanced filtering of project items using GitHub's project filtering syntax:
103-
104-
MUST reflect user intent; strongly prefer explicit content type if narrowed:
105-
- "open issues" → state:open is:issue
106-
- "merged PRs" → state:merged is:pr
107-
- "items updated this week" → updated:>@today-7d (omit type only if mixed desired)
108-
- "list all P1 priority items" → priority:p1 (omit state if user wants all, omit type if user specifies "items")
109-
- "list all open P2 issues" → is:issue state:open priority:p2 (include state if user wants open or closed, include type if user specifies "issues" or "PRs")
110-
- "all open issues I'm working on" → is:issue state:open assignee:@me
111-
112-
Query Construction Heuristics:
113-
a. Extract type nouns: issues → is:issue | PRs, Pulls, or Pull Requests → is:pr | tasks/tickets → is:issue (ask if ambiguity)
114-
b. Map temporal phrases: "this week" → updated:>@today-7d
115-
c. Map negations: "excluding wontfix" → -label:wontfix
116-
d. Map priority adjectives: "high/sev1/p1" → priority:high OR priority:p1 (choose based on field presence)
117-
e. When filtering by label, always use wildcard matching to account for cross-repository differences or emojis: (e.g. "bug 🐛" → label:*bug*)
118-
f. When filtering by milestone, always use wildcard matching to account for cross-repository differences: (e.g. "v1.0" → milestone:*v1.0*)
119-
120-
Syntax Essentials (items):
121-
AND: space-separated. (label:bug priority:high).
122-
OR: comma inside one qualifier (label:bug,critical).
123-
NOT: leading '-' (-label:wontfix).
124-
Hyphenate multi-word field names. (team-name:"Backend Team", story-points:>5).
125-
Quote multi-word values. (status:"In Review" team-name:"Backend Team").
126-
Ranges: points:1..3, updated:<@today-30d.
127-
Wildcards: title:*crash*, label:bug*.
128-
Assigned to User: assignee:@me | assignee:username | no:assignee
129-
130-
Common Qualifier Glossary (items):
131-
is:issue | is:pr | state:open|closed|merged | assignee:@me|username | label:NAME | status:VALUE |
132-
priority:p1|high | sprint-name:@current | team-name:"Backend Team" | parent-issue:"org/repo#123" |
133-
updated:>@today-7d | title:*text* | -label:wontfix | label:bug,critical | no:assignee | has:label
134-
135-
Never:
136-
- Infer field IDs; fetch via list_project_fields.
137-
- Drop 'fields' param on subsequent pages if field values are needed.`
13865
default:
13966
return ""
14067
}

pkg/github/projects.go

Lines changed: 0 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,186 +1066,3 @@ func addOptions(s string, opts any) (string, error) {
10661066
origURL.RawQuery = origValues.Encode()
10671067
return origURL.String(), nil
10681068
}
1069-
1070-
func ManageProjectItemsPrompt(t translations.TranslationHelperFunc) (tool mcp.Prompt, handler server.PromptHandlerFunc) {
1071-
return mcp.NewPrompt("ManageProjectItems",
1072-
mcp.WithPromptDescription(t("PROMPT_MANAGE_PROJECT_ITEMS_DESCRIPTION", "Guide for GitHub Projects V2: discovery, fields, querying, updates.")),
1073-
mcp.WithArgument("owner", mcp.ArgumentDescription("The owner of the project (user or organization name)"), mcp.RequiredArgument()),
1074-
mcp.WithArgument("owner_type", mcp.ArgumentDescription("Type of owner: 'user' or 'org'"), mcp.RequiredArgument()),
1075-
), func(_ context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
1076-
owner := request.Params.Arguments["owner"]
1077-
ownerType := request.Params.Arguments["owner_type"]
1078-
1079-
task := ""
1080-
if t, exists := request.Params.Arguments["task"]; exists {
1081-
task = fmt.Sprintf("%v", t)
1082-
}
1083-
1084-
messages := []mcp.PromptMessage{
1085-
{
1086-
Role: "system",
1087-
Content: mcp.NewTextContent(`System guide: GitHub Projects V2.
1088-
Goal: Pick correct tool, fetch COMPLETE data (no early pagination stop), apply accurate filters, and count items correctly.
1089-
1090-
Core rules:
1091-
- list_projects: NEVER include item-level filters (no is:issue, assignee:, label:, etc.)
1092-
- Before filtering on fields, call list_project_fields to get field IDs
1093-
- Always paginate until pageInfo.hasNextPage=false
1094-
- Keep query, fields, per_page identical across pages
1095-
- Include field IDs on every list_project_items page if you need values
1096-
- Prefer explicit is:issue / is:pr unless mixed set requested
1097-
- Only summarize if verbs like analyze / summarize / report / overview / insights appear; otherwise enumerate
1098-
1099-
Field resolution:
1100-
- Use exact returned field names; don't invent
1101-
- Iteration synonyms map to actual existing name (Sprint → sprint:@current, etc.). If none exist, omit
1102-
- Only add filters for fields that exist and matter to the user goal
1103-
1104-
Query syntax essentials:
1105-
AND space | OR comma | NOT prefix - | quote multi-word values | hyphenate names | ranges points:1..5 | comparisons updated:>@today-7d priority:>1 | wildcards title:*crash*
1106-
1107-
Pagination pattern:
1108-
Call list_project_items → if hasNextPage true, repeat with after=nextCursor → stop only when false → then count/deduplicate
1109-
1110-
Counting:
1111-
- Items array length after full pagination (dedupe by item.id or node_id)
1112-
- Never count fields array, content, assignees, labels as separate items
1113-
- item.id = project item identifier; content.id = underlying issue/PR id
1114-
1115-
Edge handling:
1116-
Empty pages → total=0 still return pageInfo
1117-
Duplicates → keep first for totals
1118-
Missing field values → null/omit, never fabricate
1119-
1120-
Self-check: paginated? deduped? correct IDs? field names valid? summary allowed?`),
1121-
},
1122-
{
1123-
Role: "user",
1124-
Content: mcp.NewTextContent(fmt.Sprintf("I want to work with GitHub Projects for %s (owner_type: %s).%s",
1125-
owner,
1126-
ownerType,
1127-
func() string {
1128-
if task != "" {
1129-
return fmt.Sprintf(" Focus: %s.", task)
1130-
}
1131-
return ""
1132-
}())),
1133-
},
1134-
{
1135-
Role: "assistant",
1136-
Content: mcp.NewTextContent("Start by listing projects: use list_projects tool with owner and owner_type parameters."),
1137-
},
1138-
{
1139-
Role: "user",
1140-
Content: mcp.NewTextContent("How do I work with fields and items?"),
1141-
},
1142-
{
1143-
Role: "assistant",
1144-
Content: mcp.NewTextContent(`Fields & items workflow:
1145-
1. Call list_project_fields to get field definitions → map lowercased name -> {id,type}
1146-
2. Use only existing field names; no invention
1147-
3. Iteration mapping: pick sprint/cycle/iteration only if present (sprint:@current etc.)
1148-
4. Include only relevant fields (e.g. Priority + Label for high priority bugs)
1149-
5. Build query after resolving fields ("last week" → updated:>@today-7d)
1150-
6. Call list_project_items with query and field IDs → paginate until hasNextPage=false
1151-
7. Keep query/fields/per_page stable across all pages
1152-
8. Include field IDs on every page when you need their values
1153-
Missing field? Omit or clarify—never guess.`),
1154-
},
1155-
{
1156-
Role: "user",
1157-
Content: mcp.NewTextContent("How do I update item field values?"),
1158-
},
1159-
{
1160-
Role: "assistant",
1161-
Content: mcp.NewTextContent(`Updating fields (update_project_item tool):
1162-
Input format: updated_field parameter with {id: <field_id>, value: <new_value>}
1163-
Examples:
1164-
- Text field: {"id":123,"value":"hello"}
1165-
- Single-select: {"id":456,"value":789} (value is option ID, not name)
1166-
- Number: {"id":321,"value":5}
1167-
- Date: {"id":654,"value":"2025-03-15"}
1168-
- Clear field: {"id":123,"value":null}
1169-
1170-
Rules:
1171-
- item_id parameter = project item ID (from list_project_items), NOT issue/PR ID
1172-
- Get field IDs from list_project_fields first
1173-
- For select/iteration fields, pass option/iteration ID as value, not the name
1174-
- To add an item first: use add_project_item tool with issue/PR ID
1175-
- To remove an item: use delete_project_item tool`),
1176-
},
1177-
{
1178-
Role: "user",
1179-
Content: mcp.NewTextContent("Show me a workflow example."),
1180-
},
1181-
{
1182-
Role: "assistant",
1183-
Content: mcp.NewTextContent(`Workflow example:
1184-
1. list_projects → pick project_number
1185-
2. list_project_fields → build field map {name: {id, type}}
1186-
3. Build query (e.g. is:issue sprint:@current priority:high updated:>@today-7d)
1187-
4. list_project_items with field IDs → paginate fully (loop until hasNextPage=false)
1188-
5. Optional: get_project_item for specific item details
1189-
6. Optional: add_project_item to add issue/PR to project
1190-
7. Optional: update_project_item to change field values for an item
1191-
8. Optional: delete_project_item to remove from an item from project
1192-
1193-
Important:
1194-
- Iteration filter must match existing field name
1195-
- Keep fields parameter consistent across pages
1196-
- Summarize only if explicitly asked
1197-
- item_id for updates/deletes comes from list_project_items response
1198-
- content.id in items is the underlying issue/PR ID (use with add_project_item)`),
1199-
},
1200-
{
1201-
Role: "user",
1202-
Content: mcp.NewTextContent("How do I handle pagination?"),
1203-
},
1204-
{
1205-
Role: "assistant",
1206-
Content: mcp.NewTextContent(`Pagination with list_project_items:
1207-
1. Make initial call with query, fields, per_page parameters
1208-
2. Check response pageInfo.hasNextPage
1209-
3. If true: call again with same query/fields/per_page + after=pageInfo.nextCursor
1210-
4. Repeat step 2-3 until hasNextPage=false
1211-
5. Collect all items from all pages before counting/analyzing
1212-
1213-
Critical: Do NOT change query, fields, or per_page between pages. Always include same field IDs on every page if you need field values.`),
1214-
},
1215-
{
1216-
Role: "user",
1217-
Content: mcp.NewTextContent("How do I get more details about items?"),
1218-
},
1219-
{
1220-
Role: "assistant",
1221-
Content: mcp.NewTextContent(`Getting additional item details:
1222-
1223-
- First inspect item's content object for info, e.g. title, assignees, labels
1224-
- If additional detail is needed, and relevant fields are present from list_project_fields, include their IDs in list_project_items and request with list_project_items again.
1225-
- If more detail needed, use separate issue/PR tools`),
1226-
},
1227-
{
1228-
Role: "assistant",
1229-
Content: mcp.NewTextContent(`Query patterns for list_project_items:
1230-
1231-
Common scenarios:
1232-
- Blocked issues: is:issue (label:blocked OR status:"Blocked")
1233-
- Overdue tasks: is:issue due-date:<@today state:open
1234-
- PRs ready for review: is:pr review-status:"Ready for Review" state:open
1235-
- Stale issues: is:issue updated:<@today-30d state:open
1236-
- High priority bugs: is:issue label:bug priority:high state:open
1237-
- Team sprint PRs: is:pr team-name:"Backend Team" sprint:@current
1238-
1239-
Rules:
1240-
- Summarize only if user requests it with verbs like "analyze", "summarize", "report"
1241-
- Deduplicate by item.id before counting totals
1242-
- Quote multi-word values: status:"In Progress"
1243-
- Never invent field names or IDs - always verify with list_project_fields first
1244-
- Use explicit is:issue or is:pr unless user wants mixed items`),
1245-
},
1246-
}
1247-
return &mcp.GetPromptResult{
1248-
Messages: messages,
1249-
}, nil
1250-
}
1251-
}

pkg/github/tools.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,7 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
328328
toolsets.NewServerTool(AddProjectItem(getClient, t)),
329329
toolsets.NewServerTool(DeleteProjectItem(getClient, t)),
330330
toolsets.NewServerTool(UpdateProjectItem(getClient, t)),
331-
).AddPrompts(
332-
toolsets.NewServerPrompt(ManageProjectItemsPrompt(t)),
333-
)
331+
)
334332
stargazers := toolsets.NewToolset(ToolsetMetadataStargazers.ID, ToolsetMetadataStargazers.Description).
335333
AddReadTools(
336334
toolsets.NewServerTool(ListStarredRepositories(getClient, t)),

0 commit comments

Comments
 (0)