nextcloud / nextcloud/context_agent

find_person_in_contacts fails with Niquests content argument and cannot serialize vCard Address

Open Beginner friendly
#217 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
24
Forks
16
Avg merge
7d 20h
Merged PRs (30d)
3

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in /ex_app/lib/all_tools/contacts.py at the find_person_in_contacts request around line 70 and the address serialization shown in the issue. Reproduce the CardDAV REPORT with an existing contact, then verify the tool returns the contact details using only MCP/JSON-serializable values and no exceptions.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
Half a day
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.