Skip to content

Fix/network filter coercion#494

Open
johndimaster-ai wants to merge 3 commits into
stickerdaniel:mainfrom
johndimaster-ai:fix/network-filter-coercion
Open

Fix/network filter coercion#494
johndimaster-ai wants to merge 3 commits into
stickerdaniel:mainfrom
johndimaster-ai:fix/network-filter-coercion

Conversation

@johndimaster-ai

Copy link
Copy Markdown

No description provided.

Jonathan and others added 3 commits June 8, 2026 19:28
When an LLM calls search_people via MCP, it may pass the network
parameter as a JSON-encoded string (e.g. '["F"]') rather than an
actual Python list, causing a Pydantic validation error:
  'Input should be a valid list [type=list_type]'

Fix: add a coercion block at the top of search_people that detects
a string network value and parses it as JSON, falling back to
wrapping it in a list if parsing fails.

Also widens the type hint to list[str] | str | None to reflect the
accepted inputs.

Handles all cases:
  '["F"]'  -> ["F"]     (JSON array string)
  '["F","S"]' -> ["F","S"]
  '"F"'    -> ["F"]     (JSON quoted string)
  'F'       -> ["F"]     (bare string fallback)
  ["F"]    -> ["F"]     (already a list, no-op)
  None      -> None       (no filter, no-op)
fix: coerce network param from JSON string to list in search_people
The MCP framework validates tool parameters via Pydantic *before* the
function body runs. The previous approach of coercing a JSON-serialised
string (e.g. '["F"]') inside the function body therefore had no effect —
Pydantic would already reject the string as an invalid list[str].

Fix: introduce a NetworkFilter type alias using Annotated + BeforeValidator
that normalises any string input to list[str] before Pydantic's type check.
The now-redundant manual coercion block in the function body is removed.

Fixes: search_people called with network=['F'] failing with
  'Input should be a valid list [type=list_type, input_value="["F"]", input_type=str]'
@greptile-apps

greptile-apps Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR moves search_people network filter coercion into a Pydantic validator. The main changes are:

  • Adds _coerce_network for JSON-serialized network values.
  • Adds a NetworkFilter annotated type with BeforeValidator.
  • Removes the previous in-body string coercion from search_people.

Confidence Score: 3/5

This should be fixed before merging.

  • Direct FunctionTool.fn callers can now skip network string coercion.
  • A serialized first-degree filter can be rejected before the search runs.
  • Serialized null does not behave like an omitted optional filter.

linkedin_mcp_server/tools/person.py

Important Files Changed

Filename Overview
linkedin_mcp_server/tools/person.py Moves network filter normalization from the tool body to Pydantic validation.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
linkedin_mcp_server/tools/person.py:138
**Coercion is bypassable**

`network` is now normalized only by the Pydantic validator. Callers that use the registered `FunctionTool.fn` directly, as the existing tests do, bypass that validator and pass the raw string into `extractor.search_people`. With `network='["F"]'`, the extractor iterates the string character by character and rejects tokens like `[` and `"`, so a previously accepted serialized network filter now fails instead of searching first-degree connections.

### Issue 2 of 2
linkedin_mcp_server/tools/person.py:39-40
**Serialized null fails**

The validator accepts JSON-serialized strings, but a serialized optional value of `"null"` parses to `None` and then gets wrapped as `[None]`. That makes an omitted network filter fail validation or extractor token checks instead of behaving the same as `network=None`.

```suggestion
            parsed = _json.loads(v)
            if parsed is None:
                return None
            return parsed if isinstance(parsed, list) else [parsed]
```

Reviews (1): Last reviewed commit: "fix(search_people): coerce network param..." | Re-trigger Greptile

ctx: Context,
location: str | None = None,
network: list[str] | None = None,
network: NetworkFilter = None,

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.

P1 Coercion is bypassable

network is now normalized only by the Pydantic validator. Callers that use the registered FunctionTool.fn directly, as the existing tests do, bypass that validator and pass the raw string into extractor.search_people. With network='["F"]', the extractor iterates the string character by character and rejects tokens like [ and ", so a previously accepted serialized network filter now fails instead of searching first-degree connections.

Prompt To Fix With AI
This is a comment left during a code review.
Path: linkedin_mcp_server/tools/person.py
Line: 138

Comment:
**Coercion is bypassable**

`network` is now normalized only by the Pydantic validator. Callers that use the registered `FunctionTool.fn` directly, as the existing tests do, bypass that validator and pass the raw string into `extractor.search_people`. With `network='["F"]'`, the extractor iterates the string character by character and rejects tokens like `[` and `"`, so a previously accepted serialized network filter now fails instead of searching first-degree connections.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +39 to +40
parsed = _json.loads(v)
return parsed if isinstance(parsed, list) else [parsed]

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.

P2 Serialized null fails

The validator accepts JSON-serialized strings, but a serialized optional value of "null" parses to None and then gets wrapped as [None]. That makes an omitted network filter fail validation or extractor token checks instead of behaving the same as network=None.

Suggested change
parsed = _json.loads(v)
return parsed if isinstance(parsed, list) else [parsed]
parsed = _json.loads(v)
if parsed is None:
return None
return parsed if isinstance(parsed, list) else [parsed]
Prompt To Fix With AI
This is a comment left during a code review.
Path: linkedin_mcp_server/tools/person.py
Line: 39-40

Comment:
**Serialized null fails**

The validator accepts JSON-serialized strings, but a serialized optional value of `"null"` parses to `None` and then gets wrapped as `[None]`. That makes an omitted network filter fail validation or extractor token checks instead of behaving the same as `network=None`.

```suggestion
            parsed = _json.loads(v)
            if parsed is None:
                return None
            return parsed if isinstance(parsed, list) else [parsed]
```

How can I resolve this? If you propose a fix, please make it concise.

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.

1 participant