Skip to content

fix(agent): skip failed server capability results#686

Open
MukundaKatta wants to merge 1 commit into
lastmile-ai:mainfrom
MukundaKatta:codex/filter-capability-exceptions
Open

fix(agent): skip failed server capability results#686
MukundaKatta wants to merge 1 commit into
lastmile-ai:mainfrom
MukundaKatta:codex/filter-capability-exceptions

Conversation

@MukundaKatta

@MukundaKatta MukundaKatta commented May 15, 2026

Copy link
Copy Markdown

Summary

Fixes get_capabilities_task when fetching capabilities for all servers and one server fails. The previous implementation used asyncio.gather(..., return_exceptions=True) and then zipped the raw results into the returned dict, which let exception objects masquerade as ServerCapabilities values.

This now logs failed server capability lookups and omits those failed entries from the aggregate result, keeping the return value type-consistent for the servers that did respond.

Tests

  • uv run ruff check src/mcp_agent/agents/agent.py tests/agents/test_agent_tasks_concurrency.py
  • uv run pytest tests/agents/test_agent_tasks_concurrency.py

Note: pytest emits existing deprecation warnings from pytest-asyncio/Pydantic, but the targeted tests pass.

Fixes #671

Summary by CodeRabbit

  • Bug Fixes
    • Improved error resilience when retrieving capabilities from multiple servers. The agent now logs warnings for failed connections and continues processing with available servers instead of stopping entirely.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The PR fixes a silent failure in get_capabilities_task where exceptions from unavailable MCP servers were being included as values in the returned capabilities dictionary. The implementation now explicitly filters exceptions, logs warnings for failed servers, and returns only successful results. Accompanying test infrastructure extends FakeAggregator to simulate per-server failures and verifies the corrected filtering behavior.

Changes

Exception Filtering in Multi-Server Capability Aggregation

Layer / File(s) Summary
Exception filtering in get_capabilities_task
src/mcp_agent/agents/agent.py
When retrieving capabilities across all servers, results from asyncio.gather(..., return_exceptions=True) are now iterated to separate BaseException results from ServerCapabilities; exceptions are logged as warnings and excluded from the final dict instead of being blindly zipped together.
Test infrastructure and verification
tests/agents/test_agent_tasks_concurrency.py
FakeAggregator is extended with capabilities_by_server and capability_errors_by_server maps in the constructor, a new get_capabilities(server_name) method that returns capabilities or raises configured errors, and a new test test_get_capabilities_filters_failed_servers verifies that capabilities are returned only for successful servers.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • lastmile-ai/mcp-agent#441: Refactored get_capabilities_task to aggregate capabilities across all servers concurrently; this PR builds on that refactor by fixing the exception handling in the concurrent aggregation path.

Poem

🐰 A rabbit hops through servers fair,
Where exceptions once hid with care,
Now filters catch them all so neat,
And logs each failure, bittersweet—
One dict remains, a triumph pure!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(agent): skip failed server capability results' clearly and concisely describes the main change: filtering out exception objects from aggregated server capabilities.
Linked Issues check ✅ Passed The code changes fully implement the requirements from issue #671: exception results are detected via isinstance checks, failed servers are logged with warnings, and exceptions are excluded from the returned dict.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing issue #671: the agent code modification handles exception filtering in get_capabilities_task, and the test additions verify this specific behavior.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/agents/test_agent_tasks_concurrency.py (1)

163-163: ⚡ Quick win

Use consistent test marker.

The test uses @pytest.mark.asyncio while other tests in this file use @pytest.mark.anyio (lines 68, 102). For consistency with the existing test suite, use @pytest.mark.anyio.

📝 Proposed fix
-@pytest.mark.asyncio
+@pytest.mark.anyio
 async def test_get_capabilities_filters_failed_servers(monkeypatch):
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/agents/test_agent_tasks_concurrency.py` at line 163, Replace the
inconsistent test marker by changing the decorator pytest.mark.asyncio to
pytest.mark.anyio for the test that currently uses `@pytest.mark.asyncio` so it
matches the rest of the file; update the decorator on the test function (replace
pytest.mark.asyncio with pytest.mark.anyio) to ensure consistent use across
tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/agents/test_agent_tasks_concurrency.py`:
- Line 163: Replace the inconsistent test marker by changing the decorator
pytest.mark.asyncio to pytest.mark.anyio for the test that currently uses
`@pytest.mark.asyncio` so it matches the rest of the file; update the decorator on
the test function (replace pytest.mark.asyncio with pytest.mark.anyio) to ensure
consistent use across tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7542d079-5ab5-4d65-8fb1-623ec81fe0ed

📥 Commits

Reviewing files that changed from the base of the PR and between f62d849 and 82b9ce2.

📒 Files selected for processing (2)
  • src/mcp_agent/agents/agent.py
  • tests/agents/test_agent_tasks_concurrency.py

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.

get_capabilities_task silently returns exception objects in ServerCapabilities dict under partial server failure

1 participant