Fix/network filter coercion#494
Conversation
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 SummaryThis PR moves
Confidence Score: 3/5This should be fixed before merging.
linkedin_mcp_server/tools/person.py Important Files Changed
Prompt To Fix All With AIFix 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, |
There was a problem hiding this comment.
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.| parsed = _json.loads(v) | ||
| return parsed if isinstance(parsed, list) else [parsed] |
There was a problem hiding this comment.
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.
| 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.
No description provided.