Skip to content

find_person_in_contacts fails with Niquests content argument and cannot serialize vCard Address #217

Description

@wollir72

Bug report draft

Title

find_person_in_contacts fails with Niquests content argument and cannot serialize vCard Address

Body

Describe the bug

The MCP tool find_person_in_contacts in Context Agent 2.7.0 fails in two consecutive places when querying CardDAV contacts.

First, the tool passes content=xml_body to the async HTTP session:

response = await nc._session._create_adapter(True).request(
    'REPORT',
    f"{nc.app_cfg.endpoint}{link}",
    headers={
        "Content-Type": "application/xml; charset=utf-8",
        "Depth": "1",
    },
    content=xml_body,
)

With the bundled Niquests version this fails because AsyncSession.request() accepts data= / json=, but no content= parameter.

After changing content=xml_body to data=xml_body, the CardDAV request succeeds, but the tool then fails while serializing the address field because vcard.adr.value is a vobject.vcard.Address object rather than a JSON-serializable value.

Environment

  • Nextcloud Server: 34.0.2
  • Context Agent image: ghcr.io/nextcloud/context_agent:2.7.0
  • nc-py-api: 0.24.2
  • niquests: 3.19.0
  • urllib3: 2.7.0
  • urllib3-future: 2.21.902
  • MCP transport: Streamable HTTP via AppAPI/HaRP

Steps to reproduce

  1. Install Context Agent 2.7.0.
  2. Use its MCP endpoint.
  3. Call find_person_in_contacts with the name of an existing CardDAV contact.
  4. Observe the exception.

Actual behavior – first failure

TypeError: AsyncSession.request() got an unexpected keyword argument 'content'

Relevant stack location:

/ex_app/lib/all_tools/contacts.py:70

niquests.AsyncSession.request() on this installation has the signature:

(self, method, url, params=None, data=None, headers=None, cookies=None,
 files=None, auth=None, timeout=None, allow_redirects=True, proxies=None,
 hooks=None, stream=None, verify=None, cert=None, json=None,
 override_scheme=None)

Second failure after fixing the request parameter

After locally changing:

- content=xml_body
+ data=xml_body

the CardDAV REPORT succeeds, but FastMCP fails to serialize the returned address:

Unable to serialize unknown type: <class 'vobject.vcard.Address'>

The relevant code is:

"address": getattr(vcard.adr, "value", None) if hasattr(vcard, "adr") else None,

Working local workaround

Both changes below make find_person_in_contacts work:

- }, content=xml_body)
+ }, data=xml_body)

and:

- "address": getattr(vcard.adr, "value", None) if hasattr(vcard, "adr") else None,
+ "address": str(getattr(vcard.adr, "value", "")) if hasattr(vcard, "adr") else None,

After these two changes, the MCP tool successfully returns name, email, phone and address for matching contacts.

Expected behavior

find_person_in_contacts should perform the CardDAV REPORT successfully and return only MCP/JSON-serializable values.

Additional information

The normal Nextcloud contact search MCP tool worked before the workaround, so the issue appears specific to find_person_in_contacts, not to OAuth/MCP/HaRP or CardDAV access in general.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions