Skip to content

feat: add bulk mutations, field clearing, and robustness fixes#32

Merged
BigLep merged 7 commits into
masterfrom
biglep/bulk-set-board-item-field
May 4, 2026
Merged

feat: add bulk mutations, field clearing, and robustness fixes#32
BigLep merged 7 commits into
masterfrom
biglep/bulk-set-board-item-field

Conversation

@BigLep
Copy link
Copy Markdown
Contributor

@BigLep BigLep commented Apr 27, 2026

Background

This was the set of changes/improvements I needed while building out #34.

Summary

  • bulk_set_board_item_field MCP tool: Sets a single field+value on multiple items in one call. Resolves field info once and batches GraphQL mutations in groups of 25 using aliased queries.
  • Field clearing support: Passing an empty value clears the field (uses clearProjectV2ItemFieldValue mutation).
  • Node ID fast path: Accepts PVTI_-prefixed node IDs directly to skip per-item REST lookups — useful when IDs are already known from a prior list_board_items call.
  • Shared client refactoring: set_field_value is now a thin wrapper around set_field_value_bulk, reducing duplication.
  • Copilot review fixes: Bumped GraphQL field limits from 50→100 in fields.py and views.py, added null-project guard in fields.py, renamed result key "item""item_ref" to match the data-model contract.
  • Docstring improvements: Clarified list_board_items query parameter naming and documented how to obtain node IDs for bulk operations.

Files changed

File Change
github-projects-client/.../mutations.py New set_field_value_bulk() with batched aliased mutations, clear support, node ID fast path; set_field_value() refactored as wrapper
github-projects-client/.../__init__.py Export set_field_value_bulk
github-projects-client/.../fields.py Bump field limit 50→100, add null project guard
github-projects-client/.../views.py Bump field limit 50→100
github-projects-client/.../items.py Docstring clarification for query param
github-projects-client/tests/test_integration.py Integration test for Node ID synthetic field
github-projects-client/tests/test_items_unit.py New unit tests for items module
filozzy-mcp/filozzy_mcp/server.py New bulk_set_board_item_field tool with action logging

Test plan

  • All 38 existing tests pass (test_integration.py, test_items_unit.py, test_filozzy_mcp.py, test_foc_pr_report.py)
  • Manual test: bulk set Cycle Theme on 2-3 items via MCP
  • Verify action log entries are per-item after bulk operation

Additional Notes

Before merging, this should be retargeted to master after #31 lands.

🤖 Generated with Claude Code

@FilOzzy FilOzzy added this to FOC Apr 27, 2026
@github-project-automation github-project-automation Bot moved this to 📌 Triage in FOC Apr 27, 2026
@BigLep BigLep moved this from 📌 Triage to 🔎 Awaiting review in FOC Apr 28, 2026
@BigLep BigLep self-assigned this Apr 28, 2026
@BigLep BigLep marked this pull request as draft April 29, 2026 14:30
@BigLep BigLep moved this from 🔎 Awaiting review to 🐱 Todo in FOC Apr 29, 2026
@BigLep BigLep moved this from 🐱 Todo to ⌨️ In Progress in FOC Apr 29, 2026
@BigLep BigLep force-pushed the 003-generalize-mcp-client branch from f9abf5d to 6c84654 Compare May 4, 2026 02:59
@BigLep BigLep requested a review from Copilot May 4, 2026 03:01
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR generalizes the GitHub Projects integration work across the repo by introducing a reusable github-projects-client package, updating filozzy-mcp and foc-pr-report to depend on it, and adding a root test runner. It also adds a new bulk field-mutation capability intended to make repeated board updates much more efficient.

Changes:

  • Added a new shared github-projects-client package with API, field, item, view, and mutation helpers plus integration tests and README.
  • Refactored filozzy-mcp to use the shared client, added env-based board configuration, and introduced bulk_set_board_item_field.
  • Migrated foc-pr-report and github-project-export off the old FOC-specific client; added repo-wide test runner and updated documentation/spec artifacts.

Reviewed changes

Copilot reviewed 35 out of 41 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
specs/003-generalize-mcp-client/tasks.md New task breakdown for the generalization work.
specs/003-generalize-mcp-client/spec.md Feature spec describing board-agnostic client/server goals.
specs/003-generalize-mcp-client/research.md Research decisions for package structure and migration.
specs/003-generalize-mcp-client/quickstart.md Setup and migration quickstart for the new layout.
specs/003-generalize-mcp-client/plan.md Implementation plan for the shared client refactor.
specs/003-generalize-mcp-client/data-model.md Data model for board config, items, fields, and mutation results.
specs/003-generalize-mcp-client/contracts/shared-client-api.md Contract for the new shared client API.
specs/003-generalize-mcp-client/contracts/mcp-tools.md Contract for MCP-layer behavior and logging.
specs/003-generalize-mcp-client/checklists/requirements.md Spec quality checklist for the feature.
scripts/test-all.sh Root-level script to run tests across packages.
github-projects-client/tests/test_integration.py New integration coverage for shared-client read APIs.
github-projects-client/tests/init.py Test package marker for shared client.
github-projects-client/pyproject.toml Package metadata and pytest config for shared client.
github-projects-client/github_projects_client/views.py New view URL resolution helper.
github-projects-client/github_projects_client/mutations.py New shared mutation logic, including bulk updates.
github-projects-client/github_projects_client/items.py Shared item listing, formatting, and lookup logic.
github-projects-client/github_projects_client/fields.py Shared field metadata and option discovery logic.
github-projects-client/github_projects_client/api.py Shared GraphQL/REST transport helpers.
github-projects-client/github_projects_client/init.py Public exports for the shared client package.
github-projects-client/README.md Usage docs for the new shared client.
github-project-export/uv.lock Lockfile updated for shared-client dependency.
github-project-export/pyproject.toml Swapped dependency from foc-pr-report to shared client.
github-project-export/github_project_export/rest_export.py Updated imports to consume shared-client REST helpers.
foc_wg_pr_notifier.py Updated notifier import to pr_enrichment.
foc-pr-report/uv.lock Lockfile updated for shared-client dependency and test deps.
foc-pr-report/tests/test_integration.py New end-to-end regression test for PR report pipeline.
foc-pr-report/tests/init.py Test package marker for PR report.
foc-pr-report/pyproject.toml Added shared-client dependency and pytest config.
foc-pr-report/foc_pr_report/report.py Switched report logic to pr_enrichment.
foc-pr-report/foc_pr_report/pr_enrichment.py New home for PR-report-specific enrichment logic.
foc-pr-report/foc_pr_report/foc_project14_client.py Reduced old client to a backward-compatibility shim.
foc-pr-report/foc_pr_report/cli.py Switched CLI imports to pr_enrichment.
filozzy-mcp/uv.lock Lockfile updated for shared-client dependency.
filozzy-mcp/tests/test_integration.py Narrowed MCP tests to MCP-layer concerns.
filozzy-mcp/pyproject.toml Replaced dependency on foc-pr-report with shared client.
filozzy-mcp/filozzy_mcp/server.py Refactored MCP tools onto shared client; added bulk mutation tool and env config.
filozzy-mcp/filozzy_mcp/mutation_tools.py Removed old MCP-local mutation implementation.
filozzy-mcp/README.md Updated docs for board-agnostic MCP setup and architecture.
README.md Root README updated to describe new shared client and test runner.
CLAUDE.md Added active technology notes for this feature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread github-projects-client/github_projects_client/fields.py Outdated
Comment thread github-projects-client/github_projects_client/fields.py Outdated
Comment thread github-projects-client/github_projects_client/views.py Outdated
Comment thread github-projects-client/github_projects_client/mutations.py
Comment thread github-projects-client/github_projects_client/mutations.py
@BigLep BigLep force-pushed the biglep/bulk-set-board-item-field branch from 7692874 to 8e31903 Compare May 4, 2026 03:13
@BigLep BigLep marked this pull request as ready for review May 4, 2026 03:13
@BigLep BigLep requested a review from rjan90 May 4, 2026 03:13
@BigLep BigLep moved this from ⌨️ In Progress to 🔎 Awaiting review in FOC May 4, 2026
Comment thread filozzy-mcp/filozzy_mcp/server.py Outdated
Copy link
Copy Markdown
Contributor

@rjan90 rjan90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment on the Python compatibility issue, once that is addressed. This LGTM

@github-project-automation github-project-automation Bot moved this from 🔎 Awaiting review to ✔️ Approved by reviewer in FOC May 4, 2026
@BigLep BigLep changed the title feat: add bulk_set_board_item_field for batch mutations feat: add bulk mutations, field clearing, and robustness fixes May 4, 2026
BigLep and others added 7 commits May 4, 2026 09:25
Add set_field_value_bulk to the shared client, which resolves field info
once and batches GraphQL mutations using aliases (groups of 25). The
existing set_field_value is now a thin wrapper around the bulk function.

Also adds query filter tips to the list_board_items tool description to
help LLMs use targeted queries like -has:"cycle-theme" instead of
fetching all items and scanning manually.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
set_board_item_field and bulk_set_board_item_field now accept an empty
string ("") as the value to clear a field. Uses the GraphQL
clearProjectV2ItemFieldValue mutation with batched aliases for bulk ops.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The filter is passed via `query`, not `filter`. FastMCP silently ignores
unknown parameters, so passing `filter` would fall back to defaults with
no error — a subtle footgun. Updated the docstring to make this explicit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ookup

When item_refs contain raw project item node IDs (PVTI_ strings), the
bulk operation skips the get_item() lookup for those entries. Also adds
"Node ID" as a requestable synthetic field in list_items so callers can
obtain node IDs for follow-up mutations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bump GraphQL field limits from 50 to 100, add null project check
in fields.py, and rename result key from "item" to "item_ref" to
match the data-model contract.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract string fragments into local variables before interpolation,
since f-string expressions cannot contain backslashes on Python <3.12.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@BigLep BigLep changed the base branch from 003-generalize-mcp-client to master May 4, 2026 16:26
@BigLep BigLep force-pushed the biglep/bulk-set-board-item-field branch from ec9da64 to 7d2c09d Compare May 4, 2026 16:26
@BigLep BigLep merged commit 904f3ea into master May 4, 2026
@github-project-automation github-project-automation Bot moved this from ✔️ Approved by reviewer to 🎉 Done in FOC May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🎉 Done

Development

Successfully merging this pull request may close these issues.

4 participants