Skip to content

Add nameFilter to get_cards_by_list_id - #76

Merged
delorenj merged 2 commits into
delorenj:mainfrom
peteanning:feat/name-filter-get-cards-by-list-id
May 23, 2026
Merged

delorenj merged 2 commits into
delorenj:mainfrom
peteanning:feat/name-filter-get-cards-by-list-id

Conversation

@peteanning

Copy link
Copy Markdown
Contributor

Summary

  • Adds an optional nameFilter parameter to the get_cards_by_list_id tool
  • When provided, filters cards client-side by case-insensitive substring match against the card name
  • Without this, the only way to find a specific card by name is to fetch all cards and filter in the LLM context, which burns tokens unnecessarily
  • Uses the same toLowerCase().includes() pattern as findChecklistItemsByDescription
  • Fully backward compatible — omitting nameFilter returns all cards as before

Changes

  • src/index.ts — added nameFilter optional string to inputSchema and passed through to client
  • src/trello-client.ts — added nameFilter parameter to getCardsByList with client-side filtering
  • tests/get-cards-name-filter.test.ts — 8 unit tests covering exact match, substring, case-insensitivity, no match, and backward compatibility

Test plan

  • bun run build compiles successfully
  • bun test — all 8 tests pass
  • Manual test: call without nameFilter returns all cards (backward compatible)
  • Manual test: call with nameFilter returns only matching cards

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant enhancement to the get_cards_by_list_id tool by adding an optional nameFilter parameter. This feature enables direct, client-side filtering of Trello cards based on their names, which is crucial for optimizing interactions with language models by reducing unnecessary data transfer and token consumption. The implementation maintains full backward compatibility and is thoroughly validated with new unit tests.

Highlights

  • New Feature: Card Name Filtering: An optional nameFilter parameter has been added to the get_cards_by_list_id tool, allowing users to filter Trello cards by a case-insensitive substring match against their names.
  • Improved Efficiency: This client-side filtering capability reduces the need to fetch all cards and filter them in the LLM context, thereby saving tokens and improving performance.
  • Backward Compatibility: The new nameFilter is optional, ensuring that existing calls to get_cards_by_list_id without this parameter will continue to return all cards as before.
  • Comprehensive Testing: A new test file (tests/get-cards-name-filter.test.ts) has been added, including 8 unit tests that cover various filtering scenarios, such as exact matches, substring matches, case-insensitivity, and no matches.
Changelog
  • src/index.ts
    • Added nameFilter as an optional string parameter to the inputSchema for the get_cards_by_list_id tool.
    • Modified the get_cards_by_list_id handler to pass the new nameFilter to the trelloClient.getCardsByList method.
  • src/trello-client.ts
    • Updated the getCardsByList method signature to accept an optional nameFilter string.
    • Implemented client-side filtering logic within getCardsByList to filter cards based on a case-insensitive substring match of their names against the provided nameFilter.
  • tests/get-cards-name-filter.test.ts
    • Added a new test file to cover various scenarios for the nameFilter functionality, including exact matches, substring matches, case-insensitivity, no matches, and backward compatibility.
Activity
  • Confirmed bun run build compiles successfully.
  • Verified all 8 unit tests pass with bun test.
  • Planned manual test for backward compatibility (calling without nameFilter).
  • Planned manual test for filtering functionality (calling with nameFilter).
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a nameFilter to the get_cards_by_list_id tool, which is a valuable addition for improving efficiency by filtering cards client-side. The implementation is well-tested. My review includes two suggestions for improvement: one to enhance the filtering logic by handling whitespace and another to remove an unused parameter for better code clarity.

Comment thread src/trello-client.ts Outdated
Comment thread src/trello-client.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an optional nameFilter parameter to the get_cards_by_list_id MCP tool and implements client-side filtering of cards by case-insensitive substring match to reduce token usage for name-based lookups.

Changes:

  • Extend get_cards_by_list_id tool input schema with optional nameFilter, and pass it through to the client.
  • Update TrelloClient.getCardsByList to optionally filter returned cards by name (case-insensitive substring).
  • Add Bun unit tests covering validation and filtering behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/index.ts Adds nameFilter to the MCP tool schema and forwards it to the Trello client call.
src/trello-client.ts Implements optional nameFilter trimming + case-insensitive substring filtering of cards.
tests/get-cards-name-filter.test.ts Adds unit tests for schema validation and filtering behavior/backward compatibility.

Comment thread src/trello-client.ts Outdated
Comment on lines +254 to +262
async getCardsByList(boardId: string | undefined, listId: string, nameFilter?: string): Promise<TrelloCard[]> {
return this.handleRequest(async () => {
const response = await this.axiosInstance.get(`/lists/${listId}/cards`);
return response.data;
let cards: TrelloCard[] = response.data;
const trimmed = nameFilter?.trim();
if (trimmed) {
const searchTerm = trimmed.toLowerCase();
cards = cards.filter((card) => card.name.toLowerCase().includes(searchTerm));
}

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

This block doesn’t match the repo’s Prettier settings (printWidth: 100, arrowParens: "avoid"): the method signature is overlong and the filter callback uses parentheses around a single parameter. Running Prettier (or manually wrapping + changing to card => ...) will align formatting with the project standards.

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +10
const MOCK_CARDS = [
{ id: '1', name: 'FEAT: Add Slippage to Position History', desc: '', due: null, idList: 'list1', idLabels: [], closed: false, url: '', dateLastActivity: '' },
{ id: '2', name: 'FEAT: Execute trade slippage config', desc: '', due: null, idList: 'list1', idLabels: [], closed: false, url: '', dateLastActivity: '' },
{ id: '3', name: 'BUG: Fix login page crash', desc: '', due: null, idList: 'list1', idLabels: [], closed: false, url: '', dateLastActivity: '' },
{ id: '4', name: 'Add Slippage to Position History', desc: '', due: null, idList: 'list1', idLabels: [], closed: false, url: '', dateLastActivity: '' },
];

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

The MOCK_CARDS entries are formatted as very long single lines (well over the repo’s Prettier printWidth: 100). Please run Prettier on this test file so the fixtures and object literals are wrapped consistently.

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +24
// Mirror the schema from index.ts for validation tests
const nameFilterSchema = z.string().trim().min(1, 'nameFilter must not be empty').optional();

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

This test duplicates the nameFilter Zod schema inline (“Mirror the schema from index.ts”). That can drift from the actual tool schema over time. Consider defining/exporting a shared nameFilter validator (e.g., in src/validators.ts) and reusing it both in src/index.ts and in tests.

Copilot uses AI. Check for mistakes.
Comment thread src/trello-client.ts Outdated
}

async getCardsByList(boardId: string | undefined, listId: string): Promise<TrelloCard[]> {
async getCardsByList(boardId: string | undefined, listId: string, nameFilter?: string): Promise<TrelloCard[]> {

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

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

boardId is now an unused parameter in getCardsByList. With the current ESLint config (@typescript-eslint/no-unused-vars), this will fail linting unless the arg is used or renamed to start with _ (e.g., _boardId) or removed entirely from the signature/callers.

Suggested change
async getCardsByList(boardId: string | undefined, listId: string, nameFilter?: string): Promise<TrelloCard[]> {
async getCardsByList(
_boardId: string | undefined,
listId: string,
nameFilter?: string
): Promise<TrelloCard[]> {

Copilot uses AI. Check for mistakes.
@delorenj

Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

Then resolve conflicts in prep for merge

@delorenj

Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

@delorenj

Copy link
Copy Markdown
Owner

Thanks for this — client-side name filtering is a genuinely useful token-saver. A few notes before merging:

  1. Conflicts with main. Recent merges touched src/trello-client.ts and src/index.ts. Please rebase on main so the merge can go cleanly.
  2. API consistency. The nameFilter substring match is fine for the common case. If you have appetite for it, consider also accepting a nameContains alias (case-insensitive includes) and a future-friendly query field — but a single nameFilter is sufficient for v1.

Once rebased, I'll review the diff and merge. Appreciate the work.

Without this, the only way to find a specific card by name is to
fetch all cards in the list and filter them in the LLM context,
which burns tokens unnecessarily. This adds an optional client-side
nameFilter parameter so the MCP server returns only matching cards.

When nameFilter is provided, cards are filtered by case-insensitive
substring match against the card name, using the same
toLowerCase().includes() pattern as findChecklistItemsByDescription.

The parameter is optional and backward compatible — omitting it
returns all cards as before.
Address PR feedback: empty string and whitespace-only nameFilter
values are now rejected via zod schema validation (.trim().min(1))
rather than silently returning all cards. The client method also
trims as defence in depth. Added schema validation tests.
@delorenj
delorenj force-pushed the feat/name-filter-get-cards-by-list-id branch from 6487333 to 806cdb6 Compare May 23, 2026 03:09
@delorenj
delorenj merged commit d1b1f53 into delorenj:main May 23, 2026
1 check passed
@peteanning
peteanning deleted the feat/name-filter-get-cards-by-list-id branch May 23, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants