Skip to main content
Glama

Server Details

Your own LinkedIn, WhatsApp, Instagram, Telegram, Email and Calendar accounts, usable from any agent

Ownership verified
Status
Healthy
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL

TDQS

B3.4/5.0

Scored across 173 tools

Disambiguation3/5

The set is organized into clear domain namespaces (email_, calendar_, linkedin_, webhook_), but several parallel APIs overlap: generic messaging_*, message_*, chat_*, and provider-specific whatsapp_/instagram_/linkedin_ tools all handle chat listing, resolution, and sending. Detailed descriptions and explicit 'prefer X' notes reduce but do not eliminate the ambiguity an agent faces in choosing between, e.g., messaging_send_message, whatsapp_send_message, and messaging_send_to_contact.

Naming Consistency4/5

Almost all tools follow a snake_case verb_noun pattern with a domain prefix (linkedin_list_conversations, email_read_message, webhook_create_destination). Deviations exist—imap_connect vs email_*, message_* vs messaging_*, and list_connected_accounts missing a prefix—but they are minor and the overall convention is highly predictable.

Tool Count1/5

173 tools is far beyond the 50+ threshold and presents a massive selection surface for an agent, even though the breadth of providers/domains can justify the underlying API. This scale inevitably hurts usability; a smaller curated set per provider would be more appropriate.

Completeness4/5

The tool surface is exceptionally broad: CRUD for calendars, email, chats/messages, posts/comments, webhooks, billing, and recruitment, plus resolver helpers that make workflows non-blocking. Minor gaps remain (e.g., no account disconnection, no Instagram post creation, Telegram actions only via generic tools), but they are workaroundable.

Available Tools

173 tools
account_change_planAccount: Change planA
Destructive
Inspect

Change the user's plan (Personal, Personal Plus, Team) or billing interval. During the trial the choice is free and applies immediately. With an active Stripe subscription the change is prorated immediately on the saved payment method: FIRST call without confirm to get the price and the explanation (and a one-click Stripe confirmation link), show them to the user, and only call again with confirm=true after explicit approval. Use when a second account of a provider needs Personal Plus, when the user wants Team for colleagues, or asks to switch monthly/annual.

ParametersJSON Schema
NameRequiredDescriptionDefault
planYesTarget plan: personal (1 account per provider), personal_plus (up to 10 accounts, several per provider allowed) or team (5 isolated users, extra seats available).
confirmNoSet true ONLY after the user explicitly confirmed the price shown to them. Without it, the tool returns the price, the proration explanation and a Stripe confirmation link instead of changing anything.
intervalNoBilling interval. Annual = 10 monthly payments (2 months free). Defaults to the user's current interval.
organization_nameNoTeam name when moving to the Team plan (defaults to 'My team').

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Although annotations already mark destructiveHint: true, the description adds substantial behavioral detail: the free and immediate effect during trial, prorated charging on the saved payment method for active subscriptions, the confirm requirement, and the one-click Stripe confirmation link. This goes far beyond the generic annotation and gives the agent the necessary caution.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loads the core action, and packs conditional behavior, confirmation flow, and use cases into about four sentences. It is slightly longer than strictly necessary but every sentence carries operational information, so no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating billing tool with no output schema, the description covers the essential operational aspects: trial vs. subscription behavior, the confirm gate, plan/interval changes, and typical use cases. It does not explicitly describe the result of the confirm=true call or error conditions (e.g., missing payment method), but it is sufficient for safe invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each parameter is already well documented, including confirm's behavior and interval's annual discount. The description restates the confirm workflow in narrative form but does not introduce new parameter semantics beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action and resource: 'Change the user's plan (Personal, Personal Plus, Team) or billing interval.' It then lists concrete use cases ('Use when a second account of a provider needs Personal Plus...') that distinguish it from sibling tools like account_start_subscription and team_add_seats, even though it does not name them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool ('Use when a second account of a provider needs Personal Plus, when the user wants Team for colleagues, or asks to switch monthly/annual') and prescribes a two-step invocation sequence (call without confirm, then with confirm after approval). It lacks explicit when-not-to-use guidance or named alternatives, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

account_connectAccount: ConnectAInspect

Get a secure connection (or reconnection) link for one of the user's provider accounts: LinkedIn, WhatsApp, Instagram, Telegram, Google/Gmail, Microsoft/Outlook or generic IMAP email. Use when the user asks to connect/add/reconnect an account, or after a connect_account/reconnect_account result. Pass account_id only to re-authenticate an existing disconnected account (from list_connected_accounts). For WhatsApp and Telegram prefer whatsapp_connect / telegram_connect, which show the QR code directly in the conversation; this tool is the browser fallback. Never ask the user for provider passwords; the link opens the provider's own authentication.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerYesProvider to connect. Use 'email' to let the user pick Gmail, Outlook or IMAP; 'imap' for a generic mailbox.
account_idNoNilyo connection ID (unipile_account_id from list_connected_accounts) of an EXISTING account to re-authenticate. Omit to connect a new account.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are all-false hints, so the description carries the burden, and it adds real behavioral context: the tool returns a provider-owned auth link, requires no user password, and is a browser fallback. It does not detail side effects like link expiry or whether initiating re-auth revokes the old session, but the core behavior and security stance are clearly disclosed. There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence adds a distinct fact: purpose, trigger, re-auth condition, sibling routing, and password prohibition. It is dense but not bloated, and the main purpose is front-loaded before caveats. The length is proportionate to the tool's branching cases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-param tool with no output schema, the description covers providers, re-authentication, sibling alternatives, and security guidance; the returned 'link' is identified even if its shape/expiry is not. It could note the imap_connect sibling as an alternative, but nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description substantially enriches both params. It maps account_id to the concrete unipile_account_id from list_connected_accounts and explains that omitting it creates a new account, and it clarifies the 'email' vs 'imap' enum distinction. This goes well beyond the schema's property descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Get a secure connection (or reconnection) link' for listed providers, and explicitly names sibling alternatives (whatsapp_connect, telegram_connect) to differentiate. The provider list and the re-authentication clause make the tool's exact role unmistakable. It clearly distinguishes from siblings rather than merely restating the name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states exactly when to use it ('when the user asks to connect/add/reconnect an account'), when to pass account_id, and when not to use it (prefer whatsapp_connect/telegram_connect for QR in-conversation). It also gives a hard rule: never ask for provider passwords. This is explicit routing with no reliance on inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

account_connection_statusAccount: Connection statusA
Read-onlyIdempotent
Inspect

Check an in-conversation WhatsApp/Telegram connection started with whatsapp_connect or telegram_connect. Returns pending (with the current QR code image or pairing code, refreshed when it changed), connected, expired or failed. Poll every 10-20 seconds until the status is connected, then retry the user's original request. Omit intent_id to check the most recent attempt.

ParametersJSON Schema
NameRequiredDescriptionDefault
intent_idNointent_id returned by whatsapp_connect/telegram_connect. Omit for the latest attempt.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: it returns pending with a QR code or pairing code that refreshes when changed, and it explicitly instructs polling behavior. This goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it states the purpose, the return states, the polling cadence, and the parameter behavior in three sentences. Every sentence earns its place with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only status tool with one optional parameter and no output schema, the description covers the essential workflow: what statuses to expect, how to poll, and what to do when connected. It doesn't describe the exact structure of the QR code or pairing code fields, but that is minor given the tool's simplicity and the annotations covering safety.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single parameter, and the description adds meaning by explaining that intent_id is the value returned by whatsapp_connect/telegram_connect and that omitting it checks the latest attempt. This clarifies the parameter's provenance and default behavior beyond the schema's simple description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool checks the status of an in-conversation WhatsApp/Telegram connection initiated by whatsapp_connect or telegram_connect. It names the specific resource (connection status) and the possible return states, distinguishing it from the connect tools and other account tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when to use this tool: poll every 10-20 seconds until status is connected, then retry the user's original request. It also explains how to handle the optional intent_id parameter, saying to omit it to check the most recent attempt. This is clear operational guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

account_get_subscriptionAccount: Get subscriptionA
Read-onlyIdempotent
Inspect

Show the user's Nilyo plan, trial/subscription status, account limits, team seats and members, plus the available billing actions (subscribe, upgrade, add seats, invite). Use when the user asks about their plan, trial, price, seats, team, why an action is blocked, or before proposing an upgrade. Never exposes payment details.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds valuable behavioral context: it reveals that the tool returns available billing actions (subscribe, upgrade, add seats, invite) and explicitly states it never exposes payment details. This goes beyond the annotations and helps the agent set user expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loads the core purpose, and every clause earns its place. The usage triggers are listed compactly, and the payment-details exclusion is a single short sentence. No redundancy with the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with strong annotations, the description is complete. It tells the agent what data is returned, when to use it, and what it will not return. There is no output schema, but the description enumerates the return contents well enough for an agent to decide whether to call it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is no schema burden. The description compensates by explaining what the tool returns (plan, trial status, limits, seats, members, billing actions), which is the closest thing to parameter semantics for a parameterless tool. A baseline of 4 is appropriate for zero-parameter tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Show') and resource ('the user's Nilyo plan, trial/subscription status, account limits, team seats and members, plus the available billing actions'). It clearly distinguishes this from sibling tools like account_start_subscription and account_change_plan by focusing on read-only display of subscription state and available actions, not performing them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly lists when to use this tool: 'when the user asks about their plan, trial, price, seats, team, why an action is blocked, or before proposing an upgrade.' It also provides a negative constraint ('Never exposes payment details'), which helps the agent avoid using it for payment-sensitive queries. This is strong usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

account_list_attentionAccount: List attentionA
Read-onlyIdempotent
Inspect

List the user's connected accounts that currently need re-authentication (status disconnected) so the agent can proactively offer to reconnect them before a request fails. Returns an empty list when everything is healthy.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so safety is covered. The description adds useful behavioral context beyond annotations: it filters to disconnected accounts and returns an empty list when healthy, which clarifies the tool's effect and output semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences of purposeful prose. It front-loads the core purpose, then adds the empty-list behavior, with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with rich annotations, the description is complete: it states what is listed, why, and what an empty result means. No schema or output details are needed to select or invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters and schema description coverage is 100%, so the description carries no parameter burden. Per the baseline for zero-parameter tools, this is a solid score; the description also clarifies what the returned list represents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'List the user's connected accounts that currently need re-authentication (status disconnected)'. It clearly distinguishes this from broader account tools like list_connected_accounts and account_connection_status by focusing on the re-authentication need.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: use it proactively to offer reconnection before a request fails. It does not explicitly name alternatives or state when not to use it, but the use case is well implied by the 'proactively offer to reconnect' framing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

account_start_subscriptionAccount: Start subscriptionA
Destructive
Inspect

Return Stripe Checkout links (one-click hosted payment, no need to visit the website) to start or restore the paid subscription when the user is on trial, the trial expired or the subscription lapsed. Use after a subscribe result or when the user asks to subscribe/pay/upgrade before having a subscription. If the user already has an active Stripe subscription, use account_change_plan instead. Present monthly and annual options; default to the current plan unless the user chose another one.

ParametersJSON Schema
NameRequiredDescriptionDefault
planNoTarget plan: personal (1 account per provider), personal_plus (up to 10 accounts, several per provider allowed) or team (5 isolated users, extra seats available).
intervalNoBilling interval. Annual = 10 monthly payments (2 months free). Defaults to the user's current interval.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate it's a mutating operation (destructiveHint=true). The description adds value by explaining it returns Stripe checkout links (so the actual payment happens externally), and notes the presentation behavior ('Present monthly and annual options; default to the current plan'). This goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact yet informative. Each sentence earns its place: it opens with the core function, then usage conditions, then the alternative, then presentation preferences. No fluff, though it could be slightly tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with an output schema absent, the description explains what it returns (checkout links) and when to use it. It also covers edge cases (trial, expired, lapsed) and defaulting. The only minor omission is a description of the actual response structure, but that's not required given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% — both 'plan' and 'interval' are fully described in the schema. The description adds some behavior guidance (e.g., 'default to the current plan'), but this is about tool behavior rather than parameter semantics, so it stays at the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb and resource: 'Return Stripe Checkout links ... to start or restore the paid subscription.' It also distinguishes itself from the sibling account_change_plan, making its unique purpose obvious without reading the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use is given: 'Use after a subscribe result or when the user asks to subscribe/pay/upgrade before having a subscription.' It also provides an exclusion: 'If the user already has an active Stripe subscription, use account_change_plan instead.' This is a model of clear routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

agent_capability_guideGuide: Capability guideA
Read-onlyIdempotent
Inspect

Return Nilyo's agent workflow recipes and chaining rules. Use when you need to know how to turn a LinkedIn URL/name into a provider user ID, how to find a chat before replying, how to resolve LinkedIn search parameter IDs, or how to combine several account providers.

ParametersJSON Schema
NameRequiredDescriptionDefault
workflowNoOptional workflow name; omit to return all recipes.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safe, non-mutating nature is fully covered. The description adds no behavioral detail beyond saying it returns recipes and rules, which is consistent but not extra disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence followed by a focused 'Use when' list. It front-loads the purpose and then gives concrete examples without redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only guide tool with one optional parameter and rich annotations, the description fully covers what the tool returns and when to invoke it. No output schema exists, but the return content (recipes and chaining rules) is described sufficiently for an agent to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single optional 'workflow' parameter is already clearly documented in the schema as 'Optional workflow name; omit to return all recipes.' The description doesn't need to add more, and it doesn't.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Return') and a specific resource ('Nilyo's agent workflow recipes and chaining rules'), and then enumerates concrete use cases such as resolving LinkedIn URLs to provider user IDs and finding a chat before replying. This clearly distinguishes it from sibling tools like agent_id_guide and general LinkedIn lookup tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use when you need to know how to...' and lists several concrete scenarios, giving an agent clear triggers for invocation. It does not explicitly name alternatives or when not to use it, so it stops short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

agent_id_guideGuide: ID guideA
Read-onlyIdempotent
Inspect

Return the authoritative Nilyo ID semantics guide. Use this when unsure whether a tool needs a LinkedIn system user ID, public identifier, request ID, post/comment/chat/message ID, inbox/contract ID, email/thread/folder/attachment ID, calendar/event ID or recruiting/list ID. The guide explains exactly which previous tool produces each ID and which lookalike values must NOT be passed.

ParametersJSON Schema
NameRequiredDescriptionDefault
id_typeNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds substantive behavioral context beyond this: the guide is 'authoritative', it explains 'exactly which previous tool produces each ID', and it warns that 'lookalike values must NOT be passed'. This tells the agent what kind of content and constraints the tool returns, which is meaningful additional disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The main action ('Return the authoritative Nilyo ID semantics guide') is front-loaded, followed immediately by usage context, and then content scope. Every clause earns its place and the description remains skimmable despite covering many ID categories.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only reference tool with one optional enum parameter and no output schema, the description covers the resource, when to use it, and what it contains. The main missing piece is how the 'id_type' parameter affects the returned content—whether it filters the guide or is required. This is a notable but non-critical gap given the tool's simplicity and the annotations already covering safety and idempotency.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the lone 'id_type' parameter. It groups the ID types into human-readable categories ('inbox/contract ID', 'email/thread/folder/attachment ID', etc.), which maps helpfully onto the enum values. However, it never explains the parameter's actual behavior—that passing a specific id_type filters the guide and that omitting it returns the full guide. This is a significant gap given zero schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Return the authoritative Nilyo ID semantics guide.' It makes the tool's function immediately clear and enumerates the ID types covered. However, it does not differentiate itself from the sibling tool 'agent_capability_guide', which is also a guide-style tool, so it falls short of a full 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool: 'Use this when unsure whether a tool needs a LinkedIn system user ID, public identifier, request ID, ...' This is clear contextual guidance. It does not, however, state when NOT to use it (e.g., when the ID type is already certain) or name any alternative tools, so it does not fully meet the 5-level bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_cancel_eventCalendar: Cancel eventA
Destructive
Inspect

Cancel an event organized by the connected account and notify attendees. This differs from deleting an event only from the user's calendar; confirm the exact event before cancellation.

ParametersJSON Schema
NameRequiredDescriptionDefault
commentNoCancellation message sent to attendees; supported by Outlook only.
event_idYesExact event ID returned by calendar_list_events or calendar_create_event, paired with its parent calendar_id. Calendar event ID: Exact event id in the selected calendar/account. Obtain with: calendar_list_events -> event.id; calendar_create_event -> created event.id Never pass: event title, date.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the destructive nature is structured. The description adds valuable behavioral context beyond annotations: it notifies attendeescias a side effect, only applies to events organized by the connected account, and warns to confirm before acting. This enriches the safety profile without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary action and scope come first, followed by a concise differentiator and a practical caution. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent operation, the description covers the key context: what it cancels, its side effect, how it differs from the delete sibling, and a confirmation warning. With no output schema, it doesn't need to explain returns. The main small gap is that it doesn't mention parameter prerequisites, but those are thoroughly handled in the schema, so overall it is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool description itself does not add parameter semantics, but the input schema covers 100% of the parameters with detailed descriptions (e.g., event_id says how to obtain it and never pass a title/date; calendar_id warns against names). Since the schema already documents param meaning, a baseline of 3 is appropriate—no extra value is needed or provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Cancel') with a clear resource ('an event organized by the connected account') and a distinct side effect ('notify attendees'). It also explicitly differentiates from the alternative 'deleting an event only from the user's calendar', which aligns with the sibling calendar_delete_event. This leaves no ambiguity about the tool's function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit when-to-use: cancel events organized by the connected account when attendees should be notified. It also names the alternative scenario ('deleting an event only from the user's calendar') and adds a caution to 'confirm the exact event before cancellation', which guides safe usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_create_calendarCalendar: Create calendarAInspect

Create a calendar in the selected Google or Microsoft account. Use only when the user explicitly asks for a new calendar, not merely an event.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
timezoneNoIANA timezone, for example Europe/Paris.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
descriptionNo
background_colorNoHexadecimal calendar color.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a non-read-only, non-idempotent mutation. The description adds the provider scope but does not disclose further behavior such as duplicate handling, immediate visibility, or external side effects. There is no contradiction with annotations, but the description contributes little beyond the obvious creation action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no wasted words. The core action is front-loaded in the first sentence, and the usage guardrail is in the second. Perfectly sized for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a straightforward creation tool with annotations covering the write nature, the description plus the detailed account_id parameter guidance are sufficient to invoke the tool correctly. The only notable omission is any indication of the return value, but no output schema exists, so this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description itself does not expand on individual parameters, but the schema already covers 3 of 5 parameters (timezone, account_id, background_color) with descriptions. The remaining parameters, name and description, are self-explanatory. The account_id parameter description is especially rich, providing operational guidance beyond basic semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Create') and resource ('calendar') with the account scope ('selected Google or Microsoft account'). It explicitly differentiates from the sibling calendar_create_event by adding 'not merely an event,' so an agent can immediately tell which creation tool is appropriate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear when-to-use condition: 'Use only when the user explicitly asks for a new calendar, not merely an event.' Additionally, the account_id parameter description gives detailed guidance on when to omit versus when to list accounts and ask, preventing incorrect multi-account selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_create_eventCalendar: Create eventAInspect

Create an event in one resolved calendar. Require an explicit title, attendees array, start and end; preserve timezone and all-day semantics instead of guessing them.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYes
bodyNo
startYes
titleYes
notifyNoGoogle-only guest update policy; omit for Microsoft.
locationNo
timezoneNoIANA timezone for the event.
attendeesYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
conferenceNo
recurrenceNoRFC5545 RRULE, EXRULE, RDATE or EXDATE lines.
visibilityNo
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.
transparencyNo
background_colorNo
is_attendees_list_hiddenNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds a behavioral guarantee ('preserve timezone and all-day semantics instead of guessing them'), which is useful. Annotations already cover mutability and non-idempotency, so the description adds a bit of extra context but not extensive behavior like side effects or response details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the main purpose, and no wasted words. The required fields and behavioral note are efficiently stated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 16 parameters and nested objects, the description is sparse. It does not cover optional parameters or return expectations, though the schema has some descriptions and the behavioral note about timezone/all-day helps. Still, an agent may lack guidance on many optional fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Description mentions only required parameters (title, attendees, start, end) and a timezone note, but does not explain the many optional parameters (location, conference, recurrence, visibility, etc.). With schema coverage at 31%, it fails to compensate for the gaps, adding minimal value beyond the schema's own descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Create), resource (event), and scope (one resolved calendar), clearly distinguishing from calendar_create_calendar and calendar_update_event. It also mentions required fields and a behavioral nuance, making the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage for creating events; does not explicitly compare with siblings like calendar_update_event or calendar_cancel_event, but the purpose is clear and no exclusions are needed. The 'one resolved calendar' hint suggests it is not for multi-calendar operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_delete_calendarCalendar: Delete calendarA
Destructive
Inspect

Delete one exact calendar. This is destructive: resolve and confirm the calendar before deleting it; never infer calendar_id from its display name.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, and the description reinforces this by stating 'This is destructive'. It adds valuable context beyond annotations by instructing the agent to resolve and confirm the calendar and to never infer the ID, which is a critical behavioral guardrail not expressed in the schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero redundancy. The action is front-loaded, and the safety warning follows immediately. Every word earns its place; no filler or vague language.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive delete tool with no output schema, the description adequately covers the key risks (destructive nature, ID resolution) and the required parameter. It doesn't describe return values, but none are expected. The inclusion of the confirmation guidance makes it complete enough for an agent to use it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains the calendar_id parameter, including how to obtain it and never pass a display name. The description reiterates the 'never infer' warning but adds no new parameter semantics beyond what the schema provides. Baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Delete' and the resource 'one exact calendar', which distinguishes it from sibling tools like calendar_delete_event. It also adds the qualifier 'exact' to set precision expectations. This is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly name alternatives or when-not-to-use, but it provides critical usage guidance: resolve and confirm the calendar before deleting, and never infer the ID from its display name. This gives clear context for safe invocation, even though it doesn't contrast with siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_delete_eventCalendar: Delete eventA
Destructive
Inspect

Delete one resolved calendar event. Confirm the intended event and preserve its parent calendar_id; this removes it only from the connected account's calendar.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesExact event ID returned by calendar_list_events or calendar_create_event, paired with its parent calendar_id. Calendar event ID: Exact event id in the selected calendar/account. Obtain with: calendar_list_events -> event.id; calendar_create_event -> created event.id Never pass: event title, date.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false. The description adds context beyond annotations: deletion is scoped to the connected account's calendarasi and the parent calendar_id must be preserved. This provides useful operational detail without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the action, and every phrase carries weight. It avoids repeating schema content, delivering only the essential behavioral scope and caution in 26 words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive three-parameter tool with no output schema, the description combined with the rich parameter schema and annotations covers all necessary details: the event to delete, the required IDs, and the scope. The account_id parameter is fully explained in the schema. No critical contextual gap exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter is thoroughly documented (event_id must be exact and never a title/date; calendar_id must be exact and never a name; account_id is optional for single-account contexts). The description's mention of preserving calendar_id reinforces the schema but adds minimal new meaning. The baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The title and description clearly state the action ('Delete') and the resource ('resolved calendar event'). The phrase 'removes it only from the connected account's calendar' distinguishes this tool from siblings like calendar_cancel_event or calendar_delete_calendar, clarifying it deletes a specific event instance within a single account.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by specifying 'resolved' event and the scope (only from connected account's calendar), but it never explicitly names alternatives or states when not to use this tool. The caution to 'Confirm the intended event' is a usage note, but no direct comparison to calendar_cancel_event or calendar_restore_event is made.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_get_calendarCalendar: Get calendarA
Read-onlyIdempotent
Inspect

Get one calendar by the exact ID returned by calendar_list_calendars. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds a useful precondition (exact calendar ID, not a name) but does not add behavioral detail such as return format or not-found behavior. This is adequate given the strong annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, front-loaded, and communicates the essential rule about exact IDs and display-name rejection. There is some redundancy between the first sentence and the 'Calendar ID:' elaboration, but it remains compact and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only get-by-ID tool, the description plus annotations cover the safety profile and the key prerequisite. The account_id nuance is fully handled in the schema. A brief statement of the return shape would be a minor enhancement, but nothing essential is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both parameters are well-documented in the schema, including the exact-ID rule for calendar_id and detailed account disambiguation for account_id. The tool description mostly repeats the calendar_id guidance already present in the schema, adding no new parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Get one calendar by the exact ID'. It clearly distinguishes this from the sibling calendar_list_calendars and calendar_get_event tools by emphasizing that it fetches a single calendar using an exact ID.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context on how to obtain the required ID ('returned by calendar_list_calendars') and explicitly warns against passing a display name. It does not explicitly enumerate when to prefer this over alternatives, but the exact-ID prerequisite makes the intended usage clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_get_eventCalendar: Get eventA
Read-onlyIdempotent
Inspect

Get one event using both its exact parent calendar_id and event_id. Never identify an event only by title or date.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesExact event ID returned by calendar_list_events or calendar_create_event, paired with its parent calendar_id. Calendar event ID: Exact event id in the selected calendar/account. Obtain with: calendar_list_events -> event.id; calendar_create_event -> created event.id Never pass: event title, date.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds value by emphasizing the exact-ID requirement and the pairing of calendar_id with event_id, which is a behavioral constraint beyond the annotations. It doesn't describe return format, but for a simple get operation with no output schema, the annotations plus the ID-pairing warning are sufficient. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero waste. The first sentence states the action and required parameters; the second sentence is a critical negative instruction. It is front-loaded with the core purpose and the exclusion is immediately actionable. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read operation with 100% schema coverage and readOnly/idempotent annotations, the description is nearly complete. It covers the key usage constraint (exact IDs, not title/date) and the parameter pairing. The only minor gap is that it doesn't mention what happens if the event is not found or the return shape, but with no output schema and a simple get, this is a minor omission. The account_id disambiguation is handled in the schema, so the description doesn't need to repeat it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters thoroughly. The description adds a concise summary of the key constraint (exact parent calendar_id and event_id) and the 'never by title or date' rule, which reinforces the schema. The account_id parameter is well-documented in the schema with disambiguation guidance. The description doesn't need to add more since the schema is exhaustive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a specific resource ('one event'), and the exact identifiers required ('exact parent calendar_id and event_id'). It also explicitly distinguishes from identifying by title or date, which differentiates it from sibling tools like calendar_list_events or calendar_resolve_event. This is a clear, unambiguous purpose statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Never identify an event only by title or date,' providing a clear exclusion. The parameter descriptions further reinforce when to use this tool: use exact IDs from calendar_list_events or calendar_create_event, and never pass title/date. This is strong usage guidance that prevents common agent errors.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_list_calendarsCalendar: List calendarsA
Read-onlyIdempotent
Inspect

List calendars for the connected Google or Microsoft account. Use the returned calendar.id before listing, creating or updating events; never pass a calendar display name as calendar_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo
offsetNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, covering safety. The description adds behavioral context beyond annotations by explaining that the output contains calendar.id and that display names must not be used as calendar_id—a common pitfall. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no waste: the first states the purpose, the second delivers a crucial usage constraint. The key information is front-loaded, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core purpose and a key pitfall, but lacks guidance on pagination (limit, cursor, offset) and does not explain how to handle multiple accounts beyond what the account_id parameter description already provides. Given the low schema coverage and absence of output schema, more detail on these aspects would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (only account_id has a description). The description does not elaborate on limit, cursor, or offset, leaving pagination semantics unexplained. With such low coverage, the description should compensate, but it does not, so agents may misuse these parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a resource ('calendars'), and the scope ('for the connected Google or Microsoft account'). It also provides a critical usage hint about using calendar.id instead of display names, which clearly differentiates this from other calendar tools like calendar_get_calendar or calendar_create_event.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly guides usage by stating to use the returned calendar.id before listing, creating, or updating events, and warns against using display names. It does not explicitly name alternative tools or when to use them, but the context is clear enough for an agent to know this is the go-to for listing calendars and obtaining IDs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_list_eventsCalendar: List eventsA
Read-onlyIdempotent
Inspect

List or search events inside one resolved calendar. Use this to obtain event.id before reading, updating or deleting an event.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoISO 8601 upper time bound.
busyNo
limitNo
startNoISO 8601 lower time bound.
titleNo
cursorNo
offsetNo
ical_uidNo
locationNo
attendeesNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
event_typeNo
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.
descriptionNo
is_cancelledNo
updated_afterNo
updated_beforeNo
expand_recurringNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive behavior, so the description is not burdened with safety disclosure. It adds the purpose of obtaining event.id but does not disclose pagination, filtering semantics, or return format. Given the annotations cover the main behavioral profile, a 3 is appropriate – it adds some context but lacks deeper behavioral details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exceptionally concise – two sentences with no filler. The primary purpose is stated first, and the secondary use case is added efficiently. Every word earns its place, making it easy to parse and act upon.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite being a simple read-only tool, it has 18 parameters and no output schema. The description does not mention pagination (cursor, limit, offset), filtering options, or what the response looks like. An agent would need to infer much from parameter names and the few schema descriptions. For a tool of this complexity, the description is insufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 22% schema description coverage and 18 parameters, the description was expected to compensate by explaining how to search or filter, but it does not. It merely says 'list or search' without detailing which parameters enable searching. The schema descriptions for calendar_id, start, end, and account_id help, but many parameters (e.g., title, location, attendees, is_cancelled) remain undocumented in both schema and description, leaving agents without guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'List or search events inside one resolved calendar.' It specifies a concrete action (list/search) and resource (events), and distinguishes its role by noting it is used to obtain event.id before reading, updating, or deleting an event, which separates it from event-specific operations like calendar_get_event.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear context: it is the entry point for obtaining event IDs and implies the need for a resolved calendar (likely from calendar_list_calendars). However, it does not explicitly mention alternatives like calendar_get_event for when the ID is already known, nor does it state exclusions. Still, the guidance is actionable and implies the correct workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_restore_eventCalendar: Restore eventAInspect

Restore an event previously cancelled by the connected organizer. Available only for Google Calendar while Google still retains the cancelled event; report the provider error for Outlook without substituting another action.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesExact event ID returned by calendar_list_events or calendar_create_event, paired with its parent calendar_id. Calendar event ID: Exact event id in the selected calendar/account. Obtain with: calendar_list_events -> event.id; calendar_create_event -> created event.id Never pass: event title, date.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate this is not read-only and not idempotent, but the description adds valuable behavioral context: the restore depends on Google's retention of the cancelled event, and Outlook should surface an error rather than be handled with a fallback. This goes beyond the structured annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact sentences with no filler. The core action and object are front-loaded, followed by the necessary provider and error-handling constraints, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Together with the fully detailed input schema, the description covers the action, provider availability, a time-based precondition, and failure behavior for an unsupported provider. The absence of an output schema is not a major gap for a simple restore operation, though a bit more detail about the response could push it higher.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already provides detailed semantics for event_id, calendar_id, and account_id, including exact ID requirements and never-pass guidance for titles/names. The description does not add parameter-specific detail, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Restore') and resource ('event previously cancelled by the connected organizer'), which clearly identifies the action and distinguishes it from sibling tools like calendar_cancel_event and calendar_delete_event. The provider scoping ('Google Calendar') further sharpens the intended operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when this tool can be used: only for Google Calendar and only while Google retains the cancelled event. It also gives direct guidance for Outlook by instructing the agent to report the provider error without substituting another action, which prevents misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_rsvp_eventCalendar: Rsvp eventAInspect

Accept, tentatively accept or decline an invitation for the connected account only. Resolve the event first; Outlook organizers cannot RSVP and declining can remove the event from their calendar.

ParametersJSON Schema
NameRequiredDescriptionDefault
statusYes
commentNo
event_idYesExact event ID returned by calendar_list_events or calendar_create_event, paired with its parent calendar_id. Calendar event ID: Exact event id in the selected calendar/account. Obtain with: calendar_list_events -> event.id; calendar_create_event -> created event.id Never pass: event title, date.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.

TDQS

A3.6/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description warns that 'declining can remove the event from their calendar,' which directly contradicts the annotation destructiveHint=false. Even though it adds useful caveats about Outlook organizers and account scope, the contradiction undermines the agent's ability to trust either signal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences contain all essential guidance with no filler. The main action is front-loaded, and the important caveat about Outlook organizers follows immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers scope, prerequisites, and provider-specific caveats, which is strong for an RSVP tool. It omits return-value details, but there is no output schema and the mutation semantics are reasonably clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 60% schema coverage, the description adds useful context by mapping the action to status values and emphasizing the connected-account restriction, which relates to account_id. However, it does not explain the comment parameter or add much beyond the existing schema descriptions for event_id and calendar_id.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear, specific verb-resource pair: accept, tentatively accept, or decline an invitation. It also immediately scopes the action to 'the connected account only,' which helps distinguish it from other calendar mutation tools like calendar_cancel_event or calendar_update_event.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives actionable usage prerequisites: resolve the event first and avoid using this tool for Outlook organizers. It clearly notes a limitation but does not explicitly name sibling alternatives or contrast with them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_update_calendarCalendar: Update calendarAInspect

Update explicit fields on an existing calendar. Resolve calendar_id first and pass only changes requested by the user.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
timezoneNoIANA timezone, for example Europe/Paris.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.
descriptionNo
background_colorNoHexadecimal calendar color.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations providing readOnlyHint=false, destructiveHint=false, and openWorldHint=true, the description adds value by specifying that only 'explicit fields' are updated, implying partial updates and not destructive behavior. It also instructs to 'pass only changes requested by the user,' which is behavioral context not in annotations. No contradictions found.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise: two sentences, front-loading the core action and key guideline. It avoids redundancy with the schema but also omits some potentially useful info like example updates. However, it is efficient and well-structured for its purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 parameters, mutation, no output schema), the description provides essential context: resolve calendar_id first, pass only changes, and rely on schema for param details. It could mention what fields are updatable or consequences, but the schema covers field details. Missing return info is minor since no output schema exists, but the tool's function is clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67%, meaning most parameters have descriptions, including important guidance on account_id and calendar_id. The description reinforces that calendar_id must be resolved and only changes passed, which adds value beyond the schema. For parameters without descriptions like name and description, the description's general context compensates reasonably.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Update explicit fields on an existing calendar,' which is a specific verb and resource. It clearly indicates this tool is for modifying a calendar, distinguishing it from sibling tools like calendar_create_calendar and calendar_delete_calendar. The description also emphasizes passing only user-requested changes, which adds clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: resolve calendar_id first and pass only changes requested by the user. It implicitly guides when to use this tool (when updating existing calendars) but does not explicitly state when not to use it or mention alternatives like calendar_update_event. However, the instruction to resolve calendar_id is a strong usage guideline.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_update_eventCalendar: Update eventAInspect

Update explicit fields on a resolved event. Keep event_id paired with the parent calendar_id and do not blindly retry after an ambiguous failure.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNo
bodyNo
startNo
titleNo
notifyNoGoogle-only guest update policy; omit for Microsoft.
event_idYesExact event ID returned by calendar_list_events or calendar_create_event, paired with its parent calendar_id. Calendar event ID: Exact event id in the selected calendar/account. Obtain with: calendar_list_events -> event.id; calendar_create_event -> created event.id Never pass: event title, date.
locationNo
timezoneNoIANA timezone for the event.
attendeesNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
conferenceNo
recurrenceNoRFC5545 RRULE, EXRULE, RDATE or EXDATE lines.
visibilityNo
calendar_idYesExact calendar ID returned by calendar_list_calendars; never pass a calendar name. Calendar ID: Exact Google/Microsoft calendar id. Obtain with: calendar_list -> calendar.id Never pass: calendar display name.
transparencyNo
background_colorNo
is_attendees_list_hiddenNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already state non-read-only, non-idempotent, and non-destructive behavior. The description adds value by specifying that only explicit fields are updated (behavioral detail not in annotations) and by warning against retrying after ambiguous failures, which indicates partial-application risk. These traits are beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences: the first states the primary purpose, the second gives two critical operational warnings. It is front-loaded and concise with no filler or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 17 parameters, no output schema, and low schema coverage, the description is too sparse. It does not explain return values, how unspecified fields are treated, provider-specific behaviors (only the notify parameter hints at Google-specificity), or account selection steps. The two warnings are helpful but insufficient for complex edge cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 35%, so the description should compensate. However, the only parameter-related guidance (event_id paired with calendar_id) is already present in the schema's event_id description. No additional meaning is provided for the other 15 parameters, such as start, end, attendees, or recurrence.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Update explicit fields on a resolved event' with a specific verb and resource, and the 'resolved' qualifier distinguishes it from creation and other calendar operations. This clearly differentiates it from siblings like calendar_create_event and calendar_update_calendar. The phrase 'explicit fields' also signals a partial update rather than a full overwrite.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage after resolving an event (by mentioning 'resolved event') but does not explicitly contrast with alternatives like calendar_create_event or calendar_cancel_event. It gives operational guidance (pairing event_id with calendar_id, avoiding blind retries) but lacks an explicit when-to-use or when-not-to-use statement, leaving some inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

chat_add_participantChat: Add participantAInspect

Add an exact provider user to an exact group chat. Resolve chat_id independently from user_id. For LinkedIn user references, URL/name -> profile resolver -> profile.id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
user_idYesExact provider user ID returned by the relevant profile/person/contact resolver. Never pass a display name. For LinkedIn actions use the stable system user ID returned as profile.id, not a linkedin.com URL.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, so the safety profile is known. The description adds ID resolution context but does not disclose additional behavioral traits like side effects or rate limits. It does not contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and then provides structured ID resolution guidance. While verbose, the length is justified by the complexity of ID handling; it remains efficient and well-organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 3 params (2 required) and no output schema, the description covers all necessary operational details: ID resolution, what to avoid, and provider-specific nuances. The optional account_id is fully explained in the schema, so no gap exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, giving a baseline of 3. The description significantly enhances parameter meaning by detailing how to obtain chat_id and user_id, including LinkedIn-specific resolver chains and explicit exclusions, going beyond the schema's descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the specific verb 'Add' and resource 'exact provider user to an exact group chat', clearly distinguishing it from siblings like chat_remove_participant and chat_list_participants. The emphasis on 'exact' reinforces the precision required.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit instructions on resolving chat_id and user_id, including what never to pass (person name, URL, etc.). It does not explicitly mention when to use this tool over alternatives, but the purpose is unambiguous and the guidance is highly actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

chat_deleteChat: DeleteA
Destructive
Inspect

Delete/remove one exact chat where supported. Resolve/verify chat_id first; destructive. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint=true and idempotentHint=false, so the description's 'destructive' label is redundant. However, it adds meaningful context by stating deletion is 'where supported' and instructing the agent to resolve/verify chat_id first, which conveys limited support and a safety precondition beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is relatively concise and front-loaded, leading with the core action and then layering preconditions and identifier guidance. The middle section repeats some schema text, but it serves as a standalone summary. No unnecessary filler is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool with no output schema, the description covers the most critical invocation details: what to delete, how to obtain the identifier, and what to never pass. However, it does not explain what happens when deletion is unsupported or on error/response behavior, and the account_id selection guidance is only in the schema, leaving a moderate gap for agents dealing with multiple accounts.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description repeats the chat_id semantics already present in the schema and does not add new parameter-specific meaning. The account_id parameter is described only in the schema, not in the main description, but the schema itself covers it thoroughly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Delete/remove one exact chat where supported.' It clearly distinguishes this from sibling tools like message_delete by targeting the chat object, and reinforces the resource type by explaining that a chat_id, not a person name, user_id, or message_id, is required.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context: resolve and verify chat_id first, note that this is destructive, and it only works 'where supported.' It also tells the agent exactly what identifiers are unacceptable. It does not explicitly name alternative tools or conditions for choosing a different tool, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

chat_list_participantsChat: List participantsA
Read-onlyIdempotent
Inspect

List members of an exact group/multi-party chat. Resolve chat_id first. Returned participant user IDs can be reused for membership operations; they are NOT chat IDs. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=true, so the description doesn't need to repeat that. It adds value by clarifying the output semantics: 'Returned participant user IDs can be reused for membership operations; they are NOT chat IDs.' This prevents a common misuse. It also states the tool works only for group/multi-party chats, which is a behavioral constraint not in annotations. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, then provides resolution guidance and output clarification. It's not overly long, and every sentence contributes value. The warning and reuse note are important. Slightly verbose due to repetition of schema content, but still efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description explains what is returned (participant user IDs) and clarifies they are not chat IDs. It covers how to obtain chat_id and what not to pass. It doesn't mention pagination, error cases, or authorization requirements, but for a simple list operation with strong annotations (readOnly, idempotent), this is adequate. Minor gaps remain but the essentials are covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% – both chat_id and account_id have detailed descriptions that already cover semantics. The tool description repeats some of that (e.g., 'Never pass: person name, user_id, message_id') but adds no new parameter-specific information beyond what's in the schema. Baseline 3 is appropriate because the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List members of an exact group/multi-party chat.' It clearly differentiates from sibling tools like chat_add_participant and chat_remove_participant by focusing on listing. The emphasis on 'exact group/multi-party chat' and the warning about not passing person names or message IDs further pin down the scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit instructions: 'Resolve chat_id first,' how to obtain it ('Obtain with: provider list conversations/inbox chats -> chat.id'), and what never to pass ('Never pass: person name, user_id, message_id'). It also notes that returned user IDs can be reused for membership operations, implying when this tool is useful before adding/removing participants. This is comprehensive and unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

chat_remove_participantChat: Remove participantA
Destructive
Inspect

Remove an exact provider user from an exact group chat. Inspect participants first when identity is ambiguous. chat_id and user_id are separate. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
user_idYesExact provider user ID returned by the relevant profile/person/contact resolver. Never pass a display name. For LinkedIn actions use the stable system user ID returned as profile.id, not a linkedin.com URL.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint: true, so the agent knows this is a mutation. The description adds context about exact matching and the need to inspect participants, which is useful beyond annotations. However, it doesn't elaborate on side effects (e.g., notifications, irreversibility) or error behavior, so it provides only moderate additional transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused paragraph that front-loads the purpose and then gives practical warnings. It is not bloated, though it repeats some schema text verbatim, which is slightly redundant but does not hinder readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a straightforward removal operation, the description covers the essential: action, exactness, inspection hint, and ID separation. The sibling chat_list_participants provides the inspection path, and annotations cover the destructive nature. It lacks explicit notes on permanent effects, but that is minor given the simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the parameter descriptions in the schema are already detailed (including the exact same warnings about chat_id and user_id). The tool description largely repeats this content rather than adding new meaning, so it doesn't compensate beyond the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise action: 'Remove an exact provider user from an exact group chat.' It clearly distinguishes from siblings like chat_add_participant (add) and chat_list_participants (list). The verb and resource are specific, and the 'exact' qualifiers prevent ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: 'Inspect participants first when identity is ambiguous' implies using chat_list_participants before removal. Also warns against passing wrong ID types. While it doesn't name sibling tools directly, the usage context is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

chat_updateChat: UpdateAInspect

Update mutable metadata of an exact chat. Resolve chat_id first; do not use person/user ID. Pass only fields explicitly requested. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnlyHint=false and destructiveHint=false, so the description's mutation implication adds little. It does disclose the important behavioral rule 'Pass only fields explicitly requested' and warns against passing person/user IDs, which is useful context beyond structured data. However, it doesn't describe side effects, reversibility, permissions, or response behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loads the core action and key constraint ('Resolve chat_id first; do not use person/user ID'). The repeated chat_id block is a bit redundant with the schema but not wordy overall. Each sentence carries useful information, though the structure could be tightened by avoiding duplication.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with no output schema and high schema coverage, the description covers the critical pitfalls (chat_id resolution, prohibiting user IDs, limiting to explicit fields). It is missing an account_id selection nuance (though the schema covers it) and doesn't clarify what 'mutable metadata' fields are supported, but these are minor given the simple signature.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with chat_id and account_id both fully described in the schema. The description repeats the chat_id guidance verbatim but adds no new parameter-specific meaning beyond the schema. The 'Pass only fields explicitly requested' rule is a general usage guideline, not a parameter semantic, so it doesn't elevate the score above the schema-coverage baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Update' and the resource 'mutable metadata of an exact chat,' distinguishing it from sibling tools like chat_delete or chat_add_participant. The additional guidance on resolving chat_id clarifies the target but 'mutable metadata' remains somewhat broad, so it doesn't fully differentiate from messaging_set_chat_state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit context: use only for exact chats, resolve chat_id first, never pass person/user IDs, and pass only explicitly requested fields. It gives concrete steps for obtaining the ID and strong do/don't guidance, but it doesn't name alternative tools or state when not to use it, so it stops short of full exclusionary guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_create_draftEmail: Create draftAInspect

Create an email draft without sending. If replying, first read the source email and use the provider-appropriate reply_to_message_id (IMAP may use RFC822 Message-ID).

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toYes
bccNo
htmlNo
subjectNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
plain_textNo
reply_to_message_idNoReply reference. Gmail/Outlook normally use provider email ID; IMAP may require RFC822 Message-ID from the read email. Email reply reference: For Gmail/Outlook normally use the provider email id. For generic IMAP, reply_to_message_id may be the RFC822 Message-ID returned in the email data. Obtain with: email_read_message -> inspect id and provider/RFC Message-ID fields Never pass: subject, sender email address.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and destructiveHint=false, so it is a non-destructive write. The description adds the reply nuance and the requirement to obtain a reply_to_message_id, which is extra context. However, it does not describe side effects (e.g., that the draft is saved to the account and retrievable later) or any authentication requirements. Given the annotations already indicate mutation, the description adds moderate value but not a full behavioral picture.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The main action ('without sending') is front-loaded, and the reply guidance is provided efficiently. Every word contributes to clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 8 parameters and no output schema. The description covers the core action and the tricky reply scenario, but it does not clarify whether html and plain_text can both be provided, the relationship between them, or how the draft is later sent (e.g., via email_send_draft). It also doesn't mention error conditions or the expectation that drafts are stored. For a draft-creation tool with this many parameters, more guidance would improve completeness, but the description is adequate for basic usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (account_id and reply_to_message_id have descriptions). The tool description adds context specifically for reply_to_message_id (provider-specific formats and how to obtain it), which is valuable. However, it does not explain the common parameters (to, cc, bcc, html, plain_text, subject) beyond what the schema provides. With low coverage, the description could compensate more, but it only partially does.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Create' and the resource 'email draft', and explicitly notes 'without sending', which distinguishes it from email_send_draft and email_send. It also hints at the reply scenario, making the primary purpose unambiguous even without examining sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides specific guidance for the reply case ('If replying, first read the source email...'), which helps when to use this tool with a reply reference. It does not explicitly mention alternatives like email_update_draft or email_send_draft, but the 'without sending' clarification implicitly distinguishes it from send operations. This is useful context though not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_create_folderEmail: Create folderBInspect

Create a mailbox folder/label. parent_id, when supplied, must be an exact existing folder ID resolved from email_list_folders; it is not a parent folder display name.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
parent_idNoExact existing parent folder ID. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false, so the description does not need to restate these. It adds a useful constraint about parent_id not being a display name, which clarifies parameter behavior. However, it does not disclose potential side effects like duplicate handling or whether the operation is reversible, which would be helpful given it is a mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise: one sentence for purpose and one for the critical parent_id constraint. It is front-loaded with the primary action and contains no filler. Every sentence adds value, making it efficient for an agent to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple create operation with 3 parameters, the description is adequate. It explains the purpose and the key constraint on parent_id. However, it does not mention what happens when parent_id is omitted (e.g., creates at root level) or what the return value is (since no output schema exists). These are minor gaps given the tool's simplicity and the schema's coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67% (parent_id and account_id are described). The description adds a redundant clarification about parent_id being an exact ID from email_list_folders, which is already in the schema. It adds no information about the 'name' parameter. Since the schema already covers most parameters, the description adds marginal value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'create' and the resource 'mailbox folder/label', which distinguishes it from sibling tools like email_delete_folder, email_update_folder, and email_list_folders. It is specific enough to avoid confusion with other email actions, though it could be more explicit about creating a new folder vs. other folder operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It does not mention that this is the tool for creating folders while others are for updating or deleting, nor does it state any prerequisites beyond the parent_id note. The parent_id note hints at needing email_list_folders, but it does not clarify usage context relative to siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_delete_draftEmail: Delete draftA
Destructive
Inspect

Discard one exact draft. draft_id comes from draft list/create; destructive.

ParametersJSON Schema
NameRequiredDescriptionDefault
draft_idYesExact draft ID returned by email_list_drafts/email_create_draft; never use subject or email_id as draft_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide destructiveHint=true, readOnlyHint=false, and idempotentHint=false, so the description's 'destructive' tag is largely redundant. It does add that the operation affects exactly one draft and that the ID must come from list/create, which helps prevent misuse. It does not mention permanence/irreversibility, but the destructive annotation already signals that risk.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single short sentence that front-loads the core action, then adds the necessary input source and a destructive warning. There is no filler or repetition beyond the intentional emphasis on destructiveness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive tool, the schema and annotations cover parameter semantics and safety, while the description clarifies scope and input provenance. It lacks an explicit note about response/confirmation behavior and does not distinguish from email_trash, but the essentials for correct invocation are present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents draft_id as the exact ID from email_list_drafts/email_create_draft with a warning not to use subject or email_id. The account_id schema also provides detailed guidance. The tool description only restates ID provenance and adds no new parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a specific verb and object: 'Discard one exact draft.' This clearly identifies the tool as a single-draft deletion operation. It does not explicitly name sibling tools like email_trash or email_delete_folder, but the scope ('exact draft') plus the title make the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a useful usage cue: the draft_id must come from email_list_drafts or email_create_draft, implying the tool is for drafts that already exist. However, it does not explicitly mention when to prefer this over alternatives such as email_trash, nor does it state exclusions. The destructive warning is a caution, not a usage routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_delete_folderEmail: Delete folderA
Destructive
Inspect

Delete one exact mailbox folder/label. Resolve folder_id first and verify target; destructive. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.

ParametersJSON Schema
NameRequiredDescriptionDefault
folder_idYesExact provider folder/label ID from email_list_folders/email_resolve_folder. Human folder names are not IDs. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the destructive nature is covered. The description adds operational caution: 'verify target' and the 'exact' match requirement, plus the explicit ID-type warning. It does not disclose downstream effects (e.g., whether messages inside the folder are deleted), but the annotations carry the primary behavioral burden and the description adds useful safety context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences and front-loaded with the core action. The third sentence is long and partly duplicates the schema's folder_id description, but it consolidates the ID-source workflow and the human-name warning into one place. Overall it is dense without being bloated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With only 2 params, no output schema, and annotations covering the destructive and read-only profile, the description covers the key prerequisites and the most common failure mode (passing a human folder name). It does not mention account_id, but the schema fully handles that. It also doesn't explain what happens to folder contents, but that is arguably beyond what a delete invocation needs from the description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline applies. The description repeats folder_id semantics already in the schema but adds a concise resolution path ('Obtain with: email_list_folders -> folder.id'). It stays silent on account_id, but the schema provides a detailed explanation of when and how to pass it. The description adds marginal value on top of the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-resource statement: 'Delete one exact mailbox folder/label.' The qualifier 'one exact' and the focus on folder/label clearly distinguish it from sibling tools like email_trash (messages), email_delete_draft, and email_update_folder. It also signals that resolution is a separate concern, differentiating from email_resolve_folder.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear prerequisite workflow: 'Resolve folder_id first and verify target.' It also gives a strong negative constraint: 'Never pass: human folder name such as Inbox when an ID is required.' While it doesn't explicitly name alternative tools or state when not to use this tool, the context of the email_* siblings and the ID-resolution guidance make usage conditions clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_get_attachmentEmail: Get attachmentA
Read-onlyIdempotent
Inspect

Retrieve one exact attachment from Gmail, Outlook/Microsoft or IMAP. Required chain: resolve/list email -> email_id -> read email -> attachment.id -> retrieve. Filename is NOT attachment_id. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP. Attachment ID: Exact attachment id returned inside a specific email/message. Obtain with: read the parent email/message first -> attachment.id Never pass: filename, URL.

ParametersJSON Schema
NameRequiredDescriptionDefault
email_idYesExact email provider ID from email list/read/resolve tools. Do not pass subject or RFC Message-ID unless a specific reply field explicitly asks for RFC Message-ID. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
attachment_idYesExact attachment ID from the already-read parent email. Never use filename or URL as attachment_id. Attachment ID: Exact attachment id returned inside a specific email/message. Obtain with: read the parent email/message first -> attachment.id Never pass: filename, URL.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already mark this as read-only and idempotent, and the description adds critical behavioral context that the agent cannot infer: on IMAP the email ID changes when a message is moved or a draft is updated, so only the last-returned ID should be reused. This materially affects whether the call succeeds.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well structured with clear labels (Email provider ID, Attachment ID) and front-loads the purpose and required chain. Some content duplicates the schema parameter descriptions, so it is not optimally concise, but the organization makes it easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter retrieval tool with no output schema, the description covers the prerequisites, provider-specific ID behavior, what not to pass, and how to obtain valid IDs. The optional account_id is fully documented in the schema, so nothing needed to call the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents all three parameters fully, so the baseline is 3, but the description adds the explicit retrieval chain and the prohibition on using filenames, URLs, or RFC Message-IDs as IDs. That operational guidance clarifies the meaning of email_id and attachment_id beyond their schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Retrieve one exact attachment from Gmail, Outlook/Microsoft or IMAP.' It also states the exact input chain and explicitly warns that filename is not attachment_id, which distinguishes this from email_read_message and related email tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear when-to-use sequence: resolve/list email -> email_id -> read email -> attachment.id -> retrieve, and tells the caller what must be done before calling. It does not explicitly name alternative tools or say when not to use it, but the chain and 'Never pass' list provide strong usage constraints.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_get_draftEmail: Get draftA
Read-onlyIdempotent
Inspect

Get one exact draft. draft_id must come from email_list_drafts or email_create_draft; never use subject/email_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
draft_idYesExact draft ID returned by email_list_drafts/email_create_draft; never use subject or email_id as draft_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry readOnly/idempotent/non-destructive facts. The description adds only the 'exact' matching semantics and ID source rule, not return shape, error behavior, or auth side effects. That is acceptable but not rich, so a 3 matches the minimal added value beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two clauses, one sentence, no filler; the core action and the critical constraint are front-loaded. Every word contributes to correct use.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only fetch-by-ID tool, the description plus schema covers the required ID source and the account disambiguation policy via account_id. It does not describe the return payload, but the name and readOnlyHint make the outcome sufficiently predictable; a small gap remains for agents expecting error semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the same draft_id provenance warning already present in the schema and a thorough account_id explanation in the schema. The tool description repeats the draft_id rule but adds no new parameter meaning, so it earns the schema-coverage baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Get one exact draft' – a specific verb and resource that make the tool's function unmistakable. It immediately differentiates from list-style siblings by emphasizing 'exact draft,' and the constraint 'draft_id must come from email_list_drafts or email_create_draft' further anchors its role in the draft workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the required ID provenance and warns against using subject/email_id, which is actionable guidance for correct invocation. It does not explicitly name alternate tools to use for other draft operations, such as email_list_drafts for searching or email_send_draft for sending, so it is not a complete routing guide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_get_folderEmail: Get folderA
Read-onlyIdempotent
Inspect

Get one exact Gmail/Outlook/IMAP folder. Resolve folder name -> folder.id first. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.

ParametersJSON Schema
NameRequiredDescriptionDefault
folder_idYesExact provider folder/label ID from email_list_folders/email_resolve_folder. Human folder names are not IDs. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is covered. The description adds the prerequisite of resolving the ID first, which is behavioral context beyond annotations. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no fluff. The purpose is front-loaded, and the ID requirement is stated clearly. Slightly repetitive with the schema description but overall efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with complete schema and annotations covering safety, the description captures the key gotcha (ID vs human name). It doesn't address edge cases like invalid IDs or return format, but given the tool's simplicity and the absence of an output schema, this is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%; both parameters have detailed descriptions. The description reinforces the folder_id requirement but adds no new meaning beyond what the schema already states. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Get one exact Gmail/Outlook/IMAP folder.' It explicitly distinguishes from listing by saying 'one exact,' and contrasts with email_list_folders and email_resolve_folder. The purpose is unambiguous and differentiates from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit step-by-step guidance: 'Resolve folder name -> folder.id first' and 'Obtain with: email_list_folders -> folder.id.' It also gives a clear exclusion: 'Never pass: human folder name such as Inbox when an ID is required.' This fully covers when and how to use the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_get_threadEmail: Get threadA
Read-onlyIdempotent
Inspect

Retrieve full email thread by exact thread_id. Obtain thread_id from email list/read response; do not substitute subject/email_id. Email thread ID: Exact thread/conversation id returned by the email provider when available. Obtain with: email list/read result -> thread_id Never pass: email_id unless equal according to returned data.

ParametersJSON Schema
NameRequiredDescriptionDefault
thread_idYesExact thread ID returned by the email provider. Do not substitute email_id unless returned data says they are equal. Email thread ID: Exact thread/conversation id returned by the email provider when available. Obtain with: email list/read result -> thread_id Never pass: email_id unless equal according to returned data.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description need not repeat safety. It adds valuable context about the thread_id: it must be the exact provider-returned ID and email_id should not be substituted unless equal. This goes beyond annotations and helps avoid common errors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description contains redundancy: 'Obtain thread_id from email list/read response; do not substitute subject/email_id.' is essentially repeated later as 'Obtain with: email list/read result -> thread_id Never pass: email_id unless equal according to returned data.' This wastes words and violates the principle that every sentence should earn its place. The core instruction is clear but could be condensed into one or two sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only retrieval tool with two parameters and no output schema, the description covers the critical aspects: how to obtain the thread_id, what not to pass, and the existence of account_id (via schema). It does not mention edge cases like invalid thread_id, but that is not essential for this operation. The description is complete enough for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are documented in the schema. The description adds significant meaning for thread_id by explaining how to obtain it and what not to pass (email_id, subject). This elevates it beyond the baseline of 3. Account_id is not elaborated in the description, but its schema description is sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Retrieve full email thread by exact thread_id.' It specifies the resource (full email thread) and the required identifier. This distinguishes it from sibling tools like email_read_message (single message) and email_list_messages (list of messages) by the phrase 'full email thread'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on how to obtain the thread_id: 'Obtain thread_id from email list/read response' and warns not to substitute subject/email_id. It implies this tool is for retrieving the whole thread, but does not explicitly list alternatives or exclusions. However, the guidance on obtaining the ID is concrete and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_list_contactsEmail: List contactsA
Read-onlyIdempotent
Inspect

List Gmail/Microsoft contacts to resolve a human recipient name to an email address before composing. Generic IMAP normally has no provider contact directory; use mailbox context instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNoOpaque cursor returned by previous contact listing.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, idempotent, and non-destructive, so the safety profile is clear without the description. The description adds useful behavioral context by revealing that provider contact directories exist only for Gmail/Microsoft and not generic IMAP, which sets expectations about availability and fallback behavior. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver the core action, the purpose, and the key limitation without wasted words. The primary verb and resource are front-loaded, and the IMAP caveat is the second sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description nevertheless provides enough context for correct invocation: provider scope, when to use it, and a fallback for IMAP. The account_id disambiguation rules are detailed in the schema. The main omission is a concrete statement of what the response contains (e.g., contact names and addresses), but this is not critical for a list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema documents cursor and account_id with detailed descriptions, but the tool description itself does not explain any parameters. At 67% schema coverage, the missing limit description is minor given its simple min/max integer type. Overall the description adds no parameter semantics beyond the schema, but the schema handles most of the load; a neutral score is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('List'), resource ('contacts'), and provider scope ('Gmail/Microsoft'), and ties it to a concrete workflow ('resolve a human recipient name to an email address before composing'). It also distinguishes the tool from generic IMAP by noting that IMAP has no provider contact directory. This clearly differentiates it from siblings like email_list_messages or whatsapp_list_contacts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly defines when to use the tool ('before composing') and when not to ('Generic IMAP normally has no provider contact directory'), directing users to 'use mailbox context instead.' The account_id schema description further clarifies the multi-account case with explicit instructions to list and ask rather than guess. This gives the agent unambiguous routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_list_draftsEmail: List draftsA
Read-onlyIdempotent
Inspect

List email drafts. Returned draft.id is the draft_id for get/update/send/delete. draft_id is not email_id or subject.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNoOpaque pagination cursor returned by previous call.
any_emailNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds a small behavioral detail about draft.id not being email_id or subject, which helps prevent misuse. It does not disclose pagination or response structure, but that is partially covered by the schema's cursor description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise—two sentences with no filler. The primary purpose is front-loaded, and the critical clarification about draft.id is placed immediately after, making it efficient for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list operation with annotations covering safety and the schema covering pagination and account selection, the description is nearly complete. It might benefit from noting the return type (a list of drafts) but that is implied by 'List'. The clarification about draft.id addresses the most likely point of confusion, so the tool is effectively usable without further context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%: cursor and account_id have descriptions, while limit and any_email do not. The description does not mention any parameters, so it adds no semantic value beyond the schema. Since the schema covers half, the baseline of 3 is appropriate, and the description does not compensate for the missing 50%.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List email drafts') and the resource, making it distinct from sibling tools like email_get_draft or email_list_messages. It also adds a critical clarification about the returned draft.id, which is essential for chaining with other draft operations, removing ambiguity about the ID semantics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by stating that the returned draft.id is used for get/update/send/delete, but it does not explicitly distinguish when to use this tool versus email_list_messages or email_get_draft. There is no 'when not to use' guidance, though the context of listing drafts is clear enough for basic routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_list_folder_messagesEmail: List folder messagesA
Read-onlyIdempotent
Inspect

List messages inside one exact folder. Especially for IMAP: list folders -> select folder.id -> list messages -> email.id -> read/action. Dates: after/before are ISO 8601 UTC datetimes (YYYY-MM-DDTHH:MM:SS.sssZ); for "today" use after=start of the user's day. Counting: an empty page is not "zero emails" unless no filter was applied; for totals use folder.total_count/unread_count from email_list_folders instead of listing. IMAP pages are capped at 50 live messages; keep limit small (20) to avoid runtime timeouts. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNo
fromNo
afterNo
limitNo
beforeNo
cursorNoOpaque pagination cursor returned by previous message listing.
any_emailNo
folder_idYesExact provider folder/label ID from email_list_folders/email_resolve_folder. Human folder names are not IDs. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only and idempotent, but the description adds significant behavioral context: IMAP page caps at 50, keep limit at 20 to avoid timeouts, empty pages don't imply zero emails when filters are applied, and IMAP IDs change when messages are moved or drafts updated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and every sentence carries practical value (date formats, counting semantics, ID stability, limits). It is long and could be restructured into clearer sections, but there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers workflow, date format, pagination hints, ID stability, and common mistakes. With no output schema, it could describe the response shape more fully, but it does reference email.id as the key outcome, so an agent can proceed confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, so the description partially compensates by explaining after/before as ISO 8601 UTC datetimes, the need to keep limit small, and the exactness of folder_id. It does not elaborate on to/from/any_email, but those are conventional filters; the main email-ID caveat is also detailed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'List messages inside one exact folder.' This clearly distinguishes it from email_list_folders and email_list_messagesa, and the workflow mention of 'folder.id' reinforces the scoped intent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit workflow ('list folders -> select folder.id -> list messages -> email.id -> read/action') and an explicit when-not-to-use ('for totals use folder.total_count/unread_count from email_list_folders instead of listing'). Also warns against passing human folder names, leaving no ambiguity about when this tool should be called.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_list_foldersEmail: List foldersA
Read-onlyIdempotent
Inspect

List Gmail labels, Outlook folders or IMAP folders. Returned folder.id is required by folder-specific operations. For IMAP this is normally the first step before listing messages. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNoOpaque cursor returned by prior folder listing; never invent.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so the description correctly avoids restating those. It adds behavioral value by explaining that the returned folder.id is essential for downstream operations and by cautioning against using human names. These details go beyond the structured annotations and help the agent understand the tool's role in a workflow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only three sentences, but it contains redundancy: the need for folder.id is mentioned twice ('Returned folder.id is required' and 'Obtain with: email_list_folders -> folder.id'). This repetition could be trimmed without losing meaning. The main purpose is front-loaded, but the wording is not maximally concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple listing tool with no output schema, the description covers the essential context: it explains what the tool returns (folder.id), when to use it (first step for IMAP), and a critical pitfall (never pass human names). It does not discuss pagination or account selection, but those are documented in the schema. Given the tool's simplicity, this is adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% – cursor and account_id have descriptions, while limit only has min/max bounds. The description does not elaborate on any parameter semantics, but the schema already covers the important ones. Since coverage is moderate and the description adds nothing about parameters, a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List') and the resource ('Gmail labels, Outlook folders or IMAP folders'), making it obvious what the tool does. It also distinguishes itself from siblings by emphasizing that the returned folder.id is required by folder-specific operations, setting it apart from email_list_folder_messages or email_get_folder.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides useful usage context: it notes that for IMAP this is normally the first step before listing messages, and warns against passing human-readable folder names when an ID is required. However, it does not explicitly name alternatives like email_resolve_folder or email_get_folder, so the guidance is implicit rather than fully explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_list_messagesEmail: List messagesA
Read-onlyIdempotent
Inspect

List email messages from the user's connected Gmail, Microsoft/Outlook OR generic IMAP mailbox. This is especially useful for IMAP mailboxes not covered by native agent connectors, and for cross-channel workflows that combine email context with LinkedIn/WhatsApp/Instagram. Use to find email_id before opening a message. For totals use email_list_folders (folder.total_count); IMAP pages are capped at 50 and listed live, keep limit small (20).

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNoISO 8601 UTC datetime; only emails after it (exclusive).
limitNo
beforeNoISO 8601 UTC datetime; only emails before it (exclusive).
cursorNo
folder_idNoExact folder/label ID returned by email_list_folders/email_resolve_folder. Never pass a human folder name unless the provider returned it as the ID. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark it read-only, open-world, and idempotent. The description adds that IMAP pages are capped at 50 and listed live, and that it's for finding email_id. It does not contradict annotations and adds useful behavioral detail beyond the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with purpose, then use cases and a pagination tip. No wasted words, well structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with 6 optional parameters and no output schema, the description covers purpose, use cases, alternative for totals, and pagination behavior. It doesn't describe return format, but that's not required without an output schema. It's reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema descriptions cover after, before, folder_id, and account_id (67% coverage). The description adds a hint to keep limit small (20) and implies cursor usage via the pagination mention. However, cursor and limit lack schema descriptions, so the description partially compensates but not fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it lists email messages from Gmail, Outlook, or IMAP, with a specific verb and resource. It also notes its utility for finding email_id before opening a message, distinguishing it from draft or folder-specific listers like email_list_drafts and email_list_folder_messages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly calls out that it's especially useful for IMAP mailboxes and cross-channel workflows, and directs to email_list_folders for totals. It also advises keeping limit small (20) for IMAP. This gives clear when-to-use context, though it doesn't explicitly contrast with email_list_folder_messages.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_mark_readEmail: Mark readAInspect

Mark one exact email read. Resolve human email reference -> email_id first. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.

ParametersJSON Schema
NameRequiredDescriptionDefault
email_idYesExact provider email ID from email list/read/resolve. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already state readOnly=false, idempotent=false, and destructive=false. The description adds valuable behavioral context beyond that: IMAP IDs encode folder+UID, change on moves/draft updates, and must always come from the last operation. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded, but the description becomes a dense run-on that repeats the schema text nearly verbatim and lacks clear structure, e.g. 'after a change Never pass'. Bulleted caveats would make it much easier to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple mutation, the description covers the critical resolution workflow, ID acquisition, IMAP ID-staleness, and forbidden input values. Account_id handling is covered in the schema. The only minor gap is no mention of the return shape since there is no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so a baseline of 3 applies. The description adds extra meaning with 'Resolve human email reference -> email_id first' and reinforces what must never be passed, which helps the agent construct the email_id parameter correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Mark one exact email read', a specific verb, resource, and scope. The word 'exact' plus the read state distinguishes it from siblings like email_mark_unread and email_read_message without needing to name them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear workflow: resolve human references to email_id first, obtain IDs from email_list_messages or email_list_folder_messages, and avoid stale IDs on IMAP. It does not explicitly name alternative tools for other read-related intents, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_mark_unreadEmail: Mark unreadAInspect

Mark one exact email unread. Resolve email_id first. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.

ParametersJSON Schema
NameRequiredDescriptionDefault
email_idYesExact provider email ID from email list/read/resolve. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a mutation (readOnlyHint=false), but the description adds crucial behavioral context beyond that: IMAP IDs encode folder+UID and change on moves/draft updates, so the caller must always reuse the last-operation ID. It also explicitly forbids passing RFC Message-ID, subject, or pre-move IDs. This is valuable, non-obvious behavioral information.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and a prerequisite, then presents essential ID-resolution rules. It is longer than strictly necessary because it duplicates the schema's parameter text, but every included caveat ('CHANGES when moved', 'Never pass: RFC Message-ID') carries real operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple state-change tool with no output schema, this description covers the only genuinely difficult part: how to obtain a valid email_id, under what conditions it goes stale, and which ID forms must never be used. The optional account_id handling is fully specified in the schema. Nothing needed for a correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the property descriptions already fully explain email_id and account_id. The tool description repeats the email_id semantics rather than adding new parameter-level meaning, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action ('Mark one exact email unread') and clearly identifies the resource ('one exact email') and the intended state ('unread'). The word 'exact' and the instruction to 'Resolve email_id first' distinguish this from bulk operations and from the sibling email_mark_read without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly establishes when to use the tool: after resolving an email_id via email_list_messages or email_list_folder_messages, and it warns against using stale or non-provider IDs. It does not explicitly name the alternative email_mark_read or state 'when not to use' conditions, but the workflow context is sufficiently clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_move_or_labelEmail: Move or labelAInspect

Move/label one exact email. The result is the email after the change: on IMAP its id CHANGES (folder+UID), so reuse result.id for any follow-up. Resolve email_id independently, then resolve every human folder name to folder.id. Never put 'Inbox'/'Archive' strings in folders_ids unless the provider actually returned those strings as IDs. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.

ParametersJSON Schema
NameRequiredDescriptionDefault
email_idYesExact provider email ID from email list/read/resolve. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.
specificsNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
folders_idsYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate mutation (readOnlyHint=false) and non-idempotence (idempotentHint=false). The description adds critical context: on IMAP the email ID changes after move/update, so the result.id must be reused. It also warns against using stale IDs. This goes beyond annotations and is essential for correct follow-up calls.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-organized, starting with the core purpose and then diving into necessary caveats and resolution steps. It is front-loaded with the key behavior (ID change) and structured into clear sections. While a bit verbose, the complexity of the tool justifies the length; every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description explains the return value ('the email after the change') and the critical ID mutation. It covers ID resolution for both email and folders, warns about common pitfalls, and clarifies account_id handling. It lacks explicit error conditions or edge cases, but covers the primary use cases and traps. Slightly incomplete for specifics parameter, but overall strong.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50% (email_id and folders_ids have descriptions; specifics and account_id lack them). The description compensates by providing detailed instructions for email_id and folders_ids, including how to obtain and what not to pass. For specifics and account_id, the description offers some guidance (e.g., account_id resolution), but specifics remains underdocumented. Overall, the description adds significant value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Move/label') and resource ('one exact email') with scope. Clearly distinguishes from siblings like email_trash, email_update_draft, and email_send by focusing on moving/labeling. The description also mentions the result is the email after the change, which is unique.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance on how to resolve email_id and folder IDs, including specific sources (email_list_messages, email_list_folders) and what to avoid (RFC Message-ID, human folder names). While it doesn't explicitly compare to alternatives like email_trash, it clearly scopes the operation and offers procedural steps. Lacks explicit 'when not to use' but strong on how to use correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_read_messageEmail: Read messageA
Read-onlyIdempotent
Inspect

Read a specific email including body/headers from Gmail, Microsoft/Outlook or IMAP. Use after email_list_messages and before a contextual reply or cross-channel decision.

ParametersJSON Schema
NameRequiredDescriptionDefault
email_idYesExact provider email ID returned by an email list/resolve/read result. Never pass the subject or sender. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint, idempotentHint, and non-destructive behavior, lowering the bar. The description adds useful behavioral context by stating that it retrieves body/headers across multiple providers, and the schema further clarifies IMAP ID mutability. This goes beyond simply repeating the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler: the first sentence states the core operation and scope, the second provides necessary workflow positioning. Every sentence earns its place and key information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description's mention of 'body/headers' gives an agent a reasonable idea of return content. Combined with rich parameter schema and annotations covering safety and idempotency, the definition is sufficiently complete for correct invocation, though it could add more detail on response format or error cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the input schema already provides extensive detail on email_id provenance, IMAP ID behavior, and account_id disambiguation rules. The tool description itself adds little parameter meaning beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'Read a specific email including body/headers' and names the provider scope 'Gmail, Microsoft/Outlook or IMAP.' It is distinguishable from list-oriented siblings like email_list_messages, though it does not explicitly contrast itself with closely related email_get_thread.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear pipeline context: 'Use after email_list_messages and before a contextual reply or cross-channel decision.' This tells the agent where the tool fits in a workflow, but it does not give when-not-to-use guidance or direct comparisons with alternatives like email_get_thread or email_resolve_message.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_resolve_folderEmail: Resolve folderB
Read-onlyIdempotent
Inspect

List mailbox folders/labels to map human names such as Inbox, Archive, Junk or a custom folder to exact folder_id before moving/labeling or listing folder messages. This is especially important for IMAP. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive, so the safety profile is covered. The description adds purpose and IMAP importance, but does not disclose pagination behavior (limit/cursor) or the exact return format, which would be useful for a read operation. Since annotations cover the main safety aspects, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the core purpose, followed by a warning and an ID clarification. The 'Mailbox folder/label ID' sentence is somewhat redundant but not excessive. It earns its keep without being verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only lookup tool, the description does not specify the output structure (e.g., list of {name, id} pairs) or explain the limit/cursor parameters. Given no output schema and low parameter coverage, an agent lacks critical information to correctly parse results or handle pagination. The tool is simple, but the description leaves notable gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33% (only account_id has a description). The description does not explain limit or cursor semantics at all, and it adds no parameter-specific guidance beyond what the schema already provides for account_id. With low coverage, the description was expected to compensate but fails to do so.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb (list/map) and resource (mailbox folders/labels) with the specific goal of mapping human names to exact folder_id. It differentiates from siblings like email_list_folders by framing this as a resolution step before operations that need IDs, and explicitly warns against passing human names when an ID is required.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use context ('before moving/labeling or listing folder messages') and a clear warning ('Never pass: human folder name...'). It references email_list_folders as the source of folder.id, implying the distinction. However, it does not explicitly state when to use email_list_folders instead of this tool, leaving a slight gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_resolve_messageEmail: Resolve messageA
Read-onlyIdempotent
Inspect

Search/list email candidates so a human reference such as sender, recipient, subject or date can be mapped to exact email_id before read/reply/trash/move/attachment operations. For generic IMAP, if account-wide listing is unavailable, use email_list_folders then email_list_folder_messages instead. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP. Email reply reference: For Gmail/Outlook normally use the provider email id. For generic IMAP, reply_to_message_id may be the RFC822 Message-ID returned in the email data. Obtain with: email_read_message -> inspect id and provider/RFC Message-ID fields Never pass: subject, sender email address. Email thread ID: Exact thread/conversation id returned by the email provider when available. Obtain with: email list/read result -> thread_id Never pass: email_id unless equal according to returned data.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNo
fromNo
afterNo
limitNo
beforeNo
cursorNo
any_emailNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, openWorldHint, idempotentHint), the description adds crucial behavioral context: IMAP email IDs encode folder+UID and change when moved/draft updated, and the returned ID should always be reused from the last operation. It also explains how to obtain each ID type and what not to pass, substantially enriching the agent's mental model.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured into labeled sections (Email provider ID, Email reply reference, Email thread ID) and front-loaded with the core purpose. The length is justified by complex provider-specific ID semantics, though a few sentences could be tightened without losing value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of provider-specific ID behavior and no output schema, the description covers the most important usage context, alternatives, and dangerous inputs. It is slightly incomplete on return-value details and some parameter behavior, but for a resolution/search tool it provides enough for an agent to use it effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema coverage at only 13% and 8 parameters, the description must compensate, but it does not define most parameters. The text gestures at sender/recipient/subject/date mapping to to/from/any_email/after/before without naming them, and limit/cursor remain unexplained. Only account_id is documented in the schema; the description adds little per-parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Search/list email candidates' with the explicit purpose of mapping human references to exact email_id before operations like read/reply/trash/move. It further distinguishes itself from siblings by naming the generic IMAP fallback (email_list_folders + email_list_folder_messages), making it clear this tool is for resolution, not listing messages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool ('before read/reply/trash/move/attachment operations'), gives a concrete alternative for generic IMAP when account-wide listing is unavailable, and lists 'Never pass' constraints. This gives an agent clear routing and exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_sendEmail: SendA
Destructive
Inspect

Send or reply to an email from the user's connected Gmail, Microsoft/Outlook or IMAP account. Use reply_to_message_id for a true reply when available. Only send after the user has clearly requested/approved the final recipients and content.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toYes
bccNo
htmlNo
subjectNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
plain_textNo
reply_to_message_idNoProvider reply reference from the source email. Gmail/Outlook normally use provider email ID; IMAP may require its RFC822 Message-ID. Email reply reference: For Gmail/Outlook normally use the provider email id. For generic IMAP, reply_to_message_id may be the RFC822 Message-ID returned in the email data. Obtain with: email_read_message -> inspect id and provider/RFC Message-ID fields Never pass: subject, sender email address.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the mutation nature is covered. The description adds valuable context: it must only be used with user consent, and it supports multiple providers. It also hints at reply behavior via reply_to_message_id, which is beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. It front-loads the core purpose (send/reply) and then adds the reply hint and consent requirement. Every word earns its place, and the structure is clean.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 8 parameters and no output schema, the description is relatively sparse. It does not explain what happens on success or failure, how to handle multiple connected accounts (though account_id is in schema), or edge cases like invalid recipients. It covers the essential 'when' but lacks depth for a complex operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only 2 of 8 parameters (account_id and reply_to_message_id) have descriptions in the schema, which is 25% coverage. The tool description does not explain common parameters like to, cc, bcc, subject, html, or plain_text. It mentions reply_to_message_id but that is already covered in the schema, so it adds no new meaning. With low schema coverage, the description should compensate, but it does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool sends or replies to an email from a connected Gmail, Outlook, or IMAP account. It distinguishes itself from sibling tools like email_create_draft and email_send_draft by emphasizing direct send/reply, and mentions the reply_to_message_id for true replies, which sets it apart from draft workflows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear context on when to use this tool (to send or reply) and includes a critical safety guideline about only sending after user approval. However, it does not explicitly exclude alternatives like email_create_draft or email_send_draft, so the differentiation is implicit rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_send_draftEmail: Send draftA
Destructive
Inspect

Send one exact existing draft. Resolve draft_id and inspect final recipients/content first when not already explicitly approved; this creates a real external send.

ParametersJSON Schema
NameRequiredDescriptionDefault
draft_idYesExact draft ID returned by email_list_drafts/email_create_draft; never use subject or email_id as draft_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint=true, but the description adds real-world consequence: 'this creates a real external send.' It also instructs the agent to inspect recipients/content before sending, reinforcing that this action is irreversible and has external impact. This goes beyond the bare annotation and provides valuable behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. The core action is front-loaded ('Send one exact existing draft'), followed immediately by the critical safety instruction. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive action with no output schema, the description covers the essential pre-send verification step and discloses the external-send consequence. It doesn't describe return values, but that is less critical for a send action. Overall, the agent has everything needed to invoke the tool safely and correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already well-documented in the input schema. The tool description itself adds little about parameter semantics; it references draft_id but not account_id. Per the rubric, with high schema coverage the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise verb and resource: 'Send one exact existing draft.' It clearly differentiates from sibling tools like email_create_draft, email_update_draft, and email_send by emphasizing it sends an already-created, exact draft rather than composing or modifying. No ambiguity remains about the tool's function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a crucial operational condition: 'Resolve draft_id and inspect final recipients/content first when not already explicitly approved.' This tells the agent when it is appropriate to execute the send and what preconditions must be met. It does not explicitly name alternative tools or give a contrast to email_send, but the context and phrasing make the intended use clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_trashEmail: TrashB
Destructive
Inspect

Trash one exact email. Resolve email_id first; destructive mailbox action. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.

ParametersJSON Schema
NameRequiredDescriptionDefault
email_idYesExact provider email ID from email list/read/resolve. Email provider ID: Exact email ID returned by Nilyo/Unipile for the connected mailbox. On IMAP (and Exchange over IMAP) the ID encodes folder + UID: it CHANGES when the email is moved or a draft is updated; always reuse the id returned by the last operation. Obtain with: email_list_messages or email_list_folder_messages -> email.id; the id returned by email_move_or_label / email_update_draft after a change Never pass: RFC Message-ID unless a tool explicitly documents it, subject, an email_id captured before a move/update on IMAP.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, and the description reinforces that with 'destructive mailbox action.' It adds valuable context about ID instability: the ID changes on move/update, and it must be the latest one. It also warns against passing RFC Message-ID or stale IDs. These are beyond annotations and help avoid misuse.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a long, dense paragraph, especially for email_id, mixing prerequisites, warnings, and ID acquisition steps. It front-loads the core action but then becomes a wall of text without bullets or clear sectioning. While informative, it is not concise or well-structured for quick consumption.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite verbosity, it covers all critical operational details: how to resolve the ID, when it becomes invalid, what to never pass, and how to handle the optional account_id with multiple accounts. With no output schema, it explains the return behavior implicitly via 'destructive action.' An agent can safely invoke it correctly after reading this.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the description essentially repeats the same text for email_id and adds a concise account_id explanation. It does not add meaning beyond the schema; it mirrors it. Since the schema already documents the parameters thoroughly, a baseline of 3 is appropriate; no extra semantic value is provided by the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: 'Trash one exact email.' It also flags it as a 'destructive mailbox action,' which sets expectations. It does not explicitly contrast with sibling tools like email_move_or_label, but the purpose is unambiguous and not a tautology.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives. It does not mention that email_move_or_label could be used for moving to trash, or that this is a permanent action, nor does it specify prerequisites beyond resolving the ID. The only context is 'destructive mailbox action,' which implies but does not state selection criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_update_draftEmail: Update draftBInspect

Update an exact existing draft. On IMAP the updated draft gets a NEW draft.id (returned in the result); use it for email_send_draft. without sending. Resolve/read draft first when preserving recipients/content matters.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toNo
bccNo
htmlNo
subjectNo
draft_idYesExact draft ID returned by email_list_drafts/email_create_draft; never use subject or email_id as draft_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
plain_textNo
reply_to_message_idNoReply reference. Gmail/Outlook normally use provider email ID; IMAP may require RFC822 Message-ID from the read email. Email reply reference: For Gmail/Outlook normally use the provider email id. For generic IMAP, reply_to_message_id may be the RFC822 Message-ID returned in the email data. Obtain with: email_read_message -> inspect id and provider/RFC Message-ID fields Never pass: subject, sender email address.

TDQS

B3.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a mutation (readOnlyHint=false) and non-destructive (destructiveHint=false). The description adds valuable behavioral context: on IMAP the draft ID changes and the new ID must be used for email_send_draft, and that reading the draft first is advised to preserve unspecified fields. This goes beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description contains an awkward fragment: 'without sending.' which appears as an incomplete sentence with a double space before it. While the core message is short, the structure is unclear and could confuse an agent. The placement of 'without sending' after the IMAP note seems out of order.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 9 parameters, no output schema, and sparse annotations, the description should clarify the update semantics and expected result. It mentions the new draft ID on IMAP but does not describe the return object, how missing fields are handled, or the exact behavior for non-IMAP providers. It also omits guidance on which parameters are typically updated together. The description is incomplete for an agent to confidently call this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, with only draft_id, account_id, and reply_to_message_id having descriptions. The tool description provides no additional meaning for the remaining six parameters (to, cc, bcc, html, subject, plain_text). It does not clarify whether the update is a full replacement or a merge, nor which fields are optional. The description fails to compensate for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Update' and resource 'exact existing draft', distinguishing it from create/send/delete siblings. The qualifier 'exact existing' implies it targets a specific draft, but it does not explicitly contrast with email_create_draft or email_get_draft. The redundant 'without sending' adds no value but does not mislead.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description includes a precondition: 'Resolve/read draft first when preserving recipients/content matters.' This is useful guidance for a partial-update scenario. However, it does not explicitly state when to use this tool versus alternatives like email_create_draft or email_send_draft, nor does it list exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

email_update_folderEmail: Update folderAInspect

Rename/move one existing folder. Resolve folder_id first; parent_id is also an exact folder ID when supplied. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
folder_idYesExact provider folder/label ID from email_list_folders/email_resolve_folder. Human folder names are not IDs. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.
parent_idNoExact parent folder ID from folder listing. Mailbox folder/label ID: Exact Gmail label, Outlook folder or IMAP folder id. Obtain with: email_list_folders -> folder.id Never pass: human folder name such as Inbox when an ID is required.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, so the mutation profile is known. The description adds that it renames/moves an existing folder and that parent_id is an exact folder ID, but doesn't disclose side effects like whether moving changes child folders or whether renaming affects labels. It doesn't contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the core action. The repeated ID guidance is somewhat redundant with the schema descriptions, but it's placed efficiently and the critical warning is clear. It earns its place by emphasizing the ID requirement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers the key prerequisites (resolve folder_id, use exact IDs) and the main parameters. It doesn't explain return values or side effects, but the annotations cover the safety profile and the schema covers parameters. The main gap is lack of detail on what happens when moving a folder (e.g., does it affect children), but this is a minor gap for a simple rename/move operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75%, so the schema already documents folder_id, parent_id, and account_id in detail. The description adds the workflow hint 'Resolve folder_id first' and the 'Never pass human folder name' warning, which reinforces the schema. The name parameter is not described in the schema, but its meaning is obvious from the tool name and description. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Rename/move one existing folder.' It clearly distinguishes from email_create_folder and email_delete_folder. However, it doesn't explicitly contrast with email_move_or_label, which is a sibling that also moves/labels messages, though the folder-specific scope is clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: 'Resolve folder_id first' and 'Obtain with: email_list_folders -> folder.id'. It also provides a clear exclusion: 'Never pass: human folder name such as Inbox when an ID is required.' This tells the agent exactly how to prepare inputs and what not to do.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

feedback_report_bugFeedback: Report bugAInspect

Report a bug to the Nilyo team as a tracked issue. Use after a tool failed unexpectedly (TOOL_FAILED, wrong or empty result, broken flow) and the user agrees to report it; also when the user says 'ça ne marche pas' / 'report this'. Include the exact error code and details from the failing result so engineers can reproduce. Never include credentials, message bodies or third-party personal data. Ask the user for consent first (user_consent=true).

ParametersJSON Schema
NameRequiredDescriptionDefault
toolNoNilyo tool name involved, if any.
stepsNoMinimal steps to reproduce: which tools/arguments in which order (IDs can be included).
titleYesShort, specific title in English (what fails or what is wanted), e.g. 'email_list_messages fails on OVH IMAP mailbox with 501'.
actualNo
expectedNo
providerNoProvider involved when relevant: linkedin, whatsapp, instagram, telegram, gmail, outlook, imap, calendar.
severityNohigh = user blocked with no workaround; medium = wrong behaviour with a workaround; low = cosmetic.
error_codeNoError code returned by Nilyo, e.g. TOOL_FAILED, PROVIDER_VALIDATION_ERROR.
descriptionYesWhat the user was trying to do, in their words plus your observations. No passwords, tokens, message contents or third-party personal data.
user_consentYesMust be true: the user explicitly agreed to send this report to the Nilyo team.
error_detailsNoThe 'Details:' text of the failing result, verbatim.
sentry_event_idNoerror.sentry_event_id from the failing result, when present.
suspected_layerNoWhere you think the bug is: 'nilyo' (tool logic, resolution, errors, billing, connection flow) or 'unipile_api' (the provider connection layer returned an error like UNIPILE_5xx/provider/…). 'unknown' lets the server infer it.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are mostly negative hints and do not describe side effects, consent, or data-handling expectations, so the description carries the burden. It discloses that the tool creates a tracked issue, requires user_consent=true, should include exact error codes/details for reproduction, and must never include credentials, message bodies, or third-party personal data. This is meaningful behavioral context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four dense sentences with no filler. It front-loads the purpose, then gives trigger conditions, then data requirements. Every sentence contributes to correct invocation or safe execution.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 13 parameters and no output schema, the description covers the essentials: when to invoke, consent requirements, what evidence to include, and what to exclude. It does not mention how to classify severity or suspected_layer, but those are covered by enum descriptions in the schema and are not critical to deciding whether to call the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 85%, so the baseline is 3. The description adds value by reinforcing how error_code and error_details should be used ('exact error code and details from the failing result') and by imposing privacy constraints across free-text parameters. It does not elaborate on the two undocumented parameters (actual/expected), but the schema handles most parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and object: 'Report a bug to the Nilyo team as a tracked issue.' It also gives clear triggering conditions ('after a tool failed unexpectedly', TOOL_FAILED, wrong or empty result, broken flow), which helps distinguish it from feature-request or general feedback tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description is explicit about when to use it: after unexpected tool failure, when the user agrees, and when the user says 'ça ne marche pas' or 'report this'. It does not explicitly contrast with the sibling feedback_request_feature, but the bug-specific framing makes the intended context clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

feedback_request_featureFeedback: Request featureAInspect

Send a feature request or improvement idea to the Nilyo team as a tracked issue: a missing action, provider or capability, a workflow that needs too many steps, a confusing result. Use when the user asks for something Nilyo cannot do yet, or explicitly wants to suggest an improvement, and agrees to send it. Describe the user's goal and why current tools fall short. Ask the user for consent first (user_consent=true).

ParametersJSON Schema
NameRequiredDescriptionDefault
toolNoNilyo tool name involved, if any.
titleYesShort, specific title in English (what fails or what is wanted), e.g. 'email_list_messages fails on OVH IMAP mailbox with 501'.
providerNoProvider involved when relevant: linkedin, whatsapp, instagram, telegram, gmail, outlook, imap, calendar.
use_caseNoConcrete scenario the user wanted to achieve and how often it happens.
workaroundNoWhat the user does today instead, if anything.
descriptionYesWhat the user was trying to do, in their words plus your observations. No passwords, tokens, message contents or third-party personal data.
user_consentYesMust be true: the user explicitly agreed to send this report to the Nilyo team.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that this sends a tracked issue to the Nilyo team and requires explicit user consent, which is useful behavioral context beyond the annotations. However, it does not explain what happens after submission, whether anything is reversible, or the lack of immediate resolution, so the behavioral picture is partial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three focused sentences front-load the core purpose, then the trigger conditions and consent requirement, with no filler or repetition. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity, the description covers purpose, trigger conditions, content expectations, and consent. The main gap is the lack of explicit guidance distinguishing this from the bug-reporting sibling and any description of the outcome after submission.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the structured schema already documents all seven parameters in detail. The description adds general guidance about capturing the user's goal and why current tools fall short, but it does not add parameter-level meaning beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool sends a feature request or improvement idea to the Nilyo team as a tracked issue, with concrete examples of what qualifies. It is specific about the resource and action, but it does not explicitly contrast this with the sibling feedback_report_bug tool, so differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use conditions: when the user asks for something Nilyo cannot do yet or explicitly wants to suggest an improvement, plus the consent requirement. It does not state when-not-to-use it or mention the alternative bug-reporting sibling, so it falls just short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

imap_connectIMAP: ConnectAInspect

Connect a generic IMAP/SMTP mailbox directly from the conversation with the mailbox credentials (alternative to the account_connect browser link, which is preferred when the user does not want to type a password in the chat). Nilyo forwards the credentials once to the connection service and never stores them. Start with user + password only (servers are auto-detected); if the result says the IMAP or SMTP configuration is invalid, ask the user for the servers (e.g. OVH: imap ssl0.ovh.net:993 ssl, smtp ssl0.ovh.net:465 ssl; Gmail/Microsoft mailboxes should use the Google/Outlook connection instead). Use account_id to re-authenticate an existing disconnected IMAP account.

ParametersJSON Schema
NameRequiredDescriptionDefault
userYesMailbox login, usually the full email address.
passwordYesMailbox password or app password, exactly as given by the user.
imap_hostNo
imap_portNo
smtp_hostNo
smtp_portNo
account_idNoNilyo connection ID (unipile_account_id from list_connected_accounts) of an EXISTING account to re-authenticate. Omit to connect a new account.
initial_syncNoEnable the initial mailbox synchronization so account-wide listing/search (email_list_messages, email_resolve_message) works; without it, use email_list_folders + email_list_folder_messages. Default false (faster connection).
imap_encryptionNo
smtp_encryptionNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are all false (not read-only, not idempotent, not destructive), so the description must carry behavioral disclosure. It states that credentials are forwarded once and never stored, which is a security transparency. It also discloses the auto-detection behavior, the failure handling (ask for servers), and the re-authentication use case. This goes beyond the annotations and gives the agent a clear picture of side effects and expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence adds value: purpose, alternative, security note, step-by-step guidance, and special cases. It is well-structured with clear flow, and the key information (user+password first) is front-loaded. No fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (10 parameters, no output schema, no annotations), the description covers many aspects: purpose, alternative, security, usage flow, and re-auth. However, it does not describe the success return value or what the agent should expect after a successful connection (e.g., connection ID or status). It implies a result by mentioning 'if the result says invalid', but doesn't explain the successful outcome. This is a minor gap for a tool with no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 40%, so the description must compensate. It does clarify that user+password are the primary required fields and that servers are auto-detected, implying host/port are optional. It provides example server settings for OVH and mentions account_id for re-auth. However, it does not explain imap_encryption, smtp_encryption, or other parameters, leaving their semantics unclear. It partially compensates but not fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: connecting a generic IMAP/SMTP mailbox with credentials. It distinguishes itself from the account_connect browser link as an alternative, and specifies it is for generic mailboxes, not Gmail/Outlook. The verb 'connect' and resource 'mailbox' are explicit, and it is differentiated from sibling connect tools like telegram_connect and whatsapp_connect.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: it is the alternative to account_connect when the user prefers typing credentials in chat. It also gives an exclusion: Gmail/Microsoft mailboxes should use Google/Outlook connection instead. It further instructs to start with user+password only and to ask for servers if configuration is invalid, plus how to re-authenticate via account_id. This is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_get_my_profileInstagram: Get my profileA
Read-onlyIdempotent
Inspect

Get the profile of the owner of the connected Instagram account.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the scope clarification ('owner of the connected Instagram account') but does not disclose any additional behavioral traits such as rate limits, failure modes, or return format. Given the annotations, the description adds limited extra value, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, well-constructed sentence that front-loads the action and resource. No fluff or redundant phrasing, and it immediately tells the agent what the tool does. It is appropriately sized for a simple read operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with one optional parameter, a well-documented schema, and annotations covering safety, the description is sufficient. It clearly identifies the target (owner's profile) and the scope. It does not describe the return payload, but the tool name and purpose imply a profile object, and the absence of an output schema reduces the burden. The description is complete enough for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the account_id parameter is fully documented in the schema with detailed guidance on optionality and disambiguation. The tool description itself does not mention any parameters, but since the schema already carries the full weight, the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and a specific resource ('profile of the owner of the connected Instagram account'), which clearly distinguishes it from siblings like instagram_get_profile (for other profiles) and instagram_update_my_profile (for updates). It is precise and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool by scoping to the owner's own profile, but it does not explicitly mention alternatives or exclusion conditions. It leaves it to the agent to infer that instagram_get_profile is for other profiles. Clear context but no explicit when-not or alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_get_profileInstagram: Get profileA
Read-onlyIdempotent
Inspect

Get an Instagram user profile by provider user ID/username where supported. Use before follow/unfollow or identity-sensitive actions.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idYesExact provider user ID returned by the relevant profile/contact resolver; never a display name or profile URL. For LinkedIn, use the stable system ID. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds the 'where supported' caveat and the intended pre-action usage, which adds minimal but relevant context. It does not disclose error behavior or rate limits, but given the annotation coverage, a mid-range score is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exactly two sentences with zero fluff. The purpose is front-loaded, and the usage note follows directly. It is appropriately sized for a simple read operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read tool with no output schema, the description and schema together provide sufficient information: how to call it, what input to provide, and when to use it. Missing details like return format or error handling are not critical for a read-only, idempotent operation, so it is complete enough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: both parameters have detailed descriptions, including the user_id guidance (exact provider ID, never display name/URL) and account_id disambiguation logic. The tool description itself does not add parameter-specific details, but since the schema already carries the full burden, the baseline of 3 is warranted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get an Instagram user profile') and the target resource (Instagram user), and specifies the input type ('provider user ID/username'). It also adds a usage context ('Use before follow/unfollow or identity-sensitive actions') that distinguishes it from the sibling instagram_get_my_profile and list tools. The verb-resource pair is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: before follow/unfollow or identity-sensitive actions. It implies the need for a provider user ID rather than a display name, which is reinforced by the schema description. However, it does not explicitly name alternatives (e.g., instagram_get_my_profile for own profile), though the sibling tool names make that differentiation obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_list_conversationsInstagram: List conversationsA
Read-onlyIdempotent
Inspect

List Instagram DM conversations from the user's own account. Use to locate a chat before reading/replying.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds that it operates on the user's own account and targets DM conversations, but it does not disclose output shape or pagination behavior. This is acceptable given the annotation coverage, but the description adds only modest behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. The core action and scope are front-loaded, and the usage hint is immediate and actionable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with no required parameters and no output schema, the description plus schema is nearly sufficient. It communicates what the tool does, the account scope, and when to use it. The only minor gap is the lack of any statement about what fields or conversation metadata the response contains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%: account_id is richly documented in the schema, but limit has no description beyond min/max constraints. The tool description does not compensate for the undocumented limit parameter, so an agent must infer that it caps the number of returned conversations. The detailed account_id guidance prevents a lower score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('Instagram DM conversations'), and scopes it to 'the user's own account'. It also states the intended role ('locate a chat before reading/replying'), which distinguishes it from siblings like instagram_read_conversation and instagram_send_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear usage context: use this tool to locate a chat before reading or replying. It does not explicitly name alternatives or state when not to use it, but the forward-looking workflow hint provides enough direction for an agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_list_followersInstagram: List followersC
Read-onlyIdempotent
Inspect

List followers of the connected Instagram account or a known Instagram user where supported.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo
offsetNo
user_idYesUse 'me' for the connected account owner, otherwise the exact provider user ID returned by a profile/contact resolver; never a display name or profile URL.me
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

C2.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, establishing a safe read operation. The description adds a small behavioral caveat with 'where supported', implying that some user queries may not be supported, but it does not disclose pagination behavior, rate limits, or what happens with large follower lists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no redundant words and is front-loaded with the verb and resource. It is appropriately concise, though it is brief enough to omit useful context about pagination or parameter usage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with five parameters and no output schema, the description is too sparse. It does not explain pagination via cursor/offset/limit, what data is returned, or how to handle the 'where supported' limitation. The read-only annotations cover safety, but not the mechanics of using the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 40% (user_id and account_id have descriptions), while limit, cursor, and offset lack descriptions. The tool description adds no parameter meaning and does not compensate for the low coverage, leaving the agent without guidance on how pagination parameters work or how they relate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List followers' of the connected account or a known Instagram user. It implicitly distinguishes from the sibling instagram_list_following by the resource type (followers vs. following), though it does not explicitly name that alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives like instagram_list_following or linkedin_list_followers. It also does not clarify when to use the connected account vs. a known user beyond the phrase 'where supported', which is vague. No exclusions or prerequisites are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_list_followingInstagram: List followingB
Read-onlyIdempotent
Inspect

List Instagram accounts followed by the connected account/user where supported.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo
offsetNo
user_idYesUse 'me' for the connected account owner, otherwise the exact provider user ID returned by a profile/contact resolver; never a display name or profile URL.me
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the 'where supported' caveat, which is useful behavioral context, but it does not disclose pagination behavior, rate limits, or what happens when following data is unavailable. Overall, the description adds some value beyond annotations but not substantial detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence delivers the core purpose with no filler. The key scoping detail, 'connected account/user where supported,' is front-loaded and directly actionable. This is an example of appropriate minimalism rather than under-specification.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list with annotations covering safety, the description is mostly adequate. However, with multiple pagination parameters (limit, cursor, offset) and no output schema, the agent lacks guidance on how results are returned or how to paginate. The 'where supported' caveat helps, but the absence of pagination and result-format context leaves a meaningful gap for a tool that can potentially return large lists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 40%, and the tool description does not compensate for the undocumented parameters. It mentions the connected account/user, which relates to user_id, but it gives no explanation of limit, cursor, or offset, leaving the agent to infer pagination mechanics. The description adds little meaning beyond what the schema already provides for the two documented parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'List Instagram accounts followed by the connected account/user.' It clearly distinguishes from the sibling instagram_list_followers by stating it lists 'following' rather than followers. The phrase 'where supported' adds an appropriate scoping caveat without obscuring the primary action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to choose this tool over alternatives such as instagram_list_followers or instagram_list_conversations. 'Where supported' hints at a platform limitation but does not explain when this tool should or should not be used, nor does it mention any prerequisites or fallback options.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_read_conversationInstagram: Read conversationB
Read-onlyIdempotent
Inspect

Read an Instagram DM conversation and recent messages for context, lead qualification or follow-up workflows.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID returned by conversation/inbox listing. Never pass a person name or provider user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds no additional behavioral traits (e.g., pagination, rate limits, or return format). It simply restates the action and purpose, which is minimal beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the primary action ('Read an Instagram DM conversation') and then adds purpose context. There is no fluff or repetition, making it efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should clarify what the tool returns. It mentions 'recent messages' but does not describe the structure, limits, or any caveats. Given the read-only nature and annotation coverage, it is minimally adequate but lacks detail about the response format or edge cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both chat_id and account_id thoroughly explained in the schema. The tool description adds no parameter-specific information beyond what the schema already provides, so it meets the baseline but does not enhance it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (Read) and the resource (Instagram DM conversation and recent messages). It also hints at use cases (context, lead qualification, follow-up) which aids purpose understanding. However, it does not explicitly differentiate from sibling tools like linkedin_read_conversation or whatsapp_read_conversation, though the provider is already in the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives context for when to use it (lead qualification, follow-up) but does not mention alternatives or exclusions. There is no guidance on when to choose this over messaging_list_messages or other read tools, leaving the agent to infer based on provider naming.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_send_messageInstagram: Send messageA
Destructive
Inspect

Send an Instagram DM in an existing conversation from the user's own account. Locate chat_id first if necessary and only send after clear user approval.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
chat_idYesExact chat/conversation ID returned by conversation/inbox listing. Never pass a person name or provider user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as a destructive, non-idempotent write. The description adds a meaningful guardrail: 'only send after clear user approval,' and clarifies that the send happens from the user's own account. It does not detail other side effects, but annotations plus the approval note cover the main behavioral risk.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the core action and the required preliminary step. No filler or repetition; every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a send operation with existing annotations and a detailed schema, the description covers the key prerequisites: existing conversation, chat_id lookup, user approval, and account ownership. It could add failure or duplicate-send guidance, but the information needed to invoke correctly is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents chat_id and account_id thoroughly; the description only reiterates locating chat_id first. The text parameter lacks a schema description, but its name is self-explanatory. At 67% schema coverage, the description adds no real parameter meaning beyond what the schema provides, so a mid score is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action verb and resource: 'Send an Instagram DM in an existing conversation from the user's own account.' This distinguishes it from sibling send tools for WhatsApp/LinkedIn and from Instagram read/list tools. 'Existing conversation' and 'own account' add scoping that prevents misuse.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: requires an existing conversation, locate chat_id first if needed, and only send after explicit user approval. It stops short of naming alternative tools or stating when not to use it, but the Instagram-specific scope and approval requirement provide enough operational guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instagram_update_my_profileInstagram: Update my profileAInspect

Update supported fields on the user's own Instagram profile. Only pass fields explicitly requested; availability is provider-dependent.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=false and destructiveHint=false, so the mutation aspect is covered. The description adds useful context about provider-dependent availability and the need to pass only requested fields, but does not disclose consequences of passing unsupported fields, response shape, or permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler; the core action and the key usage constraint are front-loaded. Every sentence contributes actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an open-world update tool with no output schema, the description covers the essential caveat about provider-dependent fields but omits guidance on the expected return value and does not point the agent to instagram_get_my_profile for retrieving current fields before updating. The account_id parameter is well documented, but the tool's behavior on unsupported fields remains unclear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The sole schema parameter account_id is fully described with clear disambiguation guidance. The description adds meaning beyond the schema by instructing the agent to pass only explicitly requested profile fields and warning that availability varies by provider, which is important given the open additionalProperties.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: updating supported fields on the user's own Instagram profile. It clearly distinguishes itself from read-only siblings like instagram_get_my_profile and instagram_get_profile by emphasizing 'Update' and 'user's own'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides contextual usage guidance: only pass explicitly requested fields and expect provider-dependent availability. However, it does not explicitly explain when to choose this tool over alternatives such as instagram_get_my_profile or social_update_post, or mention prerequisites like fetching the current profile first.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_accept_invitationLinkedIn: Accept invitationA
Destructive
Inspect

Accept a received LinkedIn connection request. Requires request_id from linkedin_list_invitations(type='received').

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
request_idYesExact pending invitation request ID returned by linkedin_list_invitations. Never pass the other person's user ID. Relation request ID: ID of a pending sent/received invitation request. Obtain with: linkedin_list_invitations(type=received|sent) -> request.id Never pass: LinkedIn user ID, profile URL.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=false and destructiveHint=true, so the mutation/destructive nature is covered. The description adds the useful constraint that only pending received requests should be accepted, but does not disclose further behavioral details such as irreversibility or effects on the connection state. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short sentence states the action first and the prerequisite second, with no filler. Every word earns its place, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with rich schema descriptions and annotations covering destructive behavior, the description provides enough context to call the tool correctly. No output schema exists, but the operation is straightforward and return format is not critical for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both parameters already have detailed schema descriptions, especially request_id with explicit instructions on what to pass and what never to pass. The description repeats the source instruction for request_id without adding significant new meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Accept') and a specific resource ('received LinkedIn connection request'). It also names the exact source of the required ID, linkedin_list_invitations(type='received'), which clearly distinguishes this from sibling tools like linkedin_cancel_or_refuse_invitation or linkedin_send_invitation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly instructs the agent to obtain the request_id from linkedin_list_invitations(type='received'), giving a clear precondition and data source. It does not explicitly name alternatives or say when not to use this tool, but the context makes the intended use unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_cancel_or_refuse_invitationLinkedIn: Cancel or refuse invitationA
Destructive
Inspect

Withdraw a sent LinkedIn invitation or refuse a received invitation. First list the relevant invitations to obtain request_id unless it is already known.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
request_idYesExact pending invitation request ID returned by linkedin_list_invitations. Never pass the other person's user ID. Relation request ID: ID of a pending sent/received invitation request. Obtain with: linkedin_list_invitations(type=received|sent) -> request.id Never pass: LinkedIn user ID, profile URL.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, which covers the mutation and irreversibility. The description adds the specific action types (withdraw/refuse) and the prerequisite for the request_id. However, it doesn't mention potential side effects (e.g., notification to the other party) or that the action is irreversible beyond what annotations imply. With annotations carrying the safety profile, the description adds some but not rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no redundancy. The purpose is stated first, followed by the key prerequisite. Every word earns its place, and the structure is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description need not explain return values. It covers the two operations and the required parameter acquisition. It omits any guidance on account_id handling, but that is already detailed in the schema. For a two-parameter mutation tool with clear annotations, the description is sufficiently complete for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds a valuable instruction for obtaining request_id via linkedin_list_invitations, which is not fully explicit in the schema's parameter description (though schema does mention 'Obtain with: linkedin_list_invitations'). This actionable guidance improves the semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verbs ('Withdraw', 'refuse') with a clear resource ('sent LinkedIn invitation', 'received invitation'). It distinguishes between the two operations and implicitly differentiates from siblings like linkedin_accept_invitation and linkedin_send_invitation. The phrase 'First list the relevant invitations' also clarifies the workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use this tool: to withdraw a sent or refuse a received invitation. It gives a practical prerequisite (obtain request_id via linkedin_list_invitations) but does not explicitly name alternatives or exclusions (e.g., 'use linkedin_accept_invitation for accepting'). The context is clear enough for an agent to decide, so not a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_classic_get_applicant_resumeLinkedIn: Classic get applicant resumeA
Read-onlyIdempotent
Inspect

Download/retrieve the resume of one applicant to a LinkedIn Classic job. Never infer applicant_id from name; list applicants first and reuse exact applicant.id.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesExact LinkedIn job posting ID. Classic: obtain from owned Classic job postings. Recruiter: obtain from the selected Recruiter project's jobs. Never use title/URL as job_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
applicant_idYesExact applicant profile ID returned by the corresponding applicants listing. Keep it paired with the Classic job_id or Recruiter project_id that produced it.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly, idempotent, and non-destructive behavior, so the safety profile is covered. The description adds a non-obvious data-provenance constraint about applicant_id, but does not disclose output format or connection prerequisites beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the core action comes first, and the critical caveat immediately follows. It avoids restating the schema and earns every word.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With read-only annotations, fully documented parameters, and the crucial applicant_id provenance rule, the tool is callable without further inference. A minor gap is not naming the Recruiter resume sibling for non-Classic jobs, but the description is otherwise complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline of 3 applies. The description adds value by warning against inferring applicant_id from name and reinforcing the required workflow: list applicants first, then reuse the exact applicant.id.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the action with a specific verb and resource: 'Download/retrieve the resume of one applicant to a LinkedIn Classic job.' The 'Classic' qualifier and 'resume' clearly separate it from siblings like linkedin_classic_get_job_applicant and linkedin_recruiter_get_applicant_resume.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit call-order guidance: 'Never infer applicant_id from name; list applicants first and reuse exact applicant.id.' It also scopes the tool to LinkedIn Classic jobs, implying Recruiter siblings cover other contexts, though it does not explicitly name them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_classic_get_job_applicantLinkedIn: Classic get job applicantA
Read-onlyIdempotent
Inspect

Get one applicant to a LinkedIn Classic job. Required chain: owned Classic job -> job_id -> list applicants -> applicant.id -> this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesExact LinkedIn job posting ID. Classic: obtain from owned Classic job postings. Recruiter: obtain from the selected Recruiter project's jobs. Never use title/URL as job_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
applicant_idYesExact applicant profile ID returned by the corresponding applicants listing. Keep it paired with the Classic job_id or Recruiter project_id that produced it.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the required chain, which is workflow context rather than behavior. It does not describe error scenarios, rate limits, or what happens if the applicant is not found, but given the strong annotation coverage, a score of 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the purpose and immediately follows with the essential chain. There is zero waste, and the most critical information (the required sequence) is placed at the beginning. This is an exemplary concise structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only get tool with only two required parameters and full schema coverage, the description is nearly complete. It provides the critical chain that ensures correct usage, and annotations cover the operational context. The only minor gap is the absence of any note about return behavior or error conditions, but these are not essential for a basic get operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter (job_id, account_id, applicant_id) already documented in detail. The description itself adds no additional parameter semantics beyond the schema, so it meets the baseline of 3 for tools with full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb ('Get') and a specific resource ('one applicant to a LinkedIn Classic job'), and it explicitly differentiates the Classic context from the Recruiter variant through the phrase 'LinkedIn Classic job'. The required chain also clarifies the exact role this tool plays within the broader workflow, distinguishing it from sibling tools like linkedin_classic_list_job_applicants.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a precise usage chain: 'owned Classic job -> job_id -> list applicants -> applicant.id -> this tool', which tells the agent exactly the prerequisite steps needed before invoking this tool. It does not explicitly name alternatives or state when not to use it, but the chain implies the correct context (Classic vs. Recruiter) and the need for a prior listing step.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_classic_list_job_applicantsLinkedIn: Classic list job applicantsA
Read-onlyIdempotent
Inspect

List applicants for a LinkedIn Classic job owned by the connected account. Resolve the exact Classic job_id first. Filters are passed as V2 applicant filters (for example ratings/experience) and must use provider enums/IDs rather than guessed display values.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesExact LinkedIn job posting ID. Classic: obtain from owned Classic job postings. Recruiter: obtain from the selected Recruiter project's jobs. Never use title/URL as job_id.
filtersNoOptional V2 Classic applicant filters. Use documented enum/filter IDs; omit unknown filters rather than guessing.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds useful behavioral context: the job_id must be resolved first, and filters are strictly constrained to documented enums/IDs. It does not cover pagination or return format, but given the annotations and the schema's richness, this is acceptable. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and scope, then a necessary prerequisite and a caution about filters. No wasted words, every sentence earns its place. Ideal structure for quick agent parsing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (list operation with optional filters, no output schema), the description covers the essential points: what it does, the critical job_id prerequisite, and filter constraints. It doesn't mention pagination or return format, but that is common for list tools and the annotations/schema cover the safety and parameter details. It could explicitly contrast with the Recruiter sibling, but the naming and description already convey the Classic scope. Overall, it is sufficiently complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each parameter already has detailed semantics. The description adds a high-level instruction ('Resolve the exact Classic job_id first') which is more of a usage guideline than parameter semantics. The filter guidance about enums is somewhat redundant with the schema's 'Use documented enum/filter IDs; omit unknown filters rather than guessing.' The description does not materially enhance parameter understanding beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List applicants for a LinkedIn Classic job owned by the connected account.' It names the specific verb (list), resource (applicants for a Classic job), and ownership scope (connected account). It also distinguishes from siblings like linkedin_recruiter_list_applicants by explicitly mentioning 'Classic' and 'owned by the connected account', so an agent can tell it apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a crucial prerequisite: 'Resolve the exact Classic job_id first.' It also instructs that filters must use provider enums/IDs rather than guessed display values. It does not explicitly name alternatives like the Recruiter list tool, but the 'Classic' qualifier and naming make the intended context clear. Slight improvement would be to explicitly say 'Use this for Classic jobs; use linkedin_recruiter_list_applicants for Recruiter projects.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_comment_on_postLinkedIn: Comment on postA
Destructive
Inspect

Publish a comment/reply on a LinkedIn post on behalf of the user. Requires post_id. Use after reading the post/comments and only when the user has asked to publish the final reply.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
post_idYesExact provider post ID returned by post search/list/get. Never pass post text, author ID or URL. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true and readOnlyHint=false, covering the side-effect nature. The description adds 'on behalf of the user' and 'only when the user has asked,' which are useful behavioral cues. However, it does not mention potential irreversibility, permission requirements, or rate limits. Given the annotations cover the core safety profile, the description adds moderate value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The purpose is stated first, followed by a clear usage condition. Every word earns its place, and the key constraint (use after reading, only on user request) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a straightforward write operation with no output schema, the description covers the essential aspects: what it does, when to use it, and the requirement for post_id. It omits error conditions or prerequisites, but these are not critical for a simple comment action. The schema handles parameter details adequately for most cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description does not elaborate on any parameters. Schema coverage is 67% (post_id and account_id have descriptions, text does not). The description does not compensate for the undocumented 'text' parameter or add any additional semantic clarity. It merely restates that post_id is required, which is already in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action 'Publish a comment/reply on a LinkedIn post' with a clear resource. It distinguishes from siblings like linkedin_create_post (which creates a new post) and linkedin_reply_to_comment (which replies to a comment), though it doesn't explicitly name them. The title 'Comment on post' reinforces the intent, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: 'Use after reading the post/comments and only when the user has asked to publish the final reply.' This tells the agent when to invoke it and implies it should not be used prematurely or without user consent. It does not explicitly mention alternatives, but the 'after reading' context effectively sets the appropriate trigger.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_create_postLinkedIn: Create postA
Destructive
Inspect

Publish a LinkedIn post from the user's own account, optionally on a managed company page using post_as. This is a public side effect; use only after the user has clearly approved the final content and target identity.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
post_asNoExact managed page/company identity returned by linkedin_list_managed_pages; omit to post as the connected person. Never pass a company name or URL.
can_readNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
can_commentNo
quoted_post_idNoExact provider post ID to quote, returned by post search/list/get. Never pass post text or a URL. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, destructiveHint=true, openWorldHint=true), the description explicitly labels the operation a 'public side effect' and requires user approval, which adds consent and visibility context. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two front-loaded sentences state function, scope, side effect, and approval requirement without redundancy. Every sentence adds information needed for safe invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Combined with the schema's detailed parameter descriptions and the annotations, the description covers target identity, approval, and public side effects. It does not describe return values or defaults for can_read/can_comment, but those are minor for invoking this tool successfully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The main description only elaborates post_as ('managed company page' and 'target identity'), while the schema already carries strong descriptions for post_as, account_id, and quoted_post_id. With 50% schema coverage, the tool definition gives enough parameter meaning overall, but the free-text description itself does little to compensate for the undocumented parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Publish') with a concrete resource ('a LinkedIn post') and clarifies the account scope: the user's own account or a managed company page via post_as. This clearly separates it from nearby social/list/comment tools even without naming a sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description sets an explicit precondition: use only after the user has clearly approved the final content and target identity. It does not name an alternative tool, but the approval trigger and public side-effect warning are enough to guide appropriate invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_endorse_skillLinkedIn: Endorse skillAInspect

Endorse one skill on a LinkedIn relation. Resolve member_id first, fetch that profile with linkedin_skills, and reuse the exact returned endorsement skill_id; never pass a skill name.

ParametersJSON Schema
NameRequiredDescriptionDefault
skill_idYesExact endorsement skill ID from the member profile's linkedin_skills section; not the display name.
member_idYesExact LinkedIn member profile ID returned by the profile resolver; not a URL/name.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a write operation (readOnlyHint=false) and non-idempotent. The description adds behavioral context beyond annotations by requiring the skill_id to be the exact endorsement ID from linkedin_skills and forbidding skill-name input, which is critical for correct invocation. It does not disclose side effects or failure modes, but the workflow constraint is a meaningful addition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero filler. The core action is stated first, followed by the two critical procedural constraints. Every clause adds necessary information; there is no redundant or vague wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple write tool with no output schema, the description provides the essential preconditions, the source of each required ID, and the primary pitfall to avoid. It could explain what happens if the skill_id is invalid or if the member is not a relation, but the current guidance is sufficient for correct invocation in the common case.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% coverage with detailed parameter descriptions, so the baseline is 3. The description adds value by prescribing the order of operations: member_id must be resolved first)SkipLinkedIn_profile via linkedin_skills, and the returned endorsement skill_id must be reused exactly. It reinforces the most important semantic rule (never pass a skill name) and explains the provenance of both required parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Endorse one skill on a LinkedIn relation.' It also distinguishes the action from related profile operations by specifying the endorsement skill context, and states the required workflow (resolve member_id, fetch profile, reuse skill_id), leaving no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear procedural context: resolve member_id first, fetch the profile with linkedin_skills, and reuse the exact returned endorsement skill_id, plus a hard constraint to never pass a skill name. It does not explicitly name an alternative tool or state when not to use it, but the workflow is specific enough for an agent to know exactly when and how to invoke it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_follow_userLinkedIn: Follow userAInspect

Follow a LinkedIn user from the connected personal account. Resolve the exact provider user_id first.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idYesExact provider user ID returned by the relevant profile/contact resolver; never a display name or profile URL. For LinkedIn, use the stable system ID. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, so the agent knows it's a mutation. The description adds that it operates on the 'connected personal account,' which provides some scope context. It does not disclose side effects like notifications or rate limits, but given the annotations cover the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero filler. The primary action is stated first, followed by the critical prerequisite. It is efficiently structured and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description, combined with detailed parameter descriptions and annotations, covers the essentials: what the tool does, the required prerequisite, and how to supply parameters. It omits handling of edge cases like already-followed users, but that is minor given the simplicity and the schema's thoroughness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 100% schema coverage, the description for user_id adds substantial meaning: it explains what constitutes a valid ID (stable system ID), how to obtain it via three specific resolver tools, and what to avoid (URLs, names, company IDs). account_id also clarifies when to omit vs. pass it. This goes far beyond the schema's basic type and is highly actionable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb+resource: 'Follow a LinkedIn user from the connected personal account.' It is unambiguous and distinguishes from sibling tools like linkedin_unfollow_user and linkedin_send_invitation by specifying the action of following.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly instructs to 'Resolve the exact provider user_id first,' which is a crucial prerequisite. However, it does not explicitly contrast with alternatives (e.g., connecting vs. following) or mention when not to use the tool. The user_id parameter description adds rich detail on how to obtain the ID, but the main description lacks explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_companyLinkedIn: Get companyA
Read-onlyIdempotent
Inspect

Get a LinkedIn company profile by numeric/provider company ID. Use after linkedin_search_companies when full company data is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
company_idYesExact LinkedIn company ID returned by company search/resolution. Never pass a company name, URL or slug. LinkedIn company ID: Provider numeric/company ID. For mentions LinkedIn requires numeric company ID, not the company URL slug. Obtain with: linkedin_search_companies -> selected result.id; linkedin_get_company after resolving a company Never pass: linkedin.com/company/google URL, company slug such as google, company name.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, which covers the safety profile. The description adds workflow context but no additional behavioral details such as response shape, error behavior, or auth expectations. This is acceptable given strong annotations, but the description itself contributes only modest extra context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the first states the action and identifier type, the second provides the workflow trigger. Every word earns its place, and the core information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a simple 2-parameter read tool with heavy schema coverage and strong annotations, the description is largely complete: it tells the agent what to call, with which ID type, and after which preceding tool. No output schema exists, and the description could briefly mention return fields, but 'company profile' plus the workflow context is sufficient for confident invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema thoroughly documents both parameters, including account_id disambiguation and the strict company_id format rules. The description itself mostly echoes 'numeric/provider company ID' and does not add parameter meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb ('Get'), a clear resource ('LinkedIn company profile'), and the exact identifier type ('numeric/provider company ID'). It distinguishes itself from search/resolve siblings by framing the call as the follow-up that returns full company data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Description explicitly says to use it after linkedin_search_companies when full company data is needed, giving a clear workflow context and selection condition. It does not list explicit exclusions or alternative tools beyond the search step, so it stops short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_inmail_creditsLinkedIn: Get InMail creditsA
Read-onlyIdempotent
Inspect

Get LinkedIn InMail credit information for the connected account. Use when the user asks whether an InMail can be sent or how many credits remain.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds the context that it reports credit status for the connected account, but doesn't disclose additional behavior such as whether the query itself consumes credits or how fresh the data is. It is consistent with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, with the core action first and the usage trigger second. No filler or repetition of schema/annotation content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity read-only tool with one optional parameter, the description plus schema cover the essential calling context: what it does, when to call it, and how to supply account_id. It doesn't detail the response fields, but the use-case phrasing ('how many credits remain') gives enough for the agent to interpret the result. Minor gap: no explicit statement about whether credits are returned per account or overall.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the account_id parameter already has a detailed description explaining when to omit it, when to list accounts, and never to guess. The main description adds no parameter-level detail, but the schema carries the full burden, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Get' and names the exact resource 'LinkedIn InMail credit information' plus a scope ('for the connected account'). It also states the trigger use-case ('whether an InMail can be sent or how many credits remain'), which clearly distinguishes it from the many other linkedin_* siblings, none of which cover credits.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use when the user asks whether an InMail can be sent or how many credits remain,' giving a clear when-to-use. It doesn't name alternatives or exclusions, but among siblings there is no competing credits tool, so the absence of when-not is not a major gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_job_postingLinkedIn: Get job postingA
Read-onlyIdempotent
Inspect

Get one job posting owned by the user's LinkedIn account. job_posting_id MUST come from linkedin_list_job_postings, not a title/company or an unrelated discovery result. LinkedIn job ID: Exact LinkedIn job/job-posting ID returned by the corresponding search/list endpoint. Obtain with: linkedin_search_jobs -> result.id for discovery; linkedin_list_job_postings -> result.id for jobs owned by the account Never pass: job title, company ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
job_posting_idYesExact owned job posting ID returned by linkedin_list_job_postings -> result.id. LinkedIn job ID: Exact LinkedIn job/job-posting ID returned by the corresponding search/list endpoint. Obtain with: linkedin_search_jobs -> result.id for discovery; linkedin_list_job_postings -> result.id for jobs owned by the account Never pass: job title, company ID.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is known. The description adds valuable context about the ID provenance requirement and the scope of owned postings, which goes beyond the annotations and prevents misuse.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is somewhat repetitive, restating the ID source in multiple places (main description and parameter description). It's front-loaded with the key constraint, but the redundancy could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple get-one-posting tool with no output schema, the description is sufficient: it states what it does, how to obtain the required ID, and what not to pass. The lack of return-format detail is acceptable given the tool's low complexity and existing annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are fully described. The description reiterates the job_posting_id guidance but doesn't add substantial new meaning beyond the schema, though it does emphasize the source constraint. Meets the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Get one job posting owned by the user's LinkedIn account.' It clearly distinguishes from siblings like linkedin_list_job_postings (listing) and linkedin_search_jobs (searching) by explicitly scoping to owned postings and requiring a specific ID source.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance: the job_posting_id MUST come from linkedin_list_job_postings, not a title/company or unrelated discovery. It also gives the exact workflow for obtaining the ID from both search and list endpoints, and warns against passing job title or company ID.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_job_posting_budgetLinkedIn: Get job posting budgetA
Read-onlyIdempotent
Inspect

Get budget/pricing information for a LinkedIn Classic job posting owned by the connected account. Resolve job_id with linkedin_list_job_postings first.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesExact Classic job ID returned by linkedin_list_job_postings; not title or URL.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, non-destructive behavior linkedin. The description adds valuable behavioral context beyond that: it restricts to Classic job postings owned by the connected accountaine, and requires a prior resolution step. This helps the agent avoid applying it to non-Classic or unowned jobs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with the core purpose first and the prerequisite second. Every word earns its place; no filler, no redundant restating of the title or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with one required parameter and no output schema, the description fully equips an agent: it states what the tool returns (budget/pricing info), the prerequisite, and the ownership scope. The absence of return-format details is not a gap given the simple nature of the data retrieved.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema fully documents both job_id (exact ID, not title/URL) and account_id (optional, multi-account handling). The description repeats the resolution prerequisite already present in the schema, adding no new parameter-level meaning. Thus baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a precise resource ('budget/pricing information for a LinkedIn Classic job posting'), and a scope condition ('owned by the connected account'). This distinguishes it clearly from sibling tools like linkedin_get_job_posting, which fetches job details rather than budget data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear prerequisite ('Resolve job_id with linkedin_list_job_postings first') and the ownership constraint, which tells the agent when this tool applies. It does not explicitly name alternatives or say when not to use it, but the specificity of 'budget/pricing' and 'Classic' makes the intended use unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_my_profileLinkedIn: Get my profileA
Read-onlyIdempotent
Inspect

Get the profile of the owner of the connected LinkedIn account. Use for 'my LinkedIn profile', identity/context, or before actions that need the account owner's provider user ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly, idempotent, non-destructive, and open world. The description adds useful behavioral context: the connected-account ownership constraint and that the result can supply the provider user ID needed for subsequent actions. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver the scope, use cases, and connection to downstream needs with no filler. The core definition comes first and the optional parameter guidance is left to the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, zero-required-parameter tool, the description plus rich schema account_id guidance and annotations are nearly complete. It does not specify the response shape, but the mention of 'provider user ID' hints at a key return value; an explicit response note would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the single account_id parameter already has a thorough schema description about multi-account handling. The tool description itself adds no parameter meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Get the profile of the owner of the connected LinkedIn account.' It also maps to natural-language triggers ('my LinkedIn profile', identity/context) and distinguishes itself from sibling profile tools by the 'owner of the connected account' scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use: for 'my LinkedIn profile', identity/context, or before actions needing the owner's provider user ID. It does not explicitly name alternatives such as linkedin_get_profile or linkedin_get_profile_from_url, but the 'owner' wording and 'my' in the title make the boundary clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_postLinkedIn: Get postA
Read-onlyIdempotent
Inspect

Get a LinkedIn post by Nilyo/Unipile post_id. Use when you already know a post_id and need full post context.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesExact provider post ID returned by post search/list/get. Never pass post text, author ID or URL. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description does not contradict these and adds minimal behavioral context—just that it fetches a post. It does not add details about edge cases, errors, or rate limits, but with annotations carrying the load, the bar is lower. The description provides no additional behavioral value beyond the annotations, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff: the first states the action and identifier type, the second gives the usage context. It is front-loaded and every word earns its place. This is a model of conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with one required parameter, the description is sufficiently complete. It explains the purpose, when to use it, and the schema documents parameters thoroughly. There is no output schema, but the phrase 'full post context' hints at the return. The tool is simple enough that no further guidance is essential, though it could mention error behavior, which is not required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: both post_id and account_id have detailed descriptions, including guidance on obtaining post_id from search/list tools and when to provide account_id. The tool description itself adds no parameter-specific information beyond the schema. According to the rubric, with high schema coverage, the baseline is 3, and the description does not elevate it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb-resource pair: 'Get a LinkedIn post by Nilyo/Unipile post_id.' It clearly distinguishes this from sibling tools like linkedin_search_posts or linkedin_list_user_posts by specifying the retrieval method (by post_id) and the condition of already having the ID. This is not a tautology and provides a clear, singular purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit usage condition: 'Use when you already know a post_id and need full post context.' This implies when not to use it (e.g., when you need to search or list posts) and distinguishes it from alternatives. However, it does not explicitly name alternative tools or state exclusion criteria beyond the presence of an ID, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_profileLinkedIn: Get profileA
Read-onlyIdempotent
Inspect

Get a LinkedIn person's full profile from a LinkedIn provider user ID, public identifier, or linkedin.com/in/... URL using the user's own account. This is the preferred resolver before an action when the user supplied only a profile URL. The result contains the stable user id needed by linkedin_start_conversation and linkedin_send_invitation. Optional sections can retrieve experience, skills, interests and other profile details.

ParametersJSON Schema
NameRequiredDescriptionDefault
variantNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
with_sectionsNoClassic-only optional sections such as linkedin_experience, linkedin_skills or preview variants.
user_id_or_urlYesLinkedIn user ID (for example ACo...), public identifier, or full linkedin.com/in/... profile URL.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, non-destructive, idempotent behavior. The description adds meaningful context beyond those annotations: the operation runs 'using the user's own account,' it resolves multiple identifier forms, and its output supplies the stable user id needed by follow-up actions. This gives the agent a clearer behavioral model than the annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The core action and accepted identifier forms are front-loaded, followed by when to prefer it, what the result enables, and optional sections. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only resolver with no output schema, the description gives enough context to call it correctly: identifier forms, account context, preferred usage, downstream dependency, and optional sections. It could be more complete by explaining the variant parameter or naming the direct sibling alternative, but nothing essential for a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%, and the description adds some value by explaining the accepted identifier forms for user_id_or_url and the purpose of with_sections. However, the variant parameter has no schema description and is not addressed in the tool description, and much of the description repeats what the schema already documents. This is adequate but not exceptional.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Get a LinkedIn person's full profile' from a user ID, public identifier, or profile URL. It also carves out a distinct role as 'the preferred resolver before an action when the user supplied only a profile URL' and ties the result to the stable user id needed by other tools, which clearly differentiates it from sibling tools like linkedin_get_profile_from_url or linkedin_search_people.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: use it as a resolver before an action when the user supplied only a profile URL, and it calls out downstream tools that need the stable user id (linkedin_start_conversation, linkedin_send_invitation). It does not explicitly name alternatives or state when not to use it, so it stops just short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_profile_from_urlLinkedIn: Get profile from URLA
Read-onlyIdempotent
Inspect

Resolve a full LinkedIn person profile URL into the real LinkedIn profile and stable system user ID required by downstream actions. Example: https://www.linkedin.com/in/john-doe-123/?trk=foo -> extract ONLY 'john-doe-123' from the /in/{public_identifier}/ pathname, ignore query parameters/fragments/trailing slash, call Get User Profile, and return the profile including result.id. Use result.id for connection requests, new conversations and other actions requiring user_id. Never pass the full URL to those action tools. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID. LinkedIn public identifier: Slug after /in/ in a LinkedIn profile URL. Example https://www.linkedin.com/in/john-doe/?trk=x -> john-doe. Obtain with: extract only pathname segment immediately after /in/; ignore query string, fragment and trailing slash Never pass: full URL, ACo system ID when a public identifier is specifically required.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
profile_urlYesFull linkedin.com/in/... person profile URL. Query parameters are ignored.
with_sectionsNoOptional LinkedIn Classic profile sections such as linkedin_experience, linkedin_education or linkedin_skills.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond readOnly/openWorld/idempotent annotations, the description discloses parsing behavior (ignore query params/fragments/trailing slash, extract only the slug), the call to Get User Profile, and that the response includes result.id. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentence is an effective front-loaded purpose statement, but the description is long and repeats the path extraction rule and 'Never pass' guidance in separate sections. Most content is useful, but it could be trimmed without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description rightly explains that the result includes result.id and how that ID should be used downstream. It also covers the account/public identifier distinction and alternatives. It is complete for an agent deciding to call this tool and use its result correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema coverage is 100%, so the baseline is 3. The description adds value for profile_url by explaining exactly how it is normalized and why result.id matters, although it does not add semantics for account_id or with_sections beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific operation: resolve a full LinkedIn profile URL into the real profile and stable system user ID via extraction of the /in/{public_identifier}/ path segment. It is clearly distinguished from linkedin_get_profile by the URL-to-profile behavior and by explaining that result.id is needed downstream. The example makes the input/output relationship unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly gives three routes to obtain result.id (linkedin_get_profile_from_url, linkedin_get_profile, linkedin_search_people) and warns never to pass full URLs, person names, or company IDs downstream. It does not explicitly state 'use this when you have a full URL and not a user ID,' but that condition is strongly implied by the purpose and examples.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_search_parametersLinkedIn: Get search parametersA
Read-onlyIdempotent
Inspect

Resolve human LinkedIn filter values such as a location, company, industry, job function, relation, project, saved search or Sales Navigator list into the provider parameter IDs required by LinkedIn search endpoints. Typical sequence: call this with type + query, then pass the chosen returned id into linkedin_search_people / Sales Navigator / Recruiter search.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesLinkedIn parameter type, e.g. LOCATION, COMPANY, INDUSTRY, RELATION, JOB_FUNCTION, PROJECT, SAVED_SEARCH, LEAD_LIST.
queryNoHuman text to resolve, such as Paris, Stripe or Software. Required for Classic search parameters; optional for Sales Navigator/Recruiter lists.
productYesclassic
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: it resolves human values into provider parameter IDs, and it explicitly states that Nilyo never guesses when multiple accounts exist, instructing the agent to list and ask. This goes beyond the annotations and helps the agent understand the tool's non-deterministic account-selection behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states the core purpose, the second gives the typical usage sequence, and the account_id guidance is placed in the schema where it belongs. Every sentence earns its place, and there is no redundant restating of the tool name or title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only resolution tool with no output schema, the description covers the main workflow, the parameter relationships, and the multi-account edge case. It doesn't describe the exact shape of the returned IDs or how to handle multiple matches for a query, but the 'choose the returned id' phrasing implies a selection step. Given the tool's moderate complexity and the strong schema coverage, this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75%, so the schema already documents type, query, and account_id. The description adds meaning by explaining the relationship between type and query ('call this with type + query') and by clarifying that query is optional for Sales Navigator/Recruiter lists. It also adds the crucial account_id disambiguation rule, which is not fully captured by the schema's 'Optional Nilyo connection ID' phrasing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Resolve') and resource ('human LinkedIn filter values... into provider parameter IDs'), and clearly distinguishes this from search tools by naming the downstream consumers (linkedin_search_people / Sales Navigator / Recruiter search). It also enumerates the filter value types, making the tool's scope unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Typical sequence: call this with type + query, then pass the chosen returned id into linkedin_search_people / Sales Navigator / Recruiter search.' This tells the agent exactly when to use this tool and how it fits into a workflow. The account_id parameter description also provides clear guidance on when to omit vs. provide it, including a fallback instruction to list and ask.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_comment_repliesLinkedIn: List comment repliesA
Read-onlyIdempotent
Inspect

List replies under one exact LinkedIn comment. Chain: resolve post -> post.id -> list comments -> comment.id -> replies. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
post_idYesExact post ID from post search/list. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
comment_idYesExact comment ID from comments of the resolved post. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal a safe read-only, idempotent call. The description adds meaningful behavioral context: the call is strictly scoped to one exact comment, the IDs must be obtained via a resolution chain, and non-ID inputs are rejected. It does not cover pagination or response behavior, but the safety profile is already declared by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with a clear one-line purpose and uses useful 'Post ID:' and 'Comment ID:' sections. However, those sections duplicate the schema descriptions nearly verbatim, and the inclusion of instagram_list_user_posts and instagram_list_post_comments as sources for a LinkedIn tool is confusing and likely erroneous.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter tool with no output schema, the description plus schema covers the essential invocation path: exact IDs, where to get them, what not to pass, and account disambiguation in the schema's account_id description. It lacks a description of return values and does not explain the optional offset parameter, which is a minor gap since the tool name and first sentence imply a list result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75%, and the tool description mostly repeats the schema's own guidance for post_id and comment_id rather than adding new parameter-level information. The offset parameter is undocumented in both the schema and the description, and account_id guidance lives only in the schema. The chain clarifies the relationship between parameters but adds little beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence, 'List replies under one exact LinkedIn comment,' states a specific action and resource. It also distinguishes itself from sibling list tools like linkedin_list_post_comments by scoping the call to a single comment ID and showing the required chain: resolve post -> post.id -> list comments -> comment.id -> replies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit chain for obtaining required IDs and names the exact preceding tools (linkedin_search_posts, linkedin_list_post_comments). It also states hard exclusions: 'Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.' It does not, however, explicitly contrast this tool with alternatives like social_list_comment_reactions for deciding which operation to call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_contractsLinkedIn: List contractsA
Read-onlyIdempotent
Inspect

List LinkedIn premium contracts available on the user's account. Returned contract.id is the ONLY value to pass as contract_id to linkedin_select_contract. contract_id is distinct from inbox_id. LinkedIn premium contract ID: Exact Sales Navigator/Recruiter contract id. Obtain with: linkedin_list_contracts -> contract.id Never pass: inbox_id, product name. Inbox ID: Provider inbox/product inbox identifier. LinkedIn Classic may use CLASSIC; premium products expose their own inbox IDs. Obtain with: linkedin_list_inboxes -> inbox.id Never pass: contract_id unless returned as the inbox id, guessing SALES_NAVIGATOR or RECRUITER.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, idempotent, non-destructive nature of the call, so the description does not need to repeat that. It adds valuable behavioral context by explaining the contract_id vs inbox_id distinction and warning against common misuse. It does not describe the full return shape, but the most important output field, contract.id, is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, and the ID disambiguation notes are genuinely useful. However, the description is longer and more intricate than a simple list operation strictly requires, reading more like a mini field guide than a tool description. Most sentences add value, but the structure could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description correctly identifies the key return value, contract.id, and explains its downstream use. Combined with full account_id schema coverage and safety annotations, an agent can call the tool correctly. A minor gap is that other fields of the returned contract objects are not mentioned, but they are not essential for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, account_id, is already documented with 100% schema coverage, so the description does not need to add parameter-level detail. The description instead adds contextual relationships between contract_id and inbox_id, which is useful but not specifically about the account_id parameter. This matches the baseline expectation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence clearly states the verb and resource: 'List LinkedIn premium contracts available on the user's account.' It also distinguishes contract.id from inbox_id, which differentiates this tool from linkedin_select_contract and linkedin_list_inboxes. The purpose is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says the returned contract.id is the ONLY value to pass as contract_id to linkedin_select_contract, and directs the agent to linkedin_list_inboxes for inbox IDs. It also gives concrete prohibitions: never pass inbox_id, product name, or guessed literals like SALES_NAVIGATOR or RECRUITER. This is strong when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_conversationsLinkedIn: List conversationsA
Read-onlyIdempotent
Inspect

List LinkedIn private conversations. By default only the Classic primary inbox (CLASSIC_PRIMARY); pass inbox_ids from linkedin_list_inboxes to read other inboxes (archived, spam, Sales Navigator, Recruiter, company pages). Inboxes are read one after another to respect LinkedIn rate limits; unreadable ones are reported with unavailable instead of failing. Preserve inbox_id and chat.id. Use before linkedin_read_conversation when chat_id is unknown.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
inbox_idsNoExact inbox IDs from linkedin_list_inboxes (e.g. CLASSIC_PRIMARY, SALES_NAVIGATOR_PRIMARY). Default: CLASSIC_PRIMARY only.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the operation read-only and safe; the description adds meaningful behavioral detail beyond that: inboxes are read sequentially to respect rate limits, unreadable inboxes yield 'unavailable' instead of failing, and clients should preserve inbox_id and chat.id. This gives the agent useful expectations about partial failures and data relations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the core purpose, followed by the most important operational details. Every sentence adds distinct value: default behavior, alternatives via inbox_ids, rate-limit handling, and relationship to linkedin_read_conversation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter tool with rich annotations, the description covers the essential call patterns, failure behavior, and cross-tool dependencies. It could be slightly stronger on whether limit applies per inbox or overall, but the default usage and alternative inbox handling are fully actionable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema describes inbox_ids and account_id well, and the description adds value by explaining the default CLASSIC_PRIMARY behavior and the purpose of inbox_ids across inbox types. The limit parameter is not addressed in the description, but its min/max constraints in the schema make it self-explanatory.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the verb and resource: 'List LinkedIn private conversations' with a specific default inbox behavior. It distinguishes itself from linkedin_read_conversation by saying it should be used first, but it does not explicitly differentiate from the similar sibling linkedin_list_inbox_chats.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: use it before linkedin_read_conversation when chat_id is unknown, and pass inbox_ids from linkedin_list_inboxes to read non-default inboxes. It does not explicitly state when to prefer linkedin_list_inbox_chats or other alternatives, but the primary routing guidance is present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_followersLinkedIn: List followersA
Read-onlyIdempotent
Inspect

List followers of the account owner or a known LinkedIn user. Use user_id='me' for the connected account owner.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
user_idYesUse 'me' for the connected account owner, otherwise an exact stable LinkedIn system user ID returned by a profile/person resolver. Never pass a name or profile URL. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.me
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the operation as read-only, open-world, idempotent, and non-destructive. The description consistently portrays a simple list operation and adds the target scope, but it does not mention response format or pagination behavior. With annotations covering safety, this is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The core operation is front-loaded and the 'me' convention is stated immediately after, making the essential usage instruction immediately visible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with detailed parameter descriptions in the schema, the description covers the main invocation choice: account owner versus known user. It omits explicit return-value or pagination context, but these are not critical for a straightforward list tool with safe annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description only echoes what the schema already states about user_id='me'. It adds no meaning for offset or account_id, and since schema coverage is 67%, the description does not compensate for the partially uncovered parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'List followers of the account owner or a known LinkedIn user.' It clearly identifies the target account and differentiates from the sibling tool linkedin_list_following by naming the followers relationship explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context by stating that user_id='me' refers to the connected account owner and that a known LinkedIn user can also be used. It lacks explicit when-not-to-use guidance or named alternatives, but the basic selection rule is present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_followingLinkedIn: List followingA
Read-onlyIdempotent
Inspect

List LinkedIn users followed by the connected account owner. Prefer user_id='me'; provider availability may restrict following data for other users.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
user_idYesUse 'me' for the connected account owner, otherwise an exact stable LinkedIn system user ID returned by a profile/person resolver. Never pass a name or profile URL. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.me
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds a behavioral caveat about provider restrictions, but it does not disclose pagination behavior or result format, and with no output schema some behavior remains implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short, purposeful sentences with no filler. The main action is front-loaded, and the usage caveat follows immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool, the schema carries the heavy parameter guidance and the description gives the key scope and provider caveat. The main gap is the undocumented offset parameter and lack of explicit comparison to linkedin_list_followers, but nothing essential is missing for a routine call with user_id=me.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides rich, detailed descriptions for user_id and account_id, and the description reinforces the user_id default with prefer user_id=me. However, offset has no description in the schema or the tool description, and the description does not explain its pagination usage, so it only partially compensates for the 67% schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and object: it lists LinkedIn users followed by the connected account owner. This unambiguously distinguishes the tool from sibling linkedin_list_followers by direction, and the follow-up preference for user_id=me reinforces the intended scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context by instructing the agent to prefer user_id=me and warns that provider availability may restrict data for other users. It does not explicitly name when-not-to-use cases or alternatives such as linkedin_list_followers, so it misses the top bar by a small margin.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_inbox_chatsLinkedIn: List inbox chatsA
Read-onlyIdempotent
Inspect

List chats from a specific LinkedIn inbox. Prefer this over generic chat listing for LinkedIn V2 and premium Sales Navigator/Recruiter inboxes. Get inbox_id from linkedin_list_inboxes.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNo
limitNo
beforeNo
cursorNo
inbox_idYesExact LinkedIn inbox ID returned by linkedin_list_inboxes. Preserve Classic/Sales Navigator/Recruiter selection; never pass contract_id or product name. Inbox ID: Provider inbox/product inbox identifier. LinkedIn Classic may use CLASSIC; premium products expose their own inbox IDs. Obtain with: linkedin_list_inboxes -> inbox.id Never pass: contract_id unless returned as the inbox id, guessing SALES_NAVIGATOR or RECRUITER.
is_unreadNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds no extra behavioral details (e.g., pagination behavior, error conditions, or side effects) beyond stating it lists chats. It does not contradict the annotations, but adds minimal behavioral context beyond what annotations already provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero waste. The first sentence states the core purpose, and the second gives the critical usage direction and the source of the required parameter. It is front-loaded and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a moderately complex tool with 7 parameters, but the description does not mention pagination, filtering, or any output format (no output schema exists). It only covers the inbox source and the preference over generic listing. For an agent to call it correctly, it would need to understand the optional params like cursor, limit, and is_unread, which are undocumented in the schema and not explained in the description. The description is incomplete for this level of complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 29% (only inbox_id and account_id have descriptions; the other 5 params—after, limit, before, cursor, is_unread—have none). The description does not compensate by explaining any parameter semantics. Since the coverage is low, the description should have provided meaning for at least the key parameters, but it is silent on all of them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb and resource: 'List chats from a specific LinkedIn inbox.' It also differentiates from generic chat listing by specifying the scope: 'for LinkedIn V2 and premium Sales Navigator/Recruiter inboxes.' This distinguishes it from siblings like linkedin_list_conversations or messaging_list_chats without needing to open their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs to prefer this tool over generic chat listing for specific inbox types, and tells the user how to obtain the required inbox_id: 'Get inbox_id from linkedin_list_inboxes.' This gives clear context for when to use it and how to source the key parameter, leaving no inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_inboxesLinkedIn: List inboxesA
Read-onlyIdempotent
Inspect

List LinkedIn messaging inboxes for Classic, Sales Navigator and Recruiter. Use before listing inbox chats or starting Sales Navigator/Recruiter conversations; premium products require the appropriate primary inbox.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the behavioral nuance that premium products require the appropriate primary inbox, which is useful context beyond the annotations. However, it doesn't disclose what the return structure looks like or how the tool behaves when no inboxes exist, but with annotations covering the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The core purpose is front-loaded, and the usage guidance is packed into the second sentence without redundancy. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with one optional parameter, full schema coverage, and safety annotations, the description is nearly complete. It explains the product scope and the premium-inbox prerequisite. The only minor gap is that it doesn't describe the return format, but with no output schema and a simple list operation, this is a small omission rather than a critical one.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents the single optional account_id parameter. The description doesn't add parameter-specific details beyond what the schema provides, but the schema's description is already rich (explaining when to omit, when to list accounts, and how to choose). Baseline 3 is correct when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists LinkedIn messaging inboxes and explicitly names the three product types (Classic, Sales Navigator, Recruiter). It distinguishes itself from the sibling linkedin_list_inbox_chats by indicating it should be used before listing inbox chats, and from linkedin_list_conversations by focusing on inboxes rather than conversations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidance: use before listing inbox chats or starting Sales Navigator/Recruiter conversations, and notes that premium products require the appropriate primary inbox. This gives the agent clear when-to-use context and implies when not to use it (when you need chats or conversations, use the sibling tools).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_invitationsLinkedIn: List invitationsA
Read-onlyIdempotent
Inspect

List pending LinkedIn connection/relation requests sent or received by the account owner. Use before accepting/refusing a received invitation or withdrawing a sent invitation so you have the required request_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds the context that the response includes request_id needed for subsequent operations, but does not disclose other behaviors like pagination or response structure. Given the strong annotation coverage, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no fluff. The main action is front-loaded, and the usage context is concise. Efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with strong annotations, the description is fairly complete. It explains purpose, use case, and implies the response contains request_id. It does not mention pagination or edge cases, but these are minor for this type of operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50% (account_id has a detailed description, type lacks one). The description partially compensates by mentioning 'sent or received' for the type parameter, but does not add further meaning beyond what the schema provides for account_id. Minimal added value, so a 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists pending LinkedIn connection/relation requests, distinguishing sent vs received. It differentiates from sibling tools like linkedin_send_invitation and linkedin_accept_invitation by focusing on pending requests and the prerequisite role for those actions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs when to use: before accepting/refusing a received invitation or withdrawing a sent invitation, to obtain the required request_id. This provides clear contextual guidance and implies alternatives (accept/refuse/withdraw) that depend on this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_job_postingsLinkedIn: List job postingsA
Read-onlyIdempotent
Inspect

List LinkedIn job postings OWNED by the user's account. Use this to resolve job_posting_id for management/budget operations. This differs from linkedin_search_jobs, which discovers jobs across LinkedIn.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum postings to return.
cursorNoPagination cursor returned by the previous list call; never invent it.
statusNoProvider-supported posting status filter.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context: it scopes results to postings OWNED by the user's account, and the account_id parameter description adds important behavioral guidance about Nilyo never guessing when multiple accounts exist. This goes beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero waste. The core purpose is front-loaded, the use case is stated, and the sibling differentiation is included. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with 100% schema coverage and no output schema, the description is nearly complete. It covers purpose, use case, and sibling differentiation. The only minor gap is that it doesn't describe the return format or pagination behavior beyond the cursor parameter, but the schema already documents the cursor and the annotations cover the safety profile.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds value by explaining the purpose of the tool (resolving job_posting_id) and the account_id parameter description provides rich guidance about when to omit it, when to list accounts, and how to choose. The cursor parameter's 'never invent it' warning is also valuable behavioral context beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a specific resource ('LinkedIn job postings OWNED by the user's account'), and explicitly differentiates from the sibling tool linkedin_search_jobs, which discovers jobs across LinkedIn. This makes the tool's purpose unmistakable and distinguishes it from the closest alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool: 'Use this to resolve job_posting_id for management/budget operations.' It also names the alternative (linkedin_search_jobs) and states the condition that selects it ('discovers jobs across LinkedIn'). This is clear routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_managed_company_pagesLinkedIn: List managed company pagesA
Read-onlyIdempotent
Inspect

List LinkedIn company pages managed by the connected user. Use before publishing as a company page so you can resolve the required post_as company ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description does not need to restate safety. It adds the scope ('managed by the connected user') and the output's role in resolving post_as, which is useful context, but it does not disclose return format, pagination, or provider-specific behavior. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the operation and followed by the key use case. There is no filler or repetition of schema/annotation content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with zero required parameters and rich annotations, the description provides enough context to call it correctly and explains why the returned pages matter (resolving post_as). It does not enumerate the exact response shape, but the absence of an output schema is mitigated by the simplicity and the stated purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single optional parameter is fully documented in the schema (100% coverage), including when to omit it and how to disambiguate multiple accounts. The description itself adds no parameter-level detail, so it stays at the schema-backed baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('List LinkedIn company pages managed by the connected user') and clarifies scope, distinguishing it from generic company lookup tools like linkedin_get_company and linkedin_search_companies. It also states the downstream purpose, which removes ambiguity about what this tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit timing/context: 'Use before publishing as a company page so you can resolve the required post_as company ID.' It does not explicitly list when-not-to-use or alternatives, but the stated use case is clear enough for an agent to select it appropriately among LinkedIn siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_my_connectionsLinkedIn: List my connectionsA
Read-onlyIdempotent
Inspect

List/search the LinkedIn connections of the account owner. Use for questions such as 'who do I know at this company?', 'find Sarah in my network', introductions, relationship mapping and connection-aware prospecting. This reads the user's personal network rather than a company page.

ParametersJSON Schema
NameRequiredDescriptionDefault
cursorNo
searchNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds the account-owner scope and states that the operation reads the personal network. It does not mention pagination behavior, rate limits, or what happens when multiple accounts exist, but the annotations lower the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no wasted words: it states the operation and resource, gives concrete use cases, and clarifies scope. It does not repeat the schema or annotations and is easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list/search tool with strong safety annotations, the core purpose and context are clear. However, search semantics and cursor pagination are left implicit, and there is no mention of behavior with multiple connected accounts beyond what the schema's account_id description provides. An agent could likely invoke it, but not with complete confidence about search and pagination.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%: only account_id has documentation in the schema, while cursor and search have no descriptions. The tool description says 'List/search' but does not explain how the search parameter matches (name, company, title, etc.) or how cursor pagination works. With such low schema coverage, the description needed to compensate and does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation ('List/search') and the resource ('the LinkedIn connections of the account owner'), and adds representative use cases. It also distinguishes the data domain from company pages, though it does not explicitly name a sibling alternative such as linkedin_list_user_relations or linkedin_search_people.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly enumerates question types where this tool is appropriate, such as 'who do I know at this company?' and 'find Sarah in my network'. It clarifies that this reads the personal network rather than a company page, but it does not provide exclusions or direct agents to alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_post_commentsLinkedIn: List post commentsA
Read-onlyIdempotent
Inspect

List comments on a LinkedIn post. Requires post_id from search/list/get post. Use before deciding which comments need a reply.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
post_idYesExact provider post ID returned by post search/list/get. Never pass post text, author ID or URL. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile with readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds workflow context and post_id provenance, but does not disclose pagination behavior or whether replies are excluded. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. The main operation is front-loaded, followed by a prerequisite and a usage context. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation, the description plus schema is mostly sufficient, but it does not clarify whether only top-level comments are returned versus replies, and it does not describe pagination/offset behavior. With no output schema, an agent would benefit from additional boundary or return-shape context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides detailed descriptions for post_id and account_id, and the tool description mostly restates post_id provenance already present in the schema. It adds no meaning for offset or account_id, and offset has no schema description. With 67% schema coverage, the description does not compensate for the undocumented parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific operation and resource: 'List comments on a LinkedIn post.' It also identifies the required input source for post_id. It does not explicitly contrast with sibling tools like linkedin_list_comment_replies, but the resource scope is unambiguous enough for an agent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a concrete prerequisite ('Requires post_id from search/list/get post') and a practical workflow cue ('Use before deciding which comments need a reply'). It does not name alternatives or give when-not-to-use conditions, but the context is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_post_reactionsLinkedIn: List post reactionsA
Read-onlyIdempotent
Inspect

List people/reactions on a LinkedIn post. Use for engagement analysis or to identify who reacted.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
post_idYesExact provider post ID returned by post search/list/get. Never pass post text, author ID or URL. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds no additional behavioral detail (e.g., pagination, rate limits, error handling), and it is fully consistent with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no waste. The core action is front-loaded and the use case is given in the second sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with rich annotations and detailed schema descriptions for the key parameters, the description covers the essential purpose. It does not describe the return shape or pagination, but that is partly inferable from the tool name and offset parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides thorough descriptions for post_id and account_id, but offset is only defined by type/min/max. Schema coverage is 67%, and the tool description adds no parameter-level semantics beyond the schema, leaving offset's purpose implicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb-resource pair: list reactions on a LinkedIn post, and gives a practical use case ('engagement analysis or to identify who reacted'). It does not explicitly name sibling tools, but 'people/reactions on a LinkedIn post' distinguishes it from listing comments or reacting to a post.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It offers clear context for when to use the tool ('Use for engagement analysis or to identify who reacted'). It does not mention when not to use it or point to alternatives like social_list_comment_reactions for comment reactions, but the intended use is explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_user_postsLinkedIn: List user postsA
Read-onlyIdempotent
Inspect

List posts authored by the connected LinkedIn user or a known provider user ID. Use to locate a recent post and obtain its post_id before reading comments/reactions or replying.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
user_idYesUse 'me' for the connected account owner, otherwise an exact stable LinkedIn system user ID returned by a profile/person resolver. Never pass a name or profile URL. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.me
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, non-destructive, and idempotent behavior. The description adds the scope nuance (connected user or external provider user ID) but does not disclose pagination, rate limits, or return-shape details. This is acceptable given the annotations but not especially rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The first sentence states what the tool does and the second gives the practical workflow, front-loading the main action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool, the description covers its main purpose and the downstream use of post_id. It omits details about pagination or return format, but the annotations and schema cover the essential safety and parameter context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is roughly 67%: user_id and account_id are well described in the schema, while offset is not. The tool description reinforces the user_id meaning but adds no parameter-level detail, especially for offset.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: listing posts authored by the connected user or a provided user ID. It also states the operational purpose (locating a recent post to get its post_id), which distinguishes it from sibling post-reading and post-writing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear workflow context: use this before reading comments/reactions or replying, because it supplies the post_id. It does not explicitly name alternatives or when not to use it, so it stops short of the top score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_list_user_relationsLinkedIn: List user relationsA
Read-onlyIdempotent
Inspect

List a LinkedIn user's visible relations by provider user ID. Use when network graph context is requested for a known profile.

ParametersJSON Schema
NameRequiredDescriptionDefault
cursorNo
searchNo
user_idYesStable LinkedIn system user ID returned by a profile/person resolver. Never pass a name or linkedin.com/in/... URL. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds only 'visible' to indicate scope; it does not disclose relation types, pagination via cursor, or non-exhaustive output behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, action first and use case second. No filler, no repetition of schema content, and the most important scoping information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list operation with helpful annotations and a well-documented key parameter, this is minimally workable. It lacks a definition of what counts as a 'relation' and does not describe the output shape, and there is no output schema to fill that gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema documents user_id and account_id well, and the description reinforces that user_id is a provider user ID. But cursor and search have no descriptions, and at 50% schema coverage the description does not compensate for those undocumented fields or explain their role in listing relations.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'List a LinkedIn user's visible relations by provider user ID.' This is clear and matches the tool name. However, it doesn't distinguish 'relations' from overlapping siblings like linkedin_list_my_connections, linkedin_list_followers, or linkedin_list_following.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use the tool: 'Use when network graph context is requested for a known profile.' This is a clear trigger condition. It does not name alternatives or provide when-not-to-use guidance, so it misses the highest bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_react_to_messageLinkedIn: React to messageA
Destructive
Inspect

Add a reaction to a specific LinkedIn message. Requires chat_id and message_id, normally discovered by reading the conversation.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID returned by conversation/inbox listing. Never pass a person name or provider user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
reactionYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the selected chat. Keep it paired with chat_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=true, so the description need not restate that this is a write operation. The description adds no extra behavioral context beyond the act of adding a reaction, such as idempotency implications, limits, or side effects, but it is consistent with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the action and resource, with no filler or redundant restatements. It is appropriately sized for the information it conveys.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is too thin for a state-changing tool with no output schema Asi He. It does not describe what a successful response looks like, how reactions are represented (e.g., emoji vs. code), or any error conditions. The absence of reaction value guidance is a critical gap for an agent invoking this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides detailed descriptions for chat_id, message_id, and account_id, but the required reaction parameter has no schema description and the tool description does not specify valid values or format. With 75% schema coverage, the description fails to compensate for the completely undocumented reaction parameter, leaving the agent without guidance on what to pass.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb ('Add') and resource ('a specific LinkedIn message'), which distinguishes it from post and comment reaction tools. The provider and target are clear both in the description and the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description names required parameters (chat_id, message_id) and how to obtain them ('normally discovered by reading the conversation'). However, it does not explicitly state when to choose this tool over related siblings like linkedin_react_to_post or message_add_reaction, nor does it mention exclusions or prerequisites beyond parameter discovery.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_react_to_postLinkedIn: React to postA
Destructive
Inspect

Add a LinkedIn reaction to a post on behalf of the user. Use a supported LinkedIn reaction value and only when the user's intent to react is clear.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesExact provider post ID returned by post search/list/get. Never pass post text, author ID or URL. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
reactionYesLinkedIn reaction type (a plain 'like' or an emoji is rejected by LinkedIn).
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true, which the description matches by describing a mutation ('Add'). It adds context: acts on behalf of the user, requires clear intent, and notes LinkedIn's rejection of plain 'like'/emoji. This goes beyond annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no filler. The primary action is stated first, followed by a critical usage condition. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple and the schema covers all parameters thoroughly. The description adds the intent-clarity requirement and reaction validation note. No output schema exists, so return-value explanation is not required. Slight gap: no mention of authentication or account prerequisites, but these are implied by the platform context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions for post_id, reaction, and account_id, including how to obtain IDs and avoid common mistakes. The tool description adds little beyond the schema, so a baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Add'), a resource ('post'), and the on-behalf-of-user scope. The supported reaction values and the intent-clearance condition are explicit, clearly distinguishing it from sibling tools like linkedin_comment_on_post and linkedin_react_to_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear when-to-use condition: 'only when the user's intent to react is clear' and warns that plain 'like' or emoji is rejected. It doesn't explicitly name alternatives or when not to use, but the intent condition and reaction enum give practical guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_read_conversationLinkedIn: Read conversationA
Read-onlyIdempotent
Inspect

Read a LinkedIn private conversation plus recent messages. Use before replying so the agent understands prior context, commitments and tone.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID returned by conversation/inbox listing. Never pass a person name or provider user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds value by stating the tool returns 'recent messages' and that it should be used to understand 'prior context, commitments and tone' — behavioral context about what the agent gets. It doesn't contradict annotations. It doesn't mention rate limits or pagination, but for a read operation with strong annotations, this is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero waste. The first sentence states the action and scope; the second gives the usage context. It is front-loaded with the core purpose and immediately useful for an agent deciding whether to call this tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with no output schema, the description covers the core purpose and usage context. The parameter schema is extremely detailed, covering the tricky chat_id vs person name distinction and the account_id disambiguation. The only minor gap is that it doesn't describe the exact return shape or message ordering, but for a conversation read tool this is acceptable given the annotations and schema richness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters thoroughly. The description adds context by explaining the purpose of reading the conversation, which helps the agent understand why chat_id matters. The chat_id parameter description is exceptionally detailed, covering what to pass, what not to pass, and how to obtain it. The description itself doesn't add much beyond the schema, but the schema is so rich that the baseline 3 is exceeded slightly by the 'prior context, commitments and tone' framing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read'), a specific resource ('LinkedIn private conversation'), and the scope ('plus recent messages'). It also names the intended use case ('before replying'), which distinguishes it from sibling tools like linkedin_list_conversations and linkedin_list_inbox_chats. The title reinforces the same clear purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use before replying so the agent understands prior context, commitments and tone.' This gives a clear when-to-use directive. It also implicitly distinguishes from listing tools by focusing on reading a single conversation's content. The parameter description for chat_id further clarifies what to pass and what not to pass, which is usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_recruiter_get_applicantLinkedIn: Recruiter get applicantA
Read-onlyIdempotent
Inspect

Get one Recruiter applicant. Required chain: list/select Hiring Project -> project.id -> list applicants -> applicant.id. applicant_id is scoped to the selected project context.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
project_idYesExact LinkedIn Recruiter Hiring Project ID from linkedin_recruiter_list_projects. Never pass project name.
applicant_idYesExact applicant profile ID returned by the corresponding applicants listing. Keep it paired with the Classic job_id or Recruiter project_id that produced it.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, covering the safety profile. The description adds useful context beyond annotations: the dependency on prior steps and the scoping of applicant_id. It does not contradict annotations and adds value by explaining the prerequisite chain, which is not present in structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences with no filler. It front-loads the core purpose and then provides the chain and scoping constraint. Every sentence adds necessary information, and it is appropriately sized for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, the description covers the essential usage: the chain and scoping. There is no output schema, but the description implies a single applicant is returned. It does not explicitly state the return format, but that is minor given the read-only nature and the clear purpose. Overall, it is complete enough for an agent to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter already described in detail. The description adds only a marginal clarification that applicant_id is scoped to the project context, which is also implied in the schema. Thus it does not significantly enhance understanding beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Get one Recruiter applicant.' It clearly indicates this is a single-applicant retrieval, distinguishing it from list-applicant tools. It also conveys the required context chain, making the purpose unambiguous even among many LinkedIn sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an explicit required chain: list/select Hiring Project -> project.id -> list applicants -> applicant.id. It clarifies that applicant_id is scoped to the project context. It does not explicitly mention when not to use this tool or name alternatives like linkedin_recruiter_list_applicants, but the chain implies it is for a single already-listed applicant, which is sufficient guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_recruiter_get_applicant_resumeLinkedIn: Recruiter get applicant resumeA
Read-onlyIdempotent
Inspect

Retrieve a Recruiter applicant resume. Resolve exact project_id and applicant_id first; never use candidate name or LinkedIn URL as applicant_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
project_idYesExact LinkedIn Recruiter Hiring Project ID from linkedin_recruiter_list_projects. Never pass project name.
applicant_idYesExact applicant profile ID returned by the corresponding applicants listing. Keep it paired with the Classic job_id or Recruiter project_id that produced it.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the agent knows this is a safe read. The description adds the constraint on applicant_id, which is more about input semantics than behavioral disclosure. It does not describe side effects, error behavior, or what happens with invalid IDs. Since annotations cover the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences: the first states the action, the second delivers the key usage constraint. It is front-loaded and avoids unnecessary words. No fluff or repetition of schema details, though it could have added sibling differentiation without much cost.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with 3 well-documented parameters and no output schema, the description is mostly sufficient to invoke it. The main gap is the lack of explicit distinction from the Classic variant; an agent might choose the wrong tool without guidance. Also, the output format (resume content) is not mentioned, but that is typically self-evident for a 'get resume' tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter already documented in detail (e.g., project_id must be exact, applicant_id must be the profile ID from a listing). The tool description adds a redundant warning about not using names/URLs, but it does not provide new parameter semantics beyond what the schema already states. Baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Retrieve a Recruiter applicant resume.' The verb 'retrieve' and the resource 'Recruiter applicant resume' are specific, and the 'Recruiter' prefix distinguishes it from the sibling linkedin_classic_get_applicant_resume. The additional constraint on applicant_id clarifies what not to pass, further sharpening purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear prerequisite: resolve exact project_id and applicant_id first, and explicitly warns against using candidate name or LinkedIn URL. However, it does not mention when to use this tool versus the alternative linkedin_classic_get_applicant_resume, nor does it state that this is for Recruiter projects only. The guidance is useful but incomplete for routing between siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_recruiter_list_applicantsLinkedIn: Recruiter list applicantsA
Read-onlyIdempotent
Inspect

List applicants from a LinkedIn Recruiter Hiring Project talent pool. Resolve project_id first. Recruiter applicants are project-scoped; never substitute a Classic job_id for project_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNoOpaque next_cursor returned by previous page; never invent.
filtersNoRecruiter talent-pool applicant filters such as sort/seniority/current-company using documented V2 enums/parameter IDs.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
project_idYesExact LinkedIn Recruiter Hiring Project ID from linkedin_recruiter_list_projects. Never pass project name.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, non-destructive behavior, so the description only needs to add context. It adds the project-scoping warning, but does not disclose pagination behavior, result shape, or account-selection nuances beyond what the schema already says.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action, then the critical prerequisite and the key exclusion. There is no filler or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a listing tool with rich schema documentation and safety annotations, the description covers the most important workflow trap (project_id vs job_id). It does not describe pagination or the return format, but the schema covers cursor behavior and the tool is simple enough that this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high at 80%, so the baseline is 3. The description adds real semantic value by clarifying that project_id refers to a Recruiter Hiring Project and explicitly warning against using a Classic job_id, which is not stated in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('List'), a specific resource ('applicants from a LinkedIn Recruiter Hiring Project talent pool'), and makes the scope explicit ('project-scoped'). It also directly contrasts with Classic job_id, which clearly differentiates this tool from linkedin_classic_list_job_applicants.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives actionable directives: resolve project_id first and never substitute a Classic job_id for project_id. It does not explicitly name alternative tools or state broader when-to-use conditions, but the exclusion is specific and useful enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_recruiter_search_peopleLinkedIn: Recruiter search peopleA
Read-onlyIdempotent
Inspect

Search LinkedIn Recruiter candidates using the user's Recruiter-capable account. Use for candidate sourcing, recruiting projects/talent pools and Recruiter-specific filters. Resolve filter IDs with linkedin_get_search_parameters(product='recruiter') when necessary.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, covering safety and side-effect behavior. The description adds the requirement of a Recruiter-capable account and the need to resolve filter IDs, which is useful context beyond annotations. However, it does not disclose other behavioral aspects like pagination, rate limits, or result format, which are not covered by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no filler. It front-loads the core purpose, then gives use cases and a practical dependency. Every sentence adds value, and the structure is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with one optional parameter and annotations covering safety, the description is reasonably complete. It states the use case, account requirement, and how to obtain filter IDs. It does not explicitly describe the return format (likely a list of candidates) or pagination, but with no output schema and a single param, these are minor gaps. The dependency on get_search_parameters is a critical piece that is covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% because the only parameter (account_id) is fully described in the schema. The description does not add additional parameter meaning; it only mentions filter ID resolution, which implies there are other parameters not represented in the schema. Since the schema already documents the parameter well, baseline 3 applies, and the description adds marginal value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (search) and the resource (LinkedIn Recruiter candidates) using the user's Recruiter-capable account. It explicitly differentiates from sibling search tools by mentioning Recruiter-specific filters and the product context, making it distinct from linkedin_search_people or linkedin_sales_navigator_search_people.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context: candidate sourcing, recruiting projects/talent pools, and Recruiter-specific filters. It also gives a concrete prerequisite instruction (resolve filter IDs with linkedin_get_search_parameters(product='recruiter')). However, it does not explicitly state when NOT to use this tool or name alternatives, though the context strongly implies it is for Recruiter-specific searches only.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_remove_connectionLinkedIn: Remove connectionA
Destructive
Inspect

Remove an existing LinkedIn relation/connection. Resolve the exact provider user_id first. This changes the user's network and requires explicit intent.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idYesExact provider user ID returned by the relevant profile/contact resolver; never a display name or profile URL. For LinkedIn, use the stable system ID. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false. The description adds context beyond this by stating the impact ('changes the user's network') and the requirement of explicit intent. This is useful behavioral context that is not in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with no filler. The first sentence states the action, the second gives the key precondition, and the third communicates the impact and intent requirement. Every sentence earns its place and the purpose is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with two parameters, full schema coverage, and annotations covering safety/destructive behavior, the description provides the essential purpose, precondition, and consequence. No output schema exists, but the description still gives enough operational context for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema fully documents both parameters. The main description adds only a sequence hint ('Resolve the exact provider user_id first'), which is minor. Baseline of 3 is appropriate since the schema carries the semantic weight.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Remove an existing LinkedIn relation/connection.' This clearly distinguishes it from related sibling tools like linkedin_send_invitation, linkedin_accept_invitation, and linkedin_unfollow_user. The purpose is immediately understandable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for use by instructing to 'Resolve the exact provider user_id first' and warning that the action 'changes the user's network and requires explicit intent.' It does not explicitly name alternatives or exclusions, but it sets the appropriate precondition and intent requirement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_reply_to_commentLinkedIn: Reply to commentA
Destructive
Inspect

Reply DIRECTLY to one exact LinkedIn comment, not create a new top-level comment. Required chain from human reference: resolve post -> post.id -> list comments -> comment.id -> optionally read replies -> reply. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesFinal reply text explicitly requested/approved by the user.
post_idYesExact post ID from post search/list. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
comment_idYesExact comment ID from comments of the resolved post. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint=true and readOnlyHint=false, so the write nature is covered. The description adds that it replies 'DIRECTLY' and not a top-level comment, which is more about purpose than side effects. It doesn't disclose what happens on success (e.g., whether a reply object is returned) or any failure modes. Given the annotations cover the safety profile, the description adds moderate value but not rich behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured: it front-loads the core purpose, then presents the required chain, then gives ID-specific guidance. It is dense with actionable information and avoids filler. However, it repeats the ID guidance that already exists in the schema, which adds redundancy. Still, given the tool's complexity, the length is justified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is complex, requiring exact IDs from a multi-step chain. The description covers the full chain, how to obtain each ID, and what not to pass. It also includes the optional account_id in the schema (though not in the description). No output schema exists, but for a write operation that's acceptable. The description lacks explicit error handling or success indication, but given the complexity, it is substantially complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already contains the exact guidance for post_id and comment_id, duplicating the description's text. The description adds the overall resolution chain, but for individual parameters it provides no new information beyond the schema. The account_id parameter is not mentioned in the description at all, but the schema covers it. Thus, the description adds minimal value over the schema, earning the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: to reply directly to one exact LinkedIn comment, explicitly distinguishing it from creating a new top-level comment. It names the verb 'reply' and the resource 'comment', and differentiates from the sibling linkedin_comment_on_post by its 'not create a new top-level comment' clause. This is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidance: it gives the required resolution chain (resolve post -> list comments -> reply), states what to obtain and how (via linkedin_search_posts, linkedin_list_user_posts, etc.), and explicitly forbids passing post text, author user ID, or URL unless a resolver accepts them. It also distinguishes from the top-level comment tool. This is thorough and leaves no ambiguity about when to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_resolve_companyLinkedIn: Resolve companyA
Read-onlyIdempotent
Inspect

Resolve a human company name to LinkedIn company results and exact company IDs. Use before employee searches, company profile reads or company mentions. LinkedIn company mentions require the numeric company ID; the slug from /company/google/ is not sufficient. LinkedIn company ID: Provider numeric/company ID. For mentions LinkedIn requires numeric company ID, not the company URL slug. Obtain with: linkedin_search_companies -> selected result.id; linkedin_get_company after resolving a company Never pass: linkedin.com/company/google URL, company slug such as google, company name.

ParametersJSON Schema
NameRequiredDescriptionDefault
filtersNo
keywordsYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds a critical behavioral nuance: LinkedIn mentions require the numeric company ID, not the slug, and clarifies that the result is a set of company IDs. It doesn't describe return format or error behavior, but given the annotation coverage, it adds useful context beyond what is already structured.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is somewhat verbose and contains redundant statements: 'LinkedIn company mentions require the numeric company ID; the slug from /company/google/ is not sufficient.' and later 'For mentions LinkedIn requires numeric company ID, not the company URL slug.' convey the same point. The 'LinkedIn company ID: Provider numeric/company ID.' sentence adds little. While the key directives are front-loaded, the redundancy could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description should clarify the return structure. It mentions 'LinkedIn company results and exact company IDs' but doesn't specify whether it returns a list, a single match, or how to select among multiple results. The workflow references other tools, which helps, but the 'filters' parameter is completely unexplained. Given 3 parameters and a nested object, the description leaves notable gaps for an agent to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% (only account_id has a description). The description clarifies that 'keywords' should be a human company name (from the opening sentence) and indirectly warns against passing URLs or slugs. However, it provides no explanation for the 'filters' parameter, which is a nested object and could be ambiguous. The description adds some semantic value for keywords but falls short of compensating for the undocumented filters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool does: 'Resolve a human company name to LinkedIn company results and exact company IDs.' It specifies the verb (resolve), the input (human company name), and the output (results and numeric company IDs). It also distinguishes itself from siblings by indicating it should be used before employee searches, company profile reads, or company mentions, and explains that the numeric ID is required for mentions, differentiating it from URL-slug-based tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: 'Use before employee searches, company profile reads or company mentions.' It also provides a workflow: 'Obtain with: linkedin_search_companies -> selected result.id; linkedin_get_company after resolving a company' and clear exclusions: 'Never pass: linkedin.com/company/google URL, company slug such as google, company name.' This tells the agent exactly when to invoke the tool and what inputs to avoid.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_resolve_my_postLinkedIn: Resolve my postA
Read-onlyIdempotent
Inspect

Resolve a user's description such as 'my latest post' into exact post IDs before comments/reactions/edit/delete. Returns the account owner's posts; choose the matching post and reuse result.id. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive intent, so the safety profile is covered. The description adds useful behavioral context: the tool returns the account owner's posts as candidates, requires the agent to choose the matching one and reuse result.id, and warns that post text, author user ID, or URL must not be passed. This goes beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but each sentence earns its place: the core purpose is front-loaded, the ID format is clarified, concrete obtaining paths are listed, and negative constraints are stated. The parameter description for account_id is also concise and actionable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a resolver with no output schema, the description clearly explains what the tool returns (account owner's posts), how to use result.id, and what inputs are prohibited. The only meaningful gap is the absence of explicit pagination/offset behavior, which would help the agent know if it needs to iterate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema documents account_id thoroughly, including how to handle single vs. multiple connected accounts Satisfyingly. offset is only present as a name and integer type, with no description in the schema and none in the tool description. The description does add meaning around accepted post ID formats and how to obtain them, but it does not clarify how offset affects results, leaving a gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Resolve') and resource ('user's description such as 'my latest post' into exact post IDs' ) and clearly distinguishes itself from post mutation tools by saying it runs 'before comments/reactions/edit/delete.' It also differentiates from the sibling resolve tools by explicitly mentioning post resolution and account owner posts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context: use when a user refers to their post by a phrase and before operations like comments, reactions, edit, or delete. It also names concrete tools to obtain the ID from (linkedin_search_posts, linkedin_list_user_posts, instagram_list_user_posts) and what never to pass. It does not explicitly contrast with alternatives like linkedin_resolve_person or linkedin_resolve_company, but that is less relevant for this resource type.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_resolve_personLinkedIn: Resolve personA
Read-onlyIdempotent
Inspect

Resolve a human description (name, role, employer, location keywords) to LinkedIn people and their stable system IDs before an action. Use when the user says 'message Sarah at Acme' or 'connect with the CTO of X' rather than providing an ID. If multiple plausible results remain, show/disambiguate them before any write. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
filtersNoOptional already-resolved LinkedIn search filters. If a filter needs a provider parameter ID, resolve it first with linkedin_get_search_parameters.
keywordsYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/idempotent behavior, and the description adds meaningful workflow context: this is a pre-action resolution step, multiple plausible results must be disambiguated before any write, and the output is a stable system ID commonly in ACo... format. This goes beyond the annotation flags and helps prevent unsafe or premature actions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Most sentences are front-loaded and purposeful: purpose, trigger conditions, disambiguation policy, ID format, and anti-patterns all earn their place. The ID-obtaining chain is dense but relevant; a little restructuring or bullet formatting would make it easier to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Together with annotations and schema, the description covers input semantics, safety, disambiguation, and output ID format. It doesn't specify no-match behavior or output shape, but the absence of an output schema is partially mitigated by the stable-ID explanation. Adequate for a resolver tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers filters and account_id, while the description compensates for the under-documented keywords parameter by specifying accepted content (name, role, employer, location keywords) and by listing how to obtain the stable ID and what never to pass instead. The limit parameter remains only partially addressed, but its schema constraints make its meaning clear enough.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Resolve a human description ... to LinkedIn people and their stable system IDs.' It clearly distinguishes itself from siblings like linkedin_resolve_company by targeting people and by framing the input as a natural-language description rather than an ID.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete trigger examples ('message Sarah at Acme', 'connect with the CTO of X') and an explicit exclusion ('rather than providing an ID'). It also instructs the agent to disambiguate before writes, but it doesn't name the direct-ID alternative tools as replacements, so it is clear context without a full when-not/alternative matrix.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_sales_navigator_search_peopleLinkedIn: Sales Navigator search peopleA
Read-onlyIdempotent
Inspect

Search LinkedIn Sales Navigator leads using the user's own Sales Navigator-capable LinkedIn account. Use for advanced prospecting intent such as lead lists, seniority, years of experience, current/past company, geography, function and saved-search criteria. Resolve human filter names to LinkedIn IDs with linkedin_get_search_parameters(product='sales_navigator') when necessary.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds valuable context: it requires the user's own Sales Navigator-capable account, and it explains the dependency on linkedin_get_search_parameters for filter name resolution. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The first sentence states the core purpose and scope; the second provides the when-to-use guidance and the alternative tool pointer. The most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only search tool with one optional parameter and annotations covering safety, the description covers the essential use case, the filter-resolution prerequisite, and the account context. It does not mention result format or pagination, but that is not strictly required for a search tool with no output schema, and the core decision-making info is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains account_id thoroughly (including the 'never guesses' behavior when multiple accounts exist). The tool description adds no new meaning about the parameter, so it relies on the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Search LinkedIn Sales Navigator leads'), identifies the resource (Sales Navigator leads via the user's own Sales Navigator-capable account), and distinguishes it from generic search by the 'advanced prospecting intent' wording. It also references the sibling tool for filter resolution, making its scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells when to use this tool ('advanced prospecting intent such as lead lists, seniority, years of experience, current/past company, geography, function and saved-search criteria') and directs the agent to linkedin_get_search_parameters for resolving filter names. It does not explicitly state when not to use it (e.g., for basic search), but the Sales Navigator qualifier and the mention of 'advanced' imply a clear use case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_search_companiesLinkedIn: Search companiesA
Read-onlyIdempotent
Inspect

Search LinkedIn companies from the user's own account. Use to find a company ID/profile before looking for employees, checking network relationships or performing a people search scoped to that company.

ParametersJSON Schema
NameRequiredDescriptionDefault
industryNo
keywordsNo
locationNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
has_job_postingsNo
is_employing_relationsNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, open-world, idempotent, and non-destructive behavior, so the bar is lower. The description adds 'from the user's own account' as an account-context trait capital. However, it does not disclose search semantics, result shape, pagination, or limits, which would be useful behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and followed by concrete use cases. No filler or redundant restatement of the title. The structure effectively supports quick agent comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with six optional parameters.Type:Boolean, no output schema, and sparse schema descriptions, the description is too thin. It omits return value shape, parameter semantics, and edge behaviors, leaving an agent to guess at important invocation details. The clear use-case framing helps, but it doesn't make the tool self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 17%, with only account_id described. The description does not compensate by explaining how keywords, industry, location, has_job_postings, or is_employing_relations affect the search. Parameter names are somewhat self-explanatory, but the description adds no semantic value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the action ('Search LinkedIn companies'), the resource (companies), and the source ('from the user's own account'). It also clearly frames the purpose (finding a company ID/profile before other scoped operations), which distinguishes it from related search tools like linkedin_search_people or linkedin_search_jobs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: use it to find a company ID/profile before employee lookups, network checks, or company-scoped people searches. It doesn't explicitly name alternative tools or exclusion criteria, but the intended pipeline is stated well enough for an agent to route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_search_from_urlLinkedIn: Search from URLA
Read-onlyIdempotent
Inspect

Run a native LinkedIn search from a LinkedIn search URL. Use when the user pastes a linkedin.com/search/results/... URL, Sales Navigator search URL or Recruiter search URL and wants the same filters/results available to the agent.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
productYesclassic
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the behavioral nuance that the search uses the URL's filters and makes results available to the agent, which is useful context. However, it does not disclose potential limitations like rate limits or authentication specifics, but those are not required given the annotation coverage. The description adds some value beyond the annotations, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The purpose is front-loaded, and the usage condition follows immediately. Every word contributes to understanding the tool's role and trigger.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with a simple input (URL and product type), the description adequately covers the core use case: it states what it does and when to use it, and the phrase 'same filters/results available to the agent' implies the output. There is no output schema, but the description does not need to elaborate return formats. The account_id parameter is explained in the schema, so the description is complete enough for an agent to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33% (only account_id has a description). The description mentions the URL types but does not explicitly explain the 'url' or 'product' parameters. It implies that the product parameter corresponds to the URL type, but it never states that connection. The account_id parameter is not mentioned in the description at all, though it is well-documented in the schema. Given the low schema coverage, the description should compensate, but it fails to do so beyond indirect hints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Run a native LinkedIn search from a LinkedIn search URL' – a specific verb (run) and resource (search URL), and it immediately differentiates itself from sibling search tools (e.g., linkedin_search_people) by grounding the action in a URL. It enumerates the three URL types (classic, Sales Navigator, Recruiter), making the tool's scope unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence explicitly states the trigger condition: 'Use when the user pastes a linkedin.com/search/results/... URL, Sales Navigator search URL or Recruiter search URL and wants the same filters/results available to the agent.' This gives clear when-to-use guidance. It does not explicitly name alternatives for the when-not case, but the implicit contrast with other search tools is sufficient for an agent to infer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_search_jobsLinkedIn: Search jobsA
Read-onlyIdempotent
Inspect

Search LinkedIn jobs with the user's own account. Use for job discovery by keywords, title, company, location, seniority, employment status or workplace type.

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsNo
job_titleNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
date_postedNo
primary_locationNo

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnly/openWorld/idempotent hints, so the safety profile is covered. The description adds the auth framing 'with the user's own account,' which is useful context, but it does not disclose result format, pagination, or any rate-limit behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler, the primary action and search scope are front-loaded, and the usage guidance follows immediately. Every word contributes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has five optional parameters and no output schema, so more detail on expected results or parameter formats would help. The schema does describe account_id thoroughly, and annotations cover side effects, but pagination, result shape, and the mismatch between described facets and actual parameters remain gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 20% schema description coverage, the description partially compensates by naming search criteria, but several mentioned facets (company, seniority, employment status, workplace type) do not map to actual schema properties. It adds meaning for keywords and title but leaves date_posted and primary_location semantics mostly to their names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb and resource: 'Search LinkedIn jobs'. It also frames the search facets (keywords, title, company, location, seniority, employment status, workplace type), which distinguishes this from sibling search tools like linkedin_search_people and linkedin_search_companies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Use for job discovery' gives explicit usage context, and listing search criteria tells an agent when this tool fits. It does not name alternatives or state when not to use it, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_search_peopleLinkedIn: Search peopleA
Read-onlyIdempotent
Inspect

Search LinkedIn Classic people with the user's own LinkedIn account. Use to find a person/provider user ID from a name, title, employer, location, industry, keywords or network distance. When the next requested action is message/invitation, take the chosen result's id and pass it to the action tool; never pass a profile URL directly to an action requiring user_id. Some filters require IDs; resolve them first with linkedin_get_search_parameters.

ParametersJSON Schema
NameRequiredDescriptionDefault
cursorNo
industryNo
keywordsNo
locationNoLinkedIn location IDs; call linkedin_get_search_parameters when starting from a human location name.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
current_companyNoLinkedIn company IDs, not company names, when the provider requires IDs.
network_distanceNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: it searches with the user's own LinkedIn account, it returns results that may need to be resolved to IDs, and it warns against passing profile URLs to actions requiring user_id. It doesn't describe pagination or result format, but the annotations carry the safety burden and the description adds meaningful operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the core purpose. It packs a lot of useful guidance into three sentences without redundancy. The only minor issue is that the account_id guidance is embedded in the schema rather than the description, but the description itself is well-structured and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with no output schema, the description covers the key operational context: what it searches, how to use results, and how to handle ID-based filters. It doesn't mention pagination or result limits, but given the annotations and the clear downstream guidance, it is reasonably complete for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 43%, so the description must compensate. It does: it explains that some filters require IDs and must be resolved first with linkedin_get_search_parameters, and it explicitly mentions location and current_company as ID-based filters. It also explains the account_id parameter's behavior (optional when one account, must be resolved when multiple). This adds meaning beyond the raw schema, though not every parameter is individually explained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches LinkedIn Classic people using the user's own account, and lists the search criteria (name, title, employer, location, industry, keywords, network distance). It distinguishes itself from sibling search tools by specifying 'LinkedIn Classic' and by explaining the downstream use case (finding a person/provider user ID for message/invitation actions).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool: to find a person/provider user ID from various criteria. It also gives clear guidance on what to do next (pass the chosen result's id to the action tool, never pass a profile URL directly) and when to use a prerequisite (resolve filters with linkedin_get_search_parameters). This is strong routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_search_postsLinkedIn: Search postsA
Read-onlyIdempotent
Inspect

Search LinkedIn posts using the user's own account. Use to find a post before reading comments, checking reactions or replying. Returns post IDs required by comment/reaction tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
sort_byNo
keywordsNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
date_postedNo

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false, so the tool is safe and non-destructive. The description adds that it searches using the user's own account, implying authorization context, and that it returns post IDs needed by downstream tools. It doesn't disclose potential rate limits or result ordering, but given the annotation coverage, the added value is moderate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise (three sentences) and front-loaded with the core action and use case. The first sentence states purpose and scope, the second gives usage context, and the third highlights output importance. No wasted words, though it could have been slightly more explicit about parameter formats.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 4 parameters, no output schema, and low schema coverage, the description should provide more guidance on how to construct the search. It omits whether keywords are free-text or exact match, how date_posted is formatted, and what sort_by options exist. It also doesn't clarify if the returned post IDs are for all matching posts or a single best match. It covers the account_id ambiguity well but leaves other aspects under-specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%, with only account_id having a description. The description does not explain the semantics of sort_by, keywords, or date_posted beyond what their names imply. However, the description does mention that it returns post IDs, which indirectly clarifies the output but not the parameters. Since the schema lacks descriptions for three parameters, the description should compensate but doesn't, leaving the agent to infer. Baseline is 3 when schema coverage is low, but the description adds minimal parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Search' and the resource 'LinkedIn posts', and specifies that it uses the user's own account. It distinguishes itself from related tools like linkedin_get_post and linkedin_resolve_my_post by emphasizing it finds posts to support subsequent actions (reading comments, reactions, replying). However, it doesn't explicitly differentiate from other search tools (e.g., linkedin_search_people, linkedin_search_companies) beyond the resource type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use this tool: to find a post before reading comments, checking reactions, or replying. It also hints at the alternative: using comment/reaction tools after obtaining the post ID. However, it doesn't explicitly say when not to use it or mention alternatives for searching other content types, though the resource type (posts) implicitly does.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_select_contractLinkedIn: Select contractAInspect

Select a LinkedIn Sales Navigator/Recruiter premium contract. First call linkedin_list_contracts and reuse exact contract.id. Do not pass product name or inbox_id. LinkedIn premium contract ID: Exact Sales Navigator/Recruiter contract id. Obtain with: linkedin_list_contracts -> contract.id Never pass: inbox_id, product name.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
contract_idYesExact premium contract ID returned by linkedin_list_contracts -> contract.id. LinkedIn premium contract ID: Exact Sales Navigator/Recruiter contract id. Obtain with: linkedin_list_contracts -> contract.id Never pass: inbox_id, product name.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and idempotentHint=false, indicating a state-changing operation. The description adds behavioral context by explaining the dependency on a prior list call and explicitly forbidding certain parameters, which helps the agent understand the expected preconditions. It does not contradict the annotations and provides useful operational details beyond them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the primary action, followed by the prerequisite and exclusions. There is some redundancy with the schema descriptions (repeating the contract ID source), but it remains efficient and does not waste words. The structure is logical: purpose first, then usage guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple selection tool with only two parameters, the description fully covers what is needed: the action, the prerequisite call, the exact ID source, and explicit exclusions. The account_id parameter is thoroughly explained in the schema, and the description ensures the agent knows not to guess when multiple accounts exist. No essential information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for both parameters, with the contract_id description already repeating the same guidance about obtaining it from linkedin_list_contracts and the account_id description being quite detailed. The tool description adds no new semantic meaning beyond what the schema already contains, so it does not elevate the score beyond the baseline for full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Select') and resource ('LinkedIn Sales Navigator/Recruiter premium contract'), clearly distinguishing the action from list/get operations. It also explicitly instructs to first call linkedin_list_contracts and reuse the exact contract.id, which clarifies the intended workflow. This differentiates it from any potential sibling selection tool and makes the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance by requiring a prerequisite call to linkedin_list_contracts and mandating the reuse of the exact contract.id. It also gives clear exclusions ('Do not pass product name or inbox_id'), preventing common misuse. This is comprehensive usage direction beyond what the schema alone provides.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_send_invitationLinkedIn: Send invitationA
Destructive
Inspect

Send a LinkedIn connection/relation request from the user's own account. Requires a provider user_id, not a profile URL. If the user supplied a URL or name, FIRST call linkedin_get_profile or linkedin_search_people and use the returned id. Include a note only when explicitly requested or clearly provided by the user.

ParametersJSON Schema
NameRequiredDescriptionDefault
messageNo
user_idYesStable LinkedIn provider user ID obtained from linkedin_get_profile/search_people.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry destructiveHint=true and idempotentHint=false, so the mutation risk is known. The description adds that the request is sent from the user's own account and that a note should only be included when explicitly requested, but does not disclose consequences such as duplicate invitations, rate limits, or errors when already connected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The core action is front-loaded, the key ID requirement is stated immediately, and the note policy is a concise final sentence. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description plus schema covers the essential preconditions, ID resolution workflow, and optional account disambiguation. It does not describe return values or failure modes, but given no output schema and the presence of destructive/idempotent annotations, the missing information is not critical for invoking the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, and the description adds meaning beyond the schema: it clarifies that user_id must be a provider ID, not a URL, and constrains the 'message' parameter by saying a note should only be included when explicitly requested or clearly provided. account_id is already well documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('send') and resource ('LinkedIn connection/relation request'), and clarifies it acts from the user's own account. This distinguishes it from sibling tools like linkedin_accept_invitation or linkedin_send_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states the required input form ('provider user_id, not a profile URL') and gives a direct pre-call workflow: if only a URL/name is available, first call linkedin_get_profile or linkedin_search_people. It does not explicitly name alternatives like linkedin_send_message for already-connected users, but the context is fairly clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_send_messageLinkedIn: Send messageA
Destructive
Inspect

Send a message in an EXISTING LinkedIn chat. Requires chat_id, normally obtained from linkedin_list_conversations. Use only when the user has clearly asked to send/approved the final text.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
chat_idYesExact chat/conversation ID returned by conversation/inbox listing. Never pass a person name or provider user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, destructiveHint=true), the description adds the critical behavioral safeguard that the user must have clearly asked or approved the final text. This is a meaningful behavioral guideline not present in structured data, ensuring the agent understands this is a real-world, consent-required action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each with a distinct purpose: core action, prerequisite, and approval condition. The description is front-loaded with the primary action and contains no filler, making it quick for an agent to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 3-parameter tool with annotations and no output schema, the description covers the essential context: what the tool does, how to obtain the required chat_id, and the approval requirement. It doesn't describe the return value, but that's not necessary given the absence of an output schema and the simplicity of the action.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds value by specifying that chat_id normally comes from linkedin_list_conversations, supplementing the already detailed schema description for chat_id. The phrase 'final text' also gives a slight hint about the text parameter's role. With 67% schema coverage, this partial compensation is adequate, though text itself could use more explicit semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Send a message') on a specific resource ('an EXISTING LinkedIn chat'), and the 'EXISTING' qualifier clearly distinguishes it from conversation-starting siblings like linkedin_start_conversation. It also names the prerequisite chat_id and its typical source, leaving no ambiguity about what this tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an explicit when-to-use condition: 'Use only when the user has clearly asked to send/approved the final text.' It also instructs that chat_id is normally obtained from linkedin_list_conversations, giving a clear workflow. It does not explicitly name alternatives or exclusions, but the 'EXISTING' constraint implicitly steers away from new-chat tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_start_conversationLinkedIn: Start conversationA
Destructive
Inspect

Start a new LinkedIn conversation and send a message. Requires the stable LinkedIn provider user_id. IMPORTANT: if the user gives a LinkedIn URL, name or search criteria, first call linkedin_get_profile or linkedin_search_people, extract the returned user id, then call this tool. Do not put a LinkedIn URL into linkedin_user_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
inbox_idNoLinkedIn inbox to start from (default CLASSIC_PRIMARY). Use a Sales Navigator/Recruiter inbox ID from linkedin_list_inboxes for InMail-style messages.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
linkedin_user_idYesStable provider user id resolved by linkedin_get_profile/search_people; not a linkedin.com URL.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry readOnlyHint=false, destructiveHint=true, and idempotentHint=false, so the mutation profile is known. The description adds a useful input precondition and URL warning, but it does not disclose additional side effects such as InMail credit usage, irreversibility, or conversation creation behavior beyond what the annotations imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: purpose first, then the critical precondition, then the warning. Every sentence earns its place without filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The workflow for resolving user IDs is complete and the schema fills in account and inbox behavior. It lacks an explicit return-value note since there is no output schema, and it does not route around sibling messaging tools, but the invocation path is otherwise well covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75%, so the schema already documents linkedin_user_id, inbox_id, and account_id in detail. The description reinforces the linkedin_user_id resolution rule, but it adds nothing about the text parameter, which has no schema description, and no new semantics for inbox_id or account_id beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Start a new LinkedIn conversation and send a message') and a clear resource, so an agent can tell it is a messaging mutation tool. It doesn't explicitly contrast with siblings like linkedin_send_message or linkedin_start_conversation_from_inbox, so sibling differentiation is incomplete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit workflow: if the user provides a URL, name, or search criteria, first call linkedin_get_profile or linkedin_search_people, extract the user id, then call this tool, and never pass a URL to linkedin_user_id. It does not say when to prefer linkedin_send_message or linkedin_start_conversation_from_inbox, so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_start_conversation_from_inboxLinkedIn: Start conversation from inboxA
Destructive
Inspect

Start a LinkedIn Classic, Sales Navigator or Recruiter conversation from an explicit inbox. Resolve recipient user IDs first and obtain inbox_id with linkedin_list_inboxes. For Sales Navigator include the required subject in specifics; Recruiter may require subject and signature. Supports one-to-one or group recipients and attachments.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
textYes
inbox_idYesExact LinkedIn inbox ID returned by linkedin_list_inboxes. Preserve Classic/Sales Navigator/Recruiter selection; never pass contract_id or product name. Inbox ID: Provider inbox/product inbox identifier. LinkedIn Classic may use CLASSIC; premium products expose their own inbox IDs. Obtain with: linkedin_list_inboxes -> inbox.id Never pass: contract_id unless returned as the inbox id, guessing SALES_NAVIGATOR or RECRUITER.
specificsNo
users_idsYesOne exact provider user ID for a direct chat, or exact provider user IDs for a group; resolve every recipient first.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
attachmentsNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a mutating, destructive operation, so the description does not need to restate that. It adds value by disclosing that Sales Navigator and Recruiter have specific subject/signature requirements, which is behavioral context beyond the annotation flags. No contradiction with annotations is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff. It front-loads the core purpose and packs in the key operational steps (resolve users, get inbox) and product-specific nuances efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 7 parameters, nested objects, and no output schema, the description is relatively brief. It covers the main flow but omits details on return values, error conditions, or the semantics of optional parameters like 'name' and 'attachments.' It provides a functional overview but not complete coverage for an agent to use all parameters confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is low (43%), and the description partially compensates by explaining that inbox_id comes from linkedin_list_inboxes and users_ids must be resolved. It also mentions specifics for subject/signature. However, it does not clarify the 'text' or 'name' parameters, nor does it detail the attachments structure, leaving gaps given the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Start') and resource ('conversation') with the key qualifier 'from an explicit inbox,' which distinguishes it from sibling tools like linkedin_start_conversation. It also mentions the supported product types (Classic, Sales Navigator, Recruiter) and capabilities (one-to-one, group, attachments), making the purpose immediately clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit prerequisites: resolve recipient user IDs and obtain inbox_id via linkedin_list_inboxes. It also gives product-specific guidance (Sales Navigator requires subject, Recruiter may require subject and signature). However, it does not explicitly contrast with linkedin_start_conversation or state when to use this tool instead, so it lacks a clear exclusion clause.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_submit_company_member_otpLinkedIn: Submit company member OTPAInspect

Complete LinkedIn company-member verification. Reuse the same email and exact challenge_id returned by linkedin_verify_company_member_email, and submit only the real user-provided code; never invent or loop over codes.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesActual verification code received by the user. Never invent.
emailYes
productYesclassic
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
company_idYesExact LinkedIn company ID from company search/profile resolution; never use company name or slug unless a resolver explicitly converts it.
challenge_idYesExact challenge_id returned by linkedin_verify_company_member_email.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With only generic annotations available, the description adds valuable behavioral guardrails: the submission must be bound to the prior challenge_id/email, and code guessing or looping is disallowed. This is especially important because the annotations already mark the operation as non-read-only and non-idempotent. The description does not disclose error/retry behavior, but it provides the most critical behavioral constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense sentence that front-loads the purpose and then lists the two most important constraints. Every clause earns its place, and there is no filler or repetition of obvious information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter verification-completion tool with no output schema, the description plus parameter schema covers the essential calling contract: required fields, the source of challenge_id, and the prohibition on guessing codes. The main gap is the lack of response/error semantics, but the invocation guidance is otherwise sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool description adds cross-parameter semantics beyond the schema: email must be the same email used before, challenge_id must be the exact value returned by the prior tool, and code must be the real user-provided value. This is operationally important and not fully inferable from individual schema fields. The unmentioned product and account_id parameters are already reasonably documented by the enum, default value, and account_id description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Complete LinkedIn company-member verification', which names a specific verb and resource. The title explicitly says 'Submit company member OTP', and the workflow relationship to linkedin_verify_company_member_email is clear, so the agent can distinguish this tool from its sibling without deeper inspection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the precondition and sequence explicit: reuse the same email and exact challenge_id from linkedin_verify_company_member_email. It also gives a clear anti-pattern: never invent or loop over codes. It does not explicitly state when not to use this tool versus an alternative, but the two-step workflow dependency is strong enough to guide correct use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_unfollow_userLinkedIn: Unfollow userAInspect

Unfollow a LinkedIn user from the connected account. Resolve the exact provider user_id first.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idYesExact provider user ID returned by the relevant profile/contact resolver; never a display name or profile URL. For LinkedIn, use the stable system ID. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is not read-only, not idempotent, and not destructive. The description adds context by noting the action happens on the connected account and requires a prior resolution step. It does not disclose side effects or edge cases, but the annotation coverage carries much of the burden and the description is consistent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary action is front-loaded, and the only added sentence gives an actionable prerequisite. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple action with a fully described schema, the description plus parameter documentation is nearly complete. It covers the necessary resolution step and account context. The only minor omission is explicit guidance about expected outcomes or failure behavior, but that is not critical for this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema itself fully documents both user_id and account_id. The description contributes little beyond the instruction to resolve the provider user_id first, but the schema already provides rich detail on how to obtain it and what to never pass. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Unfollow a LinkedIn user from the connected account.' It clearly distinguishes the action from the sibling follow tool and makes the core operation immediately understandable. The added instruction to resolve the exact provider user_id also sharpens the purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear prerequisite: 'Resolve the exact provider user_id first.' However, it does not state when to use this tool versus alternatives such as linkedin_remove_connection or linkedin_follow_user, nor does it explain under what conditions unfollowing is appropriate. The guidance is useful but incomplete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_update_my_profileLinkedIn: Update my profileAInspect

Update supported fields of the user's own LinkedIn profile. Only pass fields explicitly requested by the user; provider support varies by field.

ParametersJSON Schema
NameRequiredDescriptionDefault
summaryNo
headlineNo
locationNo
last_nameNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
first_nameNo

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a non-read-only mutation (readOnlyHint=false). The description adds value by warning that provider support varies by field and instructing to pass only explicitly requested fields, which are behavioral nuances not present in annotations. It does not cover side effects or return behavior, but given the annotation coverage, this is a strong addition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, and contains no filler. Every clause adds useful information: the action, the target, the field-passing rule, and the provider variation caveat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description does not mention what the tool returns (e.g., updated profile vs. success status) or handle edge cases like partial field support failures. The 'provider support varies' caveat hints at inconsistency but does not explain fallback behavior. It is adequate for basic selection but leaves some operational gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is only 17% (only account_id is described), and the description does not compensate. It refers generically to 'supported fields' but does not explain the meaning or expected format of summary, headline, location, last_name, or first_name. With six parameters and low schema coverage, the description leaves the agent without enough parameter-level semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Update') and the resource ('supported fields of the user's own LinkedIn profile'), which distinguishes it from read-only tools like linkedin_get_my_profile and other update tools. It is specific and unambiguous, though it does not name sibling tools to further differentiate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an important usage rule ('Only pass fields explicitly requested by the user') and notes provider support variability, which helps an agent decide what to send. However, it does not explicitly state when to prefer this tool over alternatives or when not to use it, so the guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_verify_company_member_emailLinkedIn: Verify company member emailAInspect

Start LinkedIn company-member identity verification when a job/company action fails with insufficient permissions. Resolve company_id first and submit the actual verification email. Preserve the returned challenge_id for linkedin_submit_company_member_otp.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYesEmail address to submit for company-member verification.
productYesclassic
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
company_idYesExact LinkedIn company ID from company search/profile resolution; never use company name or slug unless a resolver explicitly converts it.

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=false, confirming this is a mutation. The description adds the workflow detail of resolving company_id first and submitting the email, as well as preserving the challenge_id. However, it doesn't disclose potential side effects like sending an email to the user or requiring specific account permissions. With openWorldHint=true, providing more behavioral context (e.g., that this triggers an email) would be beneficial. The description is not contradictory but could be more transparent about the external effect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, three sentences, and front-loads the purpose and trigger. It efficiently packs critical instructions without fluff. However, it could be slightly more structured by separating the 'when' from the 'how', but it's already quite good. Minor deduction for density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (verification flow) and no output schema, the description adequately covers the essential steps, prerequisites (resolve company_id), and handoff to the next tool. It doesn't mention what happens after success (you'll receive a challenge_id) but that's implied by preserving it. The lack of response format is mitigated by the explicit instruction to preserve challenge_id. Overall, quite complete for an agent to execute correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%, covering company_id, email, and account_id. The description adds crucial guidance for account_id (omit when one account, list when several, never guess) and company_id (use exact ID, never name/slug). This goes beyond basic schema descriptions. The product parameter is well-defined by enum. The description compensates well for the uncovered parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool starts LinkedIn company-member identity verification when a job/company action fails with insufficient permissions. It specifies the action, resource, and condition for use, effectively distinguishing it from sibling tools like linkedin_submit_company_member_otp which continues the flow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool: when a job/company action fails with insufficient permissions. It also gives a clear workflow instruction: resolve company_id first, submit the verification email, and preserve the challenge_id for the next step (linkedin_submit_company_member_otp). This provides strong context and sequencing, though it doesn't mention when not to use it against all other Linkedin tools, but the trigger condition is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_visit_profileLinkedIn: Visit profileAInspect

Report a LinkedIn profile visit using notify_visit_token returned by the resolved profile. The token is provider-issued and must not be replaced with user_id, profile URL or public identifier.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
notify_visit_tokenYesExact notify_visit_token returned by linkedin_get_profile_from_url/linkedin_get_profile for the profile being visited; never invent it.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate the tool is not read-only (readOnlyHint=false) and has external side effects (openWorldHint=true). The description adds the provider-issued token constraint but does not elaborate on the side effects of 'reporting' a visit (e.g., notifications, rate limits, or data persistence). It does not contradict annotations, but it adds limited behavioral context beyond them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose and the critical token constraint. Every word earns its place; no filler or repetition. It is highly concise and well-structured for quick parsing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with no output schema, the description is largely complete. It covers the essential purpose, the token origin, and the primary pitfall. It does not explain what happens on success or failure, but given the tool's simplicity and the rich schema descriptions, this is not a critical gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with both parameters well-described. The tool description adds a crucial semantic warning: the notify_visit_token must be the exact token from a resolved profile and must not be replaced with other identifiers. This goes beyond the schema's basic description and helps prevent misuse.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Report a LinkedIn profile visit' using a specific token. It identifies the resource (LinkedIn profile visit) and the required input (notify_visit_token), distinguishing it from profile-fetching siblings by emphasizing the token from a resolved profile. It avoids ambiguity and effectively sets it apart from tools like linkedin_get_profile.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool: after a profile has been resolved and a notify_visit_token is available. It explicitly warns against substituting user_id, profile URL, or public identifier, which is a key usage constraint. However, it does not name alternative tools or provide explicit 'when not to use' guidance, leaving the context slightly implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_connected_accountsConnected accountsA
Read-onlyIdempotent
Inspect

List the user's own accounts connected to Nilyo with provider, owner display name, identifier (LinkedIn public id, phone, email), connection status and reconnection hints. Use when the user asks what is connected, when several accounts of one provider exist and the user names one ("with Julia's LinkedIn"), or after a choose_account result. Nilyo never guesses between accounts: pick the entry matching what the user said and pass its unipile_account_id as account_id to the action tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerNoOptional provider filter such as linkedin, whatsapp, instagram, google, outlook or imap.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: it lists the fields returned and communicates the 'never guesses between accounts' policy, which helps an agent know how to map results to downstream actions. It doesn't detail pagination or limits, but those are not critical for this read-only list tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states the purpose and output content, the second gives concrete usage conditions, and the third provides the critical selection rule. Every sentence earns its place and no words are wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-optional-parameter, read-only list tool, this description is complete. It tells the agent what is returned, when to call it, and how to use the results (identify the matching account and pass unipile_account_id to the action tool). No output schema exists, but the description compensates by naming the key fields. There is no important missing context for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with the single optional provider parameter already described as 'Optional provider filter such as linkedin, whatsapp, instagram, google, outlook or imap.' The description adds no additional parameter-level semantics beyond mentioning 'provider' in the output list, so the schema carries the burden. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('the user's own accounts connected to Nilyo') and enumerates the returned attributes (provider, owner display name, identifier, connection status, reconnection hints). It clearly differentiates from related account tools by focusing on listing the user's own connected accounts rather than connecting, changing plans, or checking status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit usage guidance is provided: use when the user asks what is connected, when multiple accounts of one provider exist and the user names one, or after a choose_account result. It also gives a strong behavioral rule: never guess between accounts, match the user's description and pass the unipile_account_id to the action tool. This is model-level routing guidance, not just a generic statement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_add_reactionMessage: Add reactionA
Destructive
Inspect

Add an emoji reaction to one exact WhatsApp, Instagram, Telegram or LinkedIn message (e.g. 👍, ❤️). Resolve chat/message first; keep chat_id + message_id paired. Use message_remove_reaction to withdraw it. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
reactionYesEmoji to react with, e.g. 👍.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the description is not burdened to repeat those. The description adds context about pairing IDs for mutation tools and mentions the removal method, but does not detail side effects like notification changes or permanence beyond the removal option. It adds modest value without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is somewhat long but well-organized, with clear sections for Chat ID and Message ID. It front-loads the purpose and then provides necessary ID-resolution details. Some repetition exists between the description and schema text, but the structure is efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 4 parameters and no output schema, the description covers how to obtain IDs, keep them paired, and what not to pass. It also names the removal alternative. Missing details like error handling or rate limits are not critical for correct invocation. The description is sufficient for an agent to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents each parameter. However, the description adds actionable retrieval guidance (e.g., 'Obtain with: provider list conversations/inbox chats -> chat.id') and warns against passing certain values, which goes beyond the schema's bare 'Exact chat/conversation ID' phrasing. This is meaningful added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Add an emoji reaction to one exact WhatsApp, Instagram, Telegram or LinkedIn message'. It also names the sibling tool message_remove_reaction for withdrawal, distinguishing this tool from the removal counterpart. No ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs to resolve chat/message first and keep chat_id + message_id paired, and names message_remove_reaction as the alternative for withdrawal. It also provides clear 'Never pass' guidance for each parameter, giving the agent concrete rules for correct usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_deleteMessage: DeleteA
Destructive
Inspect

Delete one exact message. Resolve and verify chat/message first; destructive. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the description adds value beyond those. It warns to 'Resolve and verify chat/message first', explains the uniqueness constraint (providers may only guarantee uniqueness inside a chat, so keep chat_id with message_id), and gives concrete sources for the IDs. It also explicitly lists 'Never pass' items, which prevents common errors. This is useful behavioral context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose ('Delete one exact message') and then gives a caution. However, it repeats the same 'Never pass' directives both in the main description and again inside the parameter descriptions, and the phrasing is somewhat redundant (e.g., 'Resolve and verify' and later 'In V2 always keep chat_id together'). While not excessively long, it could be tightened by removing duplicated guidance without losing substance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool with 3 parameters (2 required) and no output schema, the description provides thorough guidance: it explains how to obtain both IDs, the importance of pairing chat_id and message_id, and what not to pass. It also warns about the destructive nature. The only minor gap is that it does not describe the expected response (e.g., success/failure) or any post-deletion effects, but since there is no output schema and the task is straightforward, this is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%: the schema descriptions for chat_id and message_id already contain the full text about how to obtain them, the uniqueness note, and the 'Never pass' lists. The tool description essentially repeats this content, adding no new meaning beyond what the schema already provides. The account_id parameter is described only in the schema, and the description does not comment on it. Thus the description adds marginal value over the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Delete one exact message.' It clearly states the action and the target (a message), and emphasizes precision ('exact') which distinguishes it from fuzzy or batch deletes. The warning 'Resolve and verify chat/message first; destructive' reinforces the specific scope. While it doesn't compare itself to siblings, the unique action (delete vs. edit, forward, react) is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: you delete a message after resolving and verifying the chat and message IDs, and it warns that deletion is destructive. It provides explicit instructions on how to obtain the correct IDs (via list conversations and read messages) and what not to pass. However, it does not explicitly name alternative tools or describe when not to use this tool (e.g., when you might want to edit rather than delete). The guidance is strong for execution but lacks explicit rutting vs. siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_editMessage: EditAInspect

Edit one previously sent message where supported. Recommended chain: resolve chat -> list messages -> message_get -> edit. Keep exact chat_id + message_id pair. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesFinal replacement message text explicitly requested/approved by the user.
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a mutation (readOnlyHint=false) and non-idempotent behavior. The description adds the 'where supported' caveat and the requirement to keep chat_id+message_id paired, which are useful behavioral constraints. However, it doesn't disclose potential side effects like edit time limits or failure modes, and much of the text repeats schema parameter descriptions rather than providing deep behavioral insight.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is verbose and repetitive. The Chat ID and Message ID sections largely duplicate the schema parameter descriptions, and the two paragraphs repeat similar warnings. The first sentence and recommended chain are useful, but the rest could be condensed significantly. It is not front-loaded beyond the initial purpose, and the lengthy explanations hurt clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has no output schema and is a mutation. The description covers how to obtain IDs and the recommended chain, but it doesn't explain what the tool returns, what happens on failure, or any limitations like edit windows or irreversible effects. Given the openWorldHint and mutation nature, this is incomplete for an agent to understand the full effect of calling the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds extra guidance on how to obtain chat_id and message_id, and explicitly states 'Never pass: person name, user_id, message_id' for chat_id and 'Never pass: message text, chat_id, message ID without its chat context' for message_id. This goes beyond the schema by clarifying common mistakes and provenance, earning a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Edit one previously sent message where supported.' This is a specific verb+resource and distinguishes it from siblings like message_delete or message_forward. It also notes 'where supported' to indicate provider limitations, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a recommended chain: 'resolve chat -> list messages -> message_get -> edit,' which tells the agent when to use this tool. It also emphasizes keeping the chat_id+message_id pair and warns against passing person names or user_ids. However, it doesn't explicitly state when not to use this tool or name alternatives like message_forward or message_delete, so it's not fully explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_forwardMessage: ForwardA
Destructive
Inspect

Forward an existing message to another EXISTING chat. Resolve source chat + message and destination chat independently. target_chat_id is a chat ID, never recipient user_id/name. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.
target_chat_idYesExact destination chat ID from message_resolve_chat/list conversations. Never pass a person name/user_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a destructive, non-read-only mutation, and the description adds behavioral context by emphasizing the 'EXISTING chat' requirement and that providers may only guarantee message-ID uniqueness within a chat, so chat_id must be kept paired with message_id. This goes beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The top-level description is heavily redundant with the parameter descriptions, repeating the same Chat ID and Message ID paragraphs almost verbatim. While the front-loaded opening sentence is strong, the repetition across description and schema bloats the definition and makes it less scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers the essential invocation concerns: where to get chat/message IDs, how to pair them, and what values to avoid. It is sufficiently complete for an agent to resolve and pass the three required parameters correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds meaningful guidance beyond the schema: it explicitly forbids passing user names/user_ids for chat parameters, requires chat_id/message_id pairing, and instructs where to obtain IDs. This real-world resolution guidance is valuable for an agent selecting correct parameter values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Forward an existing message to another EXISTING chat,' naming the specific verb, resource, and the key constraint that both source and destination chats must already exist. It further disambiguates from sibling messaging tools by stressing that target_chat_id is a chat ID, never a recipient user_id/name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context is provided: resolve source chat/message and destination chat independently, and obtain IDs from conversation/message listing resolvers. It warns against passing person names, user_ids, or bare message IDs, but it does not explicitly name alternative tools like messaging_send_message or linkedin_send_message for when forwarding is not appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_getMessage: GetA
Read-onlyIdempotent
Inspect

Get one exact message. BOTH chat_id and message_id are required because V2 message identity is contextual to its chat. If starting from a person/topic, resolve chat first, list messages, then reuse both IDs. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint, idempotentHint, and non-destructive behavior. The description adds valuable context about V2 message identity being contextual to the chat and provider uniqueness guarantees, plus explicit anti-patterns like 'Never pass: person name, user_id, message_id.' It does not mention return format, but this is a read operation whose safety profile is already covered by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is excellent and front-loaded, but the rest is verbose and somewhat repetitive: 'Exact provider chat/conversation ID' and 'Exact message id inside a specific chat' are duplicated from the schema, and the tail about 'for mutation tools' is tangential to a get operation. Labeled Chat ID and Message ID sections help structure, but several sentences could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description gives complete ID-provenance guidance, a resolution workflow, and safety annotations, so an agent can invoke the tool correctly. It lacks an explicit statement of what the response contains and relies partly on schema text for account_id guidance, but this is a minor gap for a straightforward get operation with no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaningful parameter semantics beyond the schema by explaining how to obtain the IDs, why chat_id and message_id must stay paired, and what values must never be passed. It does not cover account_id in the main description, but the schema fully documents that parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Get one exact message,' a specific verb and resource, and immediately clarifies the singular scope. It differentiates from message listing and mutation siblings by emphasizing that both chat_id and message_id are required and context-bound.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit workflow guidance: 'If starting from a person/topic, resolve chat first, list messages, then reuse both IDs.' It also tells the agent how to obtain each ID from provider listings and what never to pass, though it does not explicitly name alternative sibling tools to prefer in other situations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_list_reactionsMessage: List reactionsA
Read-onlyIdempotent
Inspect

List detailed reactions on one exact message. Preserve its chat_id + message_id pair. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description's 'List' matches those hints. The description adds a useful data-model caveat about chat-scoped ID uniqueness, but it does not disclose other behavioral traits such as pagination or ordering. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is a crisp purpose statement, but the subsequent Chat ID and Message ID paragraphs duplicate the schema descriptions nearly verbatim. The 'Never pass' guidance is repeated and even includes a mutation-tool caveat that is irrelevant to this read-only lister. The content is structured, but it could be tightened significantly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides the full ID acquisition chain and the chat-scoped uniqueness warning, so an agent knows exactly which parameters are required and how to obtain them. The absence of an output schema means the return shape is not described, but for a simple read-only list operation this is a minor gap given the strong annotations and parameter guidance.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both required parameters fully documented. The tool description mostly restates the schema's parameter text rather than adding new semantic detail, and account_id is documented only in the schema. Baseline 3 is appropriate because the schema already carries the parameter-semantics burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence 'List detailed reactions on one exact message' names the action, resource, and scope precisely. The read-only verb distinguishes it from sibling mutation tools like message_add_reaction and message_remove_reaction without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the required chat_id + message_id pairing and explicitly warns 'In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat.' It also tells the agent where to obtain each ID and what never to pass. It does not explicitly name an alternative tool, but the context is sufficient to avoid misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_mark_readMessage: Mark readAInspect

Mark one exact message read. Resolve chat_id then message_id; do not pass person/user ID as chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=false, idempotentHint=false, destructiveHint=false, and openWorldHint=true, so the safety profile is mostly established. The description adds some behavioral context by labeling this as a mutation tool and warning that providers may only guarantee message uniqueness inside a chat, but it does not address side effects, rate limits, or auth requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with a clear purpose and is organized into Chat ID and Message ID sections, but it is verbose and largely duplicates the schema property descriptions. Phrases like 'Never pass: person name, user_id, message_id' and 'Never pass: message text, chat_id, message ID without its chat context' are repetitive and could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple state-changing tool, the description covers the key complexity: how to obtain and pair chat_id and message_id, and common mistakes to avoid. It does not explain the return value or broader side effects, but the annotations supply the safety and mutability signals, making this adequate for a correctly scoped call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds a useful resolution order ('Resolve chat_id then message_id') and reinforces the exact-ID requirement with explicit 'never pass' examples. It does repeat much of what is in the schema, but the added workflow guidance helps the agent call the tool correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence, 'Mark one exact message read,' names a specific verb, resource, and scope, and the emphasis on 'exact' distinguishes it from bulk operations or unread-marking. Provider-related examples and 'chat/conversation ID' further clarify it is for chat messages rather than email, despite email_mark_read existing among siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear guidance on how to call the tool: resolve chat_id first, then message_id, and never pass person/user IDs as chat_id. It also tells the agent where to obtain valid IDs. It does not explicitly name alternatives or exclusions, but the context is detailed enough to avoid the most common misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_remove_reactionMessage: Remove reactionA
Destructive
Inspect

Remove the user's reaction from one exact message. Resolve chat/message first. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID from a conversation/chat listing or resolver. A person name/user_id is NOT a chat_id. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
reactionYesThe emoji/reaction to remove (the same value that was added, e.g. 👍); list reactions first when unknown.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
message_idYesExact message ID returned inside the specified chat. Keep it paired with chat_id for all V2 message mutations/reactions. Message ID: Exact message id inside a specific chat. In V2 always keep chat_id together with message_id because providers may only guarantee uniqueness inside the chat. Obtain with: provider read/list conversation messages -> message.id Never pass: message text, chat_id, message ID without its chat context for mutation tools.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, and the description adds useful operational context: providers may only guarantee message uniqueness inside a chat, and certain values must never be passed. It does not describe effects like what happens if the reaction is absent, but the annotation safety profile lowers the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is verbose and repetitive: the Chat ID and Message ID blocks follow the same 'Obtain with... Never pass...' pattern and are duplicated verbatim in the schema parameter descriptions. The opening sentence is clear, but the overall length is disproportionate to the tool's simple purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description covers the critical knowledge an agent needs: how to resolve and pair chat_id/message_id, provider-specific caveats, and explicit negative examples. The account_id disambiguation lives in the schema and is well handled there. Minor gaps like the effect of removing a non-existent reaction are negligible.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The main description mostly duplicates the schema text for chat_id and message_id rather than adding new meaning; reaction and account_id are only documented in the schema. No significant parameter clarification is added beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb, resource, and scope: 'Remove the user's reaction from one exact message.' This cleanly differentiates it from siblings like message_add_reaction, message_list_reactions, and social_remove_post_reaction. No ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit resolution steps ('Resolve chat/message first') and precise provenance for IDs ('Obtain with: provider list conversations/inbox chats -> chat.id'). It does not explicitly name alternatives or state when-not-to-use, but the context is strong enough for an agent to apply it correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_resolve_chatMessage: Resolve chatA
Read-onlyIdempotent
Inspect

List/search conversations so a human recipient/topic can be mapped to exact chat_id before reading/replying or resolving message_id. Do not use a person name as chat_id. For LinkedIn use linkedin_list_inboxes then linkedin_list_inbox_chats because account-wide chat listing is not supported. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo
providerYes
is_unreadNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: the LinkedIn limitation, the exact workflow for obtaining chat IDs, and the invalid-value caveats.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main purpose is front-loaded and the LinkedIn workflow is compactly stated. Minor redundancy exists between 'Do not use a person name as chat_id' and the final 'Never pass: person name, user_id, message_id.'

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With five parameters and no output schema, the description gives the main purpose and caveats but omits pagination/filter semantics and the expected return shape beyond 'chat.id'. It is minimally viable for a read-only lookup, but not fully complete for an agent to call it confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20%, but the description does not explain limit, cursor, or is_unread; it focuses mostly on a chat_id concept that is not even an input property. The account_id guidance is already in the schema, and the provider enum is self-explanatory, so the description fails to compensate for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action and resource: 'List/search conversations' to map a recipient/topic to an exact chat_id. It also delineates the LinkedIn case by naming linkedin_list_inboxes and linkedin_list_inbox_chats, making it easy to distinguish from sibling resolver tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states when this tool is the right step ('before reading/replying or resolving message_id') and gives an explicit exclusion: for LinkedIn, use the two linkedin_list_* tools instead because account-wide chat listing is not supported. The negative guidance 'Do not use a person name as chat_id' and 'Never pass: person name, user_id, message_id' further clarifies correct use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_send_native_mediaMessage: Send native mediaA
Destructive
Inspect

Send one media/file attachment using the provider's native rendering mode where supported. Resolve chat_id first. Useful for inline image/video/native media; for WhatsApp multiple attachments may become separate provider messages, so this tool intentionally sends one attachment per call for predictable behavior.

ParametersJSON Schema
NameRequiredDescriptionDefault
textNo
chat_idYesExact chat.id resolved/listed for the destination conversation; never pass a person name/user_id here.
filenameYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
content_typeYes
content_base64Yes

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as non-read-only and destructive. The description adds behavioral value by explaining native rendering support caveats and the WhatsApp multi-attachment-to-separate-messages behavior, which is not visible in the schema or annotations. It could go further in specifying which providers support native rendering, but the added context is meaningful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the core action. The three sentences each add useful information, though 'native media' in the third sentence is somewhat redundant with the first sentence. Overall it is appropriately sized and readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose and a key provider-specific nuance, but it omits essential invocation details such as the format of content_base64, the role of content_type and filename, and what response or outcome to expect. With no output schema and low parameter coverage, these omissions leave the agent under-equipped for correct calls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, so the description must compensate, but it does not explain the key parameters content_base64, content_type, filename, or text. It only implies that these relate to a media/file attachment. The agent is left guessing about base64 encoding format, MIME type expectations, and whether text is a caption. This is a significant gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Send one media/file attachment using the provider's native rendering mode where supported.' This distinguishes it from text or voice messaging tools by emphasizing media, native rendering, and one-attachment-per-call behavior. However, it does not explicitly name or contrast any sibling tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful context: 'Resolve chat_id first' is a prerequisite, 'Useful for inline image/video/native media' identifies a use case, and the WhatsApp note explains when and why to prefer this tool for predictable one-attachment behavior. It does not explicitly mention alternatives or state when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

message_send_voice_noteMessage: Send voice noteA
Destructive
Inspect

Send an audio attachment as a native/playable voice note where the connected provider supports it (notably WhatsApp/Telegram). Resolve chat_id first. Provide base64 content + exact MIME type/filename. Do not send the same voice note repeatedly after an uncertain timeout; read chat state first.

ParametersJSON Schema
NameRequiredDescriptionDefault
textNoOptional caption/text only when supported/requested.
chat_idYesExact chat.id resolved/listed for the destination conversation; never pass a person name/user_id here.
filenameYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
content_typeYesAudio MIME type. WhatsApp voice notes expect Opus in OGG: audio/ogg (codecs=opus); MP3 is sent as a regular audio file.
content_base64YesBase64-encoded audio bytes, not a URL/path.
duration_secondsNoDuration of the audio in seconds when known (shown by the provider on the voice note).

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false. The description adds a specific caution: 'Do not send the same voice note repeatedly after an uncertain timeout; read chat state first', which is valuable operational guidance beyond the structured hints and does not contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loads the main purpose, and includes the key operational caveat without any filler. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It covers the essential usage points: provider support, prerequisite of resolving chat_id, content format, and duplicate-avoidance. It could benefit from explicitly contrasting with message_send_native_media or other senders, but the description is sufficiently self-contained for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 86% (6/7 params have descriptions). The description reiterates 'base64 content + exact MIME type/filename' but adds little beyond schema. It adds a note about resolving chat_id, which is already in the schema. The description does not compensate for the one undocumented parameter (duration_seconds is described in schema, so actually 100%? Wait, duration_seconds has a description, so coverage is actually 100%? The signal says 86% but all properties have descriptions? Let's re-check: text, chat_id, filename, account_id, content_type, content_base64, duration_seconds all have descriptions. So coverage is 100%? But signal says 86% maybe because text is optional? Anyway, schema covers all. So description adds marginal value, baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Send an audio attachment as a native/playable voice note', and immediately specifies provider support (WhatsApp/Telegram). This clearly distinguishes it from generic send tools like messaging_send_message or message_send_native_media.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage conditions: 'where the connected provider supports it', and prerequisites: 'Resolve chat_id first', 'Provide base64 content + exact MIME type/filename', and 'read chat state first'. It does not name alternative tools for when not to use it, but the provider-support caveat is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_find_chat_by_userMessaging: Find chat by userA
Read-onlyIdempotent
Inspect

Find the existing one-to-one chat for a known LinkedIn, WhatsApp, Instagram or Telegram provider user ID. Use after resolving the user; user_id is not chat_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idYesExact provider user ID returned by a profile/contact resolver; never a name or profile URL.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the behavioral nuance that user_id is distinct from chat_id, which is valuable context for correct invocation. It does not describe return format or absence behavior, but the annotations carry the heavy lifting.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero waste. The primary purpose is front-loaded, followed by a usage hint and a key clarification. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only lookup with 2 parameters and no output schema, the description is adequately complete. It gives the intended use, the input prerequisite, and a critical distinction. It does not mention what happens when no chat is found, but given the openWorldHint and the simplicity of the operation, this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters are well documented in the schema, so the description adds minimal value. The only addition is the explicit clarification that user_id is not chat_id, which is a useful but minor supplement to the schema's already-detailed description of user_id.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Find') with a clear resource ('existing one-to-one chat') and scope ('for a known provider user ID'). It also differentiates from related tools by focusing on finding an existing chat rather than listing or creating one, and explicitly warns 'user_id is not chat_id' to avoid confusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: 'Use after resolving the user' sets a prerequisite, and the warning about user_id vs chat_id helps avoid a common mistake. It implies when to use this tool (after user resolution) but does not explicitly name alternatives or exclusions, though the context is sufficient for an agent to infer its role among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_list_chatsMessaging: List chatsA
Read-onlyIdempotent
Inspect

List chats for WhatsApp, Instagram or Telegram. Exposes V2 pagination and filters: type, before/after, archived and unread. LinkedIn requires inbox-specific listing.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNo
afterNo
limitNo
beforeNo
cursorNo
offsetNo
providerYes
is_unreadNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
is_archivedNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds meaningful behavioral context: it mentions 'V2 pagination' and the available filters (type, before/after, archived, unread), and notes the LinkedIn exception. It does not contradict annotations and provides useful operational details beyond what annotations supply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundancy. The core purpose is front-loaded, followed by a compact list of capabilities and a crucial exception. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list operation with 10 parameters and no output schema, the description covers the key aspects: provider scope, filters, pagination version, and the LinkedIn exclusion. The account_id parameter has its own schema description, so that is covered. It does not explain the return structure, but that is less critical for a list operation where the agent can infer a list of chats. Overall, it provides sufficient guidance for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 10% (only account_id has a description), so the description must compensate. It explicitly lists the filter parameters (type, before/after, archived, unread) and mentions 'V2 pagination', which gives semantic meaning to cursor/limit/offset. However, it does not elaborate on the pagination parameters individually or explain the difference between cursor and offset, leaving some nuance unaddressed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('chats') with an explicit provider scope ('WhatsApp, Instagram or Telegram'). It also differentiates from LinkedIn by noting the alternative requirement, making it clear that this tool is not for LinkedIn. This distinguishes it from the many sibling chat tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear 'when not to use' by stating LinkedIn requires inbox-specific listing, which routes the agent to LinkedIn-specific tools like linkedin_list_inbox_chats. It also implies when to use it (for the three named providers), but it does not explicitly compare to provider-specific list tools like whatsapp_list_conversations or instagram_list_conversations, leaving some ambiguity about which to prefer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_list_messagesMessaging: List messagesA
Read-onlyIdempotent
Inspect

List messages in a known chat with full V2 filters/pagination. Message IDs are scoped to their chat: keep chat_id for any later get/edit/delete/forward/reaction action.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNo
limitNo
beforeNo
cursorNo
offsetNo
chat_idYesExact chat/conversation ID from the appropriate chat/inbox listing or resolver. Never pass a person name or user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
user_idNoExact provider user ID returned by the relevant profile/contact resolver; never a display name or profile URL. For LinkedIn, use the stable system ID. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, covering safety. The description adds a valuable behavioral caveat: message IDs are scoped to their chat and chat_id must be retained for subsequent actions (get/edit/delete/forward/reaction). This goes beyond annotations and helps agents avoid misuse.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two efficient sentences with no redundancy. The first sentence front-loads the core purpose and scope; the second adds a critical usage caveat. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 8 parameters, no output schema, and low parameter coverage, the description is incomplete. It does not describe the return structure (e.g., list of messages with fields) or pagination behavior in detail. The scoping caveat is helpful, but the missing parameter semantics and return format leave significant gaps for an agent to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 38% (3 of 8 parameters have descriptions). The description does not compensate; it only mentions 'full V2 filters/pagination' without detailing after, before, cursor, offset, or limit. Parameters like cursor and offset remain undefined in both schema and description, leaving agents to guess their semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('messages') scoped to a known chat, with 'full V2 filters/pagination' indicating comprehensive functionality. Clearly distinguishes from siblings like messaging_list_chats (lists chats) and message_get (gets a single message), and from other providers' list tools via the 'messaging_' prefix.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage when you have a known chat_id ('in a known chat') but does not explicitly name alternatives or exclusions. An agent can infer it is the right tool for listing messages within a chat versus listing chats, but no direct comparison or when-not guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_resolve_recipientMessaging: Resolve recipientA
Read-onlyIdempotent
Inspect

Turn a person's name, nickname, phone number or handle into the exact WhatsApp/Instagram/Telegram recipient BEFORE sending: searches the user's 1-to-1 chats (ranked by most recent exchange) and contacts. Returns resolved (one clear match: send immediately with the recommended next tool, no extra confirmation needed when the user already gave the message), ambiguous (several people: ask which one, most recent conversation first) or not_found. Use for 'send a WhatsApp to Julien', 'reply to Marie on Instagram', 'message +33 6…'. Never pass a name as chat_id or user_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesHow the user refers to the person: first name, full name, phone number or handle.
providerYesMessaging provider named by the user. LinkedIn recipients use linkedin_resolve_person + linkedin_start_conversation instead.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Required when the user has several accounts for the provider: pick the one the user named.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and idempotentHint annotations, the description explains the search scope (1-to-1 chats ranked by recency, plus contacts) and the three return states (resolved, ambiguous, not_found) with specific follow-up actions for each. This adds significant behavioral context not available in annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place: first sentence defines purpose and scoping, second explains return behavior, third provides examples, fourth gives a caution. The information is dense but logically ordered and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully explains the return values (resolved, ambiguous, not_found) and their handling, the search ranking, and even the caveat about account_id. For a 3-parameter tool with no output schema, this is complete and actionable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains name, provider, and account_id. The description reinforces that name can be a nickname or phone number (already in schema) and warns against passing a name as an ID, but it adds no new parameter-level meaning beyond what the structured schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Turn a person's name... into the exact recipient') and resource (WhatsApp/Instagram/Telegram recipient), and clearly distinguishes it from siblings like messaging_find_chat_by_user by emphasizing resolution before sending. It even includes concrete example queries and a warning against misuse.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use examples ('send a WhatsApp to Julien', 'reply to Marie on Instagram', 'message +33 6…') and states it should be used BEFORE sending. It also warns against passing a name as chat_id or user_id, effectively directing the agent away from incorrect usage patterns.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_send_messageMessaging: Send messageA
Destructive
Inspect

Send a message in an existing LinkedIn, WhatsApp, Instagram or Telegram chat. Supports text, base64 file attachments and provider-specific options. Locate/read the chat first if chat_id is not already known. This is a real external send action.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
chat_idYesExact chat/conversation ID from the appropriate chat/inbox listing or resolver. Never pass a person name or user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
specificsNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
attachmentsNo

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal destructiveHint and openWorldHint, and the description reinforces this with 'This is a real external send action.' That is valuable plain-language confirmation, but it mostly paraphrases the annotations rather than adding new behavioral details like irreversibility, rate limits, or failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with no filler: action, capabilities, and prerequisite/side-effect are each clearly separated. The most important facts are front-loaded in the first sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a nested, side-effecting tool with no output schema, the description supplies the key selection facts and the chat-lookup prerequisite. It leaves nested attachment semantics and provider-specific option details largely to inference, making it adequate for selection but not fully complete for invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description names text, base64 file attachments, and provider-specific options, which loosely maps to the text, attachments, and specifics parameters. However, schema description coverage is only 40% and the description does not explain send_mode, voice_note, or how to structure provider-specific options, so it only partially compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb and resource: send a message in an existing chat, with the provider scope explicitly stated (LinkedIn, WhatsApp, Instagram, Telegram). The phrase 'existing chat' differentiates it from chat-starting tools, and the provider list distinguishes it from email and social tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs the agent to locate/read the chat first if chat_id is not already known, which is a clear precondition for correct use. It does not explicitly name alternatives like messaging_start_chat or provider-specific send_message tools, but the context strongly implies them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_send_to_contactMessaging: Send to contactA
Destructive
Inspect

One-step send for voice-style requests: 'send a WhatsApp to Julien saying I'm 10 minutes late'. Resolves the recipient like messaging_resolve_recipient and sends the text ONLY when exactly one person matches (existing conversation or contact). When several people match, nothing is sent and the candidates are returned so you can ask the user which one. The user must have stated the message content; do not invent it.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesHow the user refers to the recipient.
textYesExact message text the user asked to send.
providerYesMessaging provider named by the user. LinkedIn recipients use linkedin_resolve_person + linkedin_start_conversation instead.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Required when the user has several accounts for the provider: pick the one the user named.
recipient_user_idNoExact provider user ID chosen by the user after an ambiguous result; skips name matching.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=false, and openWorldHint=true. The description adds valuable behavioral context: it sends ONLY when exactly one person matches, returns candidates on ambiguity, and requires the user to have stated the message content (do not invent it). It also notes that account_id is required when the user has several accounts. This goes beyond the annotations and helps the agent understand the tool's safety and decision behavior. A 4 is appropriate because the description doesn't cover every edge case (e.g., what happens if no one matches), but it adds substantial context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with the primary use case and example, then the resolution behavior, then the safety constraint. Every sentence earns its place: the example clarifies the voice-style input, the ambiguity rule is critical for correct invocation, and the 'do not invent it' instruction prevents hallucination. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 5 parameters, 100% schema coverage, and no output schema, the description covers the key decision logic (single match vs. multiple matches), the provider routing, and the account_id requirement. It doesn't explicitly state what happens when zero people match, but the schema and annotations cover the rest. The description is complete enough for an agent to invoke it correctly in most cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all five parameters. The description adds meaning by explaining the resolution behavior tied to 'name' and 'recipient_user_id' (skips name matching), and the provider enum's LinkedIn exclusion. It also clarifies that 'text' must be the exact message the user asked to send. This is above the baseline 3 because the description enriches the parameters with behavioral context, though the schema already does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('send'), a resource ('voice-style requests'), and the exact behavior: resolves the recipient and sends only when exactly one person matches. It also distinguishes itself from messaging_resolve_recipient and messaging_send_message by describing the one-step combined flow. This is a clear, specific purpose that an agent can act on.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool: for one-step voice-style requests where the user has stated the message content. It also names the alternative messaging_resolve_recipient and explains the disambiguation behavior (when several people match, nothing is sent and candidates are returned). The provider enum also routes LinkedIn users to linkedin_resolve_person + linkedin_start_conversation, which is an explicit exclusion. This is strong usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_set_chat_stateMessaging: Set chat stateAInspect

Update supported chat state such as read/unread, archive/pin, label or mute metadata. Only send fields explicitly requested.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
labelNo
chat_idYesExact chat/conversation ID from the appropriate chat/inbox listing or resolver. Never pass a person name or user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
pin_statusNo
muted_untilNo
read_statusNoTrue marks the chat read; false marks it unread.
archive_statusNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, and openWorldHint=true. The description adds the instruction 'Only send fields explicitly requested,' which hints at partial-update behavior but does not disclose what happens to unspecified fields (e.g., whether they are left unchanged or reset). It also does not mention whether the operation is reversible or what side effects occur. The description does not contradict the annotations, but it adds only modest behavioral context beyond them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the core purpose and ends with a practical usage rule. It is concise and every clause earns its place. It could be slightly improved by naming an alternative tool, but as written it is efficient and clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 8 parameters, no output schema, and only 38% schema description coverage, so the description carries a heavy burden. It covers the main state categories and the partial-update rule, but it does not explain the 'name' parameter, the muted_until union type, or the behavior of unspecified fields. For a mutation tool with no output schema, an agent would likely need more detail to call it correctly in edge cases, though the chat_id guidance in the schema helps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 38%, so the description must compensate. The description names the state dimensions (read/unread, archive/pin, label, mute metadata) which maps to several parameters (read_status, archive_status, pin_status, label, muted_until). It also adds the key guidance 'Only send fields explicitly requested,' which clarifies that parameters are optional and partial updates are intended. However, it does not explain the meaning of 'name' or the boolean/string union for muted_until, so it does not fully compensate for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb ('Update') and resource ('supported chat state') and enumerates the state dimensions (read/unread, archive/pin, label, mute metadata). It is distinguishable from siblings like messaging_set_composing and messaging_set_presence, though it does not explicitly name them. The title 'Messaging: Set chat state' reinforces the purpose, so the description adds enough specificity to avoid confusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a partial usage rule: 'Only send fields explicitly requested.' This implies the tool is for updating only the fields the user asked for, which is useful guidance. However, it does not explicitly state when to use this tool versus alternatives like messaging_set_composing, messaging_set_presence, or email_mark_read, nor does it mention prerequisites like needing a valid chat_id. The guidance is implied rather than explicit, so it earns a 3.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_set_composingMessaging: Set composingAInspect

Publish a typing or voice-recording composing signal in a known chat where supported (LinkedIn Classic and WhatsApp). This is ephemeral provider state; use only when an agent workflow explicitly needs it.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYes
chat_idYesExact chat/conversation ID from the appropriate chat/inbox listing or resolver. Never pass a person name or user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=false (write), destructiveHint=false, and idempotentHint=false. The description adds that the signal is 'ephemeral provider state', which is a useful behavioral detail beyond the annotations, and implies no persistent effects. It does not contradict any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose and provider scope, followed by a concise usage caveat. No redundant words or information already in the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple write tool with good schema descriptions and annotations, the description covers what it does, when to use it, and its ephemeral nature. It does not describe return values or error handling, but with no output schema and low complexity, this is acceptable. The provider restriction and usage caution are valuable context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% (two of three params have detailed descriptions, including strong guidance on chat_id and account_id). The action param is an enum with clear options (typing/recording) that requires no further explanation. The description itself adds no parameter detail, but the schema is sufficient, so this is above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('publish'), a precise resource ('typing or voice-recording composing signal'), and a scope ('in a known chat where supported (LinkedIn Classic and WhatsApp)'). This clearly distinguishes it from sibling tools like messaging_set_chat_state or messaging_set_presence, which handle different state/signals.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit guidance: 'use only when an agent workflow explicitly needs it' and notes it is ephemeral provider state. It does not explicitly name alternatives or state when not to use it, but the 'only when needed' instruction plus provider scope gives clear context for an agent deciding between this and similar messaging tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_set_presenceMessaging: Set presenceAInspect

Set the connected messaging account presence where the provider supports it (LinkedIn Classic, WhatsApp, Telegram). Use only for an explicit presence request.

ParametersJSON Schema
NameRequiredDescriptionDefault
presenceYes
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal this is a mutation (readOnlyHint=false) and non-idempotent, so the description's main added value is the provider-support qualifier and the explicit-request restriction. It does not detail what happens for unsupported providers or failed updates, and no annotation contradiction is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and resource, followed by the usage restriction. Every clause earns its place; there is no redundant restating of the title or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple mutation tool with one enum parameter and a rich account_id description, the combination of schema and description is mostly sufficient. It includes the essential provider-support and explicit-request context, though it could have added a sentence about unsupported-provider behavior or the visible effect of the call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents account_id thoroughly, but the required 'presence' parameter has no description and the tool description adds no parameter-level meaning. With only 50% schema description coverage, the description should compensate for the undocumented required parameter; it does not explain the meaning of values like 'restricted_online'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Set ... presence', and scopes it to providers that support it (LinkedIn Classic, WhatsApp, Telegram). It also states the narrow trigger ('explicit presence request'), which clearly distinguishes this from sibling tools like messaging_set_composing or messaging_set_chat_state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear usage condition: only call for an explicit presence request, and only when the provider supports presence. It does not explicitly name alternative tools for chat state or composing, but the exclusionary 'only for an explicit presence request' is enough for an agent to select this tool correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

messaging_start_chatMessaging: Start chatA
Destructive
Inspect

Start a new WhatsApp, Instagram or Telegram one-to-one/group chat by sending its first message. Resolve users_ids first. A string starts 1-to-1; an array requests a group. LinkedIn requires the inbox-specific start tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
textYes
providerYes
specificsNo
users_idsYesOne exact provider user ID for a direct chat, or exact provider user IDs for a group; resolve every recipient first.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
attachmentsNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and readOnlyHint=false, so the mutating nature is established. The description adds useful context: it sends a message and creates a new chat, and it distinguishes one-to-one vs group behavior. It doesn't disclose what happens on failure, partial group creation, or whether sending is immediate, but annotations carry the core safety burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the core purpose and providers. Every sentence adds useful routing or usage information. It is slightly terse given the optional parameters and complexity, but nothing is padded or redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 7 parameters, no output schema, and nested attachment objects, the description covers the core start-chat flow and the critical string/array behavior, but leaves gaps. It does not explain return values, error behavior, or the meaning of specifics/name/attachments. The schema covers account_id and users_ids, but overall context is only moderately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 29%, so the description must compensate. It does explain the critical users_ids distinction: string for 1-to-1, array for group. However, it adds nothing for text, name, specifics, or attachments, leaving several parameters semantically opaque. The schema documents users_ids and account_id well, but the description only partially fills the overall gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation: start a new WhatsApp, Instagram, or Telegram one-to-one/group chat by sending its first message. It distinguishes the tool from the broader messaging_send_message and provider-specific tools, and explicitly excludes LinkedIn. This is a specific verb + resource with scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear when-to-use guidance: use for starting new chats and resolving users_ids first. It also names an exclusion ('LinkedIn requires the inbox-specific start tool'), which routes the agent away from a sibling. It could be stronger by explicitly naming the LinkedIn sibling or distinguishing from messaging_send_message for existing chats.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_delete_commentPosts: Delete commentA
Destructive
Inspect

Delete one exact comment. Resolve post_id then comment_id; never use comment text as ID. Destructive. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
comment_idYesExact comment ID belonging to the already resolved post_id. Obtain by listing comments on that post; never pass comment text or post_id here. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, so the explicit 'Destructive' warning is redundant but consistent. The description adds behavioral value by requiring exact ID resolution and forbidding text-based identifiers, which prevents accidental deletion of the wrong comment.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but organized into Post ID and Comment ID sections with clear do/don't lists. There is minor repetition of 'never use comment text as ID' at the top and again under Comment ID, but every sentence otherwise earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, ID-sensitive tool it covers target resolution, forbidden inputs, and provider-specific ID formats, and account disambiguation is handled in the schema. It does not mention return/confirmation behavior, but this is a deletion action and no output schema exists to require it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the input schema already contains the same ID-resolution guidance for post_id and comment_id. The description adds no meaning beyond the schema, so the high-coverage baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening phrase 'Delete one exact comment' names a specific verb and resource, with 'one exact' distinguishing it from bulk or fuzzy operations. The title 'Posts: Delete comment' plus this description clearly separates it from siblings like social_delete_post and social_update_comment.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly instructs the agent to resolve post_id first, then comment_id, and states what must never be passed (comment text, author user ID, URL, post_id in comment_id). It names concrete resolver tools for obtaining valid IDs, giving the agent a clear path to correct invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_delete_postPosts: Delete postA
Destructive
Inspect

Delete an exact supported social post. Resolve/verify post_id first. Destructive: explicit deletion intent required. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true, and the description reinforces this with 'Destructive: explicit deletion intent required.' It adds useful behavioral context beyond annotations by warning to verify the ID beforehand and specifying what inputs are unacceptable, which helps an agent avoid irreversible mistakes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence carries operational weight: the core action, the destructive warning, ID format, sourcing commands, and exclusions. It is front-loaded with the primary purpose and does not waste words, though it does duplicate some schema text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive single-parameter tool with no output schema, the description covers everything an agent needs: what to delete, how to resolve the correct ID, which tools to use to obtain it, and how to handle account ambiguity via the optional account_id. The account_id guidance in the schema complements this fully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both post_id and account_id thoroughly. The description restates the post_id sourcing guidance but adds little beyond the schema; it does not introduce new parameter-level semantics that the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a precise verb-resource pair, 'Delete an exact supported social post,' which clearly distinguishes this from social_delete_comment and the many read/list tools in the sibling list. It also adds the precondition 'Resolve/verify post_id first,' making the scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational guidance: resolve the post first, obtain the ID through listed tools, and never pass post text, author ID, or URL unless a resolver accepts it. It does not explicitly contrast with social_delete_comment, but the 'exact supported social post' phrasing and detailed ID sourcing make the intended use clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_list_comment_reactionsPosts: List comment reactionsA
Read-onlyIdempotent
Inspect

List detailed reactions on an exact comment. First resolve post_id, then list comments and select comment.id. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNoPagination offset returned/used by this reaction listing.
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
comment_idYesExact comment ID belonging to the already resolved post_id. Obtain by listing comments on that post; never pass comment text or post_id here. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the behavioral requirement of resolving exact IDs before calling, and the 'Never pass' rules clarify input constraints beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is verbose and repetitive. The same 'Never pass' and 'Obtain with' instructions are duplicated in the description text and again inside the schema property descriptions for post_id and comment_id. It could be condensed significantly without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main complexity—how to obtain the required IDs—and includes guidance on the optional account_id. It does not describe the return format, but given the absence of an output schema and the fact that this is a read/list operation, the essential information for correct invocation is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all parameters are documented in the schema. The description adds extra semantics by explaining how to obtain post_id and comment_id via specific sibling tools and by explicitly listing what not to pass, which is not present in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action 'List detailed reactions on an exact comment', specifying a verb, resource, and scope. It does not explicitly name sibling tools like linkedin_list_post_reactions, but the title and text make it unambiguous that this targets comment reactions, not post reactions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit workflow instructions: 'First resolve post_id, then list comments and select comment.id', and also tells the agent what not to pass (e.g., 'Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it'). It does not compare against alternatives, but the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_react_to_commentPosts: React to commentA
Destructive
Inspect

React to one exact comment. Resolve post -> comment before acting. Do not confuse post_id and comment_id. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
reactionYesProvider-supported reaction value; use the requested semantic reaction and do not invent unsupported values.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
comment_idYesExact comment ID belonging to the already resolved post_id. Obtain by listing comments on that post; never pass comment text or post_id here. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=true, so the mutation/destructive nature is covered. The description adds practical behavioral context: the need to resolve IDs first, the warning against confusing post_id and comment_id, and the caution against passing invalid values. It does not contradict annotations and provides additional process-level transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized, with the core purpose front-loaded. It uses line breaks to separate Post ID and Comment ID instructions, making it scannable. While it repeats some schema content, every sentence serves a purpose (resolution steps, exclusions, account_id handling). It is not overly verbose for a tool with such a high risk of ID confusion.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (requires resolving both post and comment) and the absence of an output schema, the description covers the essential steps to call it correctly: how to obtain both IDs, what not to pass, and how to handle the optional account_id. It does not describe return values, but that is not required without an output schema. The guidance is sufficient for an agent to execute the action correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description largely mirrors the schema's parameter descriptions for post_id and comment_id, adding little new meaning. However, it does reinforce the resolution workflow and explicitly warns against passing text/URLs, which is slightly more than the schema alone. Still, the added value is marginal, keeping the score at 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb+resource: 'React to one exact comment.' It explicitly distinguishes itself from related tools by focusing on comments rather than posts or reaction removal. Sibling tools like linkedin_react_to_post and social_remove_comment_reaction are implicitly differentiated by the 'exact comment' scope and the resolution steps.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: it requires resolving post -> comment before acting, and names specific resolver tools (linkedin_search_posts, linkedin_list_user_posts, etc.) and their output fields. It also gives clear 'never pass' exclusions for each ID, preventing common misuse. This goes beyond vague context to actionable rules.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_remove_comment_reactionPosts: Remove comment reactionA
Destructive
Inspect

Remove the user's reaction from one exact comment. Resolve post_id/comment_id first. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
reactionYesThe reaction to remove: emoji or provider reaction type that was added.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
comment_idYesExact comment ID belonging to the already resolved post_id. Obtain by listing comments on that post; never pass comment text or post_id here. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint=true and readOnly=false, so the description is not required to restate the safety profile. It adds useful context that the operation is scoped to an exact, pre-resolved comment and warns against guessing from unstructured input, but it does not reveal much beyond what the annotations and name imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentence is clear and the resolver guidance is well labeled, but much of the description duplicates the parameter descriptions in the schema nearly verbatim. This repetition makes the description longer than necessary without adding new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive 4-parameter tool with full schema coverage, the description provides sufficient resolver chains and anti-misuse guardrails to call it correctly. It is slightly incomplete because one referenced comment resolver is missing from the sibling tool list, but the overall guidance is strong.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already contains the same detailed resolver and 'never pass' guidance for post_id and comment_id. The description therefore adds little new parameter meaning beyond what the input schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the exact action and target ('Remove the user's reaction from one exact comment'), clearly distinguishing this from related tools like social_remove_post_reaction and social_react_to_comment. It emphasizes the precise scope of the operation without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete resolver chains for obtaining the post_id and comment_id, and explicit 'Never pass' exclusions for text, author IDs, and URLs. It does not explicitly steer the agent toward this tool versus the sibling post-reaction removal tool, and it references instagram_list_post_comments, which is not present in the provided sibling list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_remove_post_reactionPosts: Remove post reactionA
Destructive
Inspect

Remove the user's reaction from one exact post. Resolve post_id first; never use post URL/text unless another resolver explicitly converts it. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
reactionYesThe reaction to remove: the emoji for Instagram, or the LinkedIn reaction type that was added (e.g. LIKE).
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the description does not need to restate that this is a destructive operation. It adds contextual behavior about ID resolution, but does not disclose edge cases such as what happens if no reaction exists or whether the action is reversible beyond what destructiveHint implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and then provides focused, high-value ID resolution rules. There is some redundancy between the description and the schema, but the warnings about never passing URL/text/author ID are important and justify their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter destructive tool with no output schema, the description covers the critical invocation details: exact post ID format, how to obtain IDs, and account_id disambiguation. It is complete enough for an agent to select and call the tool correctly, though it does not describe response or no-op behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema coverage is 100%, and the schema already documents post_id, reaction, and account_id in detail, including the emoji vs. LinkedIn reaction format and account disambiguation. The description repeats much of the same post_id guidance rather than adding substantial new parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Remove the user's reaction from one exact post.' It also distinguishes this from related siblings like social_remove_comment_reaction and linkedin_react_to_post by explicitly scoping to posts and removal.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage guidance: resolve post_id first, never pass URL/text/author ID, and use specific list/search tools to obtain the ID. It does not explicitly name sibling alternatives for deleting comment reactions or chat reactions, but the post-scoped instructions and exclusions make the intended context clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_resolve_commentPosts: Resolve commentA
Read-onlyIdempotent
Inspect

List comments for an already-resolved post so the agent can map a human reference such as 'the comment from Sarah' to exact comment_id before replying/reacting/editing/deleting. First resolve post_id. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
post_idYesExact provider post ID returned by post search/list/get. Never pass post text, author ID or a post URL. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds behavioral context beyond annotations: it explains the tool is a resolver/mapper step in a workflow, requires the post to be 'already-resolved', and warns about ID formats (LinkedIn base64-style IDs). It doesn't describe pagination or return format, but for a read-only list tool with strong annotations, this is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense and front-loaded with the core purpose, but it is somewhat repetitive: the post_id guidance appears in both the description and the schema's post_id property description nearly verbatim. The account_id guidance is also duplicated in the schema. This redundancy makes the description longer than necessary, though every unique piece of guidance is valuable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only resolver tool with 3 parameters and no output schema, the description covers the critical workflow context: when to use it, how to obtain the required post_id, how to handle multi-account ambiguity, and what not to pass. The offset parameter is left unexplained, and there's no mention of pagination or return shape, but the tool's role as a resolver is well contextualized. The sibling list shows related comment tools, and the description routes the agent appropriately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67% (post_id and account_id have descriptions, offset does not). The description adds significant meaning beyond the schema: it explains how to obtain post_id from specific sibling tools (linkedin_search_posts -> result.id, etc.), what never to pass, and how to handle account_id when multiple accounts exist. The offset parameter is undocumented in both schema and description, which prevents a 5, but the description compensates well for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List comments for an already-resolved post' to map a human reference to an exact comment_id. It clearly distinguishes this from comment mutation tools like social_update_comment or social_delete_comment. However, the title 'Posts: Resolve comment' is slightly ambiguous—it could be read as resolving a comment rather than listing comments for a resolved post—but the description clarifies the actual purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: use it to map a human reference like 'the comment from Sarah' to an exact comment_id before replying/reacting/editing/deleting. It also provides explicit alternatives: linkedin_list_post_comments and instagram_list_post_comments, and tells the agent to first resolve post_id. It even includes negative guidance on what never to pass (post text, author user ID, URL). This is exemplary usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_update_commentPosts: Update commentA
Destructive
Inspect

Edit an existing comment. Required chain when starting from human text: resolve post -> post.id -> list comments -> comment.id -> edit. post_id and comment_id are different ID namespaces. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesFinal replacement comment text explicitly requested/approved by the user.
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
comment_idYesExact comment ID belonging to the already resolved post_id. Obtain by listing comments on that post; never pass comment text or post_id here. Comment ID: Exact comment id scoped to the identified post. Obtain with: linkedin_list_post_comments(post_id) -> comment.id; instagram_list_post_comments(post_id) -> comment.id Never pass: comment text, post_id.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is not read-only and is destructive; the description adds meaningful context by explaining that post_id and comment_id belong to different ID namespaces and must be sourced through specific resolver/list tools. It also stresses that text must be 'explicitly requested/approved by the user', which is useful safety behavior beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is substantially repetitive: the full ID-sourcing guidance appears both in the main description and again verbatim inside the post_id and comment_id schema descriptions. The important workflow is front-loaded, but the bloated, run-on phrasing and duplicated content hurt readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter mutation tool with no output schema, the description covers the full invocation workflow, ID provenance, account disambiguation, and prohibited input types. It is nearly complete, though it never states what the caller should expect in the response after a successful edit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description repeats most of that information rather than adding unique parameter-level meaning; the only marginal addition is the explicit 'different ID namespaces' warning, but it is not enough to push beyond baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening phrase 'Edit an existing comment' names a specific verb and resource, and the title 'Posts: Update comment' reinforces the operation. It is clearly distinguished from siblings like social_delete_comment, linkedin_comment_on_post, and social_update_post by stating exactly which mutation it performs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit required chain: resolve post -> post.id -> list comments -> comment.id -> edit, and warns against passing post text, author IDs, or URLs. It does not explicitly name alternative create/delete comment tools, but the when-to-use and when-not-to-use guidance is clear enough for an agent to follow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

social_update_postPosts: Update postAInspect

Edit an existing supported social post. Resolve the exact post first, then reuse post.id. Never infer an ID from post text or author. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.

ParametersJSON Schema
NameRequiredDescriptionDefault
textNoReplacement/updated post text requested by the user.
post_idYesExact provider post ID. Resolve/list the post first; never pass post text, author ID or a human description. Post ID: Exact provider/Unipile post id; LinkedIn commonly uses a preformatted/base64-style post ID. Obtain with: linkedin_search_posts -> result.id; linkedin_list_user_posts -> result.id; instagram_list_user_posts -> result.id Never pass: post text, author user ID, URL unless a resolver tool explicitly accepts it.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
can_commentNo

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal mutation (readOnlyHint=false) and non-destruction (destructiveHint=false), so the description mainly needs to add context beyond that. It adds important ID-resolution caveats, but does not disclose side effects, permission requirements, irreversibility, or failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded and the critical never-infer-an-ID guidance is emphasized. The description is somewhat run-on and repeats ID guidance also present in the schema, but it remains appropriately sized and actionable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description does not specify which social providers are 'supported' or what a partial update behaves like. Still, the ID-resolution instructions plus the schema's account_id guidance cover the main invocation needs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

post_id semantics are strongly enriched beyond the schema with provider-specific examples and resolver chains. Schema coverage is 75%, so baseline is near 3, but the detailed warning about never passing post text, author ID, or URL justifies a higher score. can_comment lacks semantic explanation beyond its enum values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Edit an existing supported social post.' This distinguishes it from sibling create, delete, and comment tools, and the title 'Posts: Update post' reinforces the intent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: resolve the exact post first and reuse post.id, never inferring an ID from text or author. It does not explicitly name alternatives or state when not to use this tool, but the 'existing' wording implies the update-vs-create/delete boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

team_add_seatsTeam: Add seatsA
Destructive
Inspect

Add (or reduce) paid extra seats on the Team subscription so more colleagues can be invited. Billing owner only; prorated immediately on the saved payment method. FIRST call without confirm to get the price and a one-click Stripe confirmation link, then call with confirm=true after the user approves. extra_seats is the ADDED number of seats relative to the current paid extra seats (use 1 to add one seat).

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoSet true ONLY after the user explicitly confirmed the price shown to them. Without it, the tool returns the price, the proration explanation and a Stripe confirmation link instead of changing anything.
extra_seatsYesSeats to add (positive) or remove (negative, only unused seats).

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses critical behaviors beyond annotations: billing owner restriction, immediate proration on the saved payment method, and the non-destructive nature of the first call. The description also explains that extra_seats is relative to current paid extra seats)Skip, which prevents off-by-one mistakes. Annotations indicate destructiveHint=trueholen, and the description aligns by showing confirm is required for changes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences deliver purpose, authorization, billing side effect, and the exact confirm workflow with no wasted words. The critical 'relative' parameter semantics are front-loaded after the workflow, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive billing mutation with no output schema, the description covers prerequisites (billing owner), workflow (dry-run then confirm), side effects (proration on saved payment method), and parameter semantics. An agent can invoke this tool correctly without guessing, and the absence of an output schema is compensated by the explicit mention of the first-call response (price, proration explanation, Stripe link).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though schema coverage is 100%, the description adds meaning beyond the schema: extra_seats is 'the ADDED number of seats relative to the current paid extra seats (use 1 to add one seat),' clarifying that the value is delta, not total. It also reinforces the confirm semantics from the schema, making the workflow unambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Add (or reduce) paid extra seats on the Team subscription' with clear purpose 'so more colleagues can be invited.' It also distinguishes itself from team_invite_member by focusing on billing seats rather than inviting members, and clarifies the direction of change with 'add (or reduce).'

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit operational usage through the two-step confirm workflow: first call without confirm to obtain price and Stripe link, then call with confirm=true after user approval. It also states the authorization requirement ('Billing owner only'). It does not explicitly name sibling alternatives, but the billing-vs-invite distinction is enough to prevent confusion with team_invite_member.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

team_invite_memberTeam: Invite memberA
Destructive
Inspect

Invite a colleague to the user's Team workspace by email. Each member gets a separate login, isolated provider Scope and their own connected accounts; the team only centralizes billing and seats. Only team owners/admins can invite. When no seat is free, the result explains how to add a paid seat (team_add_seats). If the user is not on Team, propose account_change_plan(plan='team').

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYesEmail address of the person to invite.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses that it's a write operation (invite) and adds behavioral context: the result explains how to add a paid seat, and it suggests proposing a plan change if not on Team. Does not contradict annotations (destructiveHint=true, readOnlyHint=false). Adds value beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the purpose, then scoping, permission, and fallback actions. No wasted words; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with no output schema, the description covers the action, permission, conditional alternatives, and explains the team concept. An agent has everything needed to decide when and how to call it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a clear description for the email parameter. The tool description adds no extra parameter-specific details beyond 'by email', which is already implied. Baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (invite), resource (colleague to Team workspace), and method (by email). Clearly distinguishes from sibling tools by mentioning team_add_seats and account_change_plan as alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states permission requirements (only owners/admins can invite) and provides conditional guidance: when no seat is free, points to team_add_seats; when not on Team, points to account_change_plan. Gives clear when-to-use and when-not-to-use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

telegram_connectTelegram: ConnectAInspect

Connect or reconnect the user's Telegram account directly in the conversation: returns a QR code image to scan from Telegram > Settings > Devices > Link Desktop Device, then poll account_connection_status until connected. Accounts protected by a Telegram cloud password (2FA) must use the browser link returned by account_connect instead. Use account_id to re-authenticate an existing disconnected Telegram account.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoNilyo connection ID (unipile_account_id from list_connected_accounts) of an EXISTING account to re-authenticate. Omit to connect a new account.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With all annotations false, the description carries the behavioral burden. It discloses the full flow: returns QR code, then polling until connected. It also notes the 2FA limitation and re-auth path. While it doesn't mention potential side effects like creating a new connection record, it gives sufficient behavioral context beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately long but each sentence carries necessary information: the core action, the QR scanning path, the 2FA exclusion, and re-auth usage. It is front-loaded with the primary purpose and avoids fluff, though slightly more verbose than strictly needed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a connect tool with no output schema, the description covers the essential steps: returning a QR image, polling, the 2FA caveat, and account_id usage. It doesn't detail error handling or timeouts, but given the tool's simplicity and schema coverage, it is adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already fully describes account_id with 100% coverage, including its purpose and how to obtain it. The description restates this usage but doesn't add new semantic meaning. Baseline 3 is appropriate since the schema handles parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool connects or reconnects a Telegram account via QR code, which is a specific verb+resource. It distinguishes itself from account_connect (browser link for 2FA) and account_connection_status (polling), making it unambiguous among the sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when NOT to use this tool: accounts with 2FA must use account_connect. Also provides guidance on using account_id for re-authentication of existing accounts and mentions polling account_connection_status. This gives clear decision rules for the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_create_destinationRealtime: Create destinationAInspect

Create a realtime event destination for this Nilyo user. Nilyo uses its global Unipile control-plane key server-side but ALWAYS restricts the Unipile endpoint to account IDs owned by this authenticated user. By default matching future accounts are automatically added. For n8n use its Test URL first, validate with a Development/Mock event, then update to Production URL.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
eventsYesExact Unipile V2 event types. Call webhook_list_available_events first when unsure. Do not invent event names.
runtimeYes
providersNoOptional provider filter. google includes Gmail and outlook includes Microsoft accounts. With auto_include_new_accounts=true, Nilyo keeps this Unipile endpoint's account_ids synchronized when the user connects matching accounts later.
account_idsNoOptional explicit Unipile account IDs returned by list_connected_accounts. Nilyo rejects the whole request if any ID is not owned by the authenticated user.
request_urlYesPublic HTTPS POST receiver URL supplied by the target runtime. Never guess a URL.
auto_include_new_accountsYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are minimal (readOnlyHint false, destructiveHint false, etc.), so the description carries the burden. It discloses important behavioral traits beyond the schema: the endpoint is always restricted to the authenticated user's account IDs, and by default matching future accounts are automatically included. This adds security and default-behavior context that annotations do not provide, though it omits details about failure modes or return values.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description consists of four tightly packed sentences, each adding value: purpose/security, auto-include default, and n8n validation workflow. It is front-loaded with the core action and scoping. No filler or repetition; slightly dense but appropriately concise for the amount of context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a create tool with 7 parameters and no output schema, the description provides important security and workflow guidance but leaves gaps. It does not state what the tool returns (e.g., created destination ID) or how errors are surfaced. It also does not explain runtime values or reiterate the events enumeration guidance (though schema covers that). Overall, the description is helpful but not fully complete for an agent to confidently call without additional lookups.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 57%, so the description should compensate. It does add meaning to auto_include_new_accounts ('By default matching future accounts are automatically added') and to request_url ('For n8n use its Test URL first...'), but it does not clarify name or runtime semantics. The events and providers parameters already have descriptions in the schema, so the overall contribution is partial rather than comprehensive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Create a realtime event destination for this Nilyo user.' The security scoping detail ('restricts the Unipile endpoint to account IDs owned by this authenticated user') differentiates it from generic webhook creation and from sibling tools like webhook_update_destination or webhook_test_destination. The purpose is unambiguous and actionable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a concrete n8n workflow ('use its Test URL first, validate with a Development/Mock event, then update to Production URL'), which is useful context. However, it does not explicitly state when to prefer this tool over alternatives like webhook_update_destination, nor does it mention exclusions such as 'use webhook_get_setup_guide to learn more.' The intended usage is implied but not contrasted with siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_delete_destinationRealtime: Delete destinationA
Destructive
Inspect

Delete an Nilyo-owned Unipile webhook endpoint. This stops future realtime delivery to that destination; require explicit user intent.

ParametersJSON Schema
NameRequiredDescriptionDefault
destination_idYesNilyo webhook destination ID returned by webhook_create_destination/webhook_list_destinations. Never use the Unipile endpoint ID directly.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint=true, so deletion is known. The description adds value by specifying what gets stopped ('future realtime delivery') and requiring explicit user intent, which is a meaningful behavioral caution. It does not mention irreversibility or permission needs, but the annotation plus consequence statement carry most of the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences: the first states the action and scope; the second states the direct consequence and a safety requirement. There is no filler or repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter deletion tool with full schema coverage and annotations, the description is complete. It names the resource, the effect, and the user-intent requirement; nothing an agent needs to decide whether to invoke it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the destination_id property is already well documented: it is the Nilyo webhook destination ID returned by create/list tools and must never be the Unipile endpoint ID directly. The description adds no new parameter-level detail, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the exact action ('Delete') on a specific resource ('Nilyo-owned Unipile webhook endpoint') and names the ownership boundary, which distinguishes this from deleting some other webhook resource. It clearly differentiates from sibling tools like webhook_create_destination, webhook_update_destination, and webhook_list_destinations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description tells the agent the consequence ('stops future realtime delivery to that destination') and adds an important gate: 'require explicit user intent.' It does not explicitly contrast with alternatives (e.g., updating/disabling instead of deleting), but the direct deletion call and consequence make the usage context clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_get_delivery_logsRealtime: Get delivery logsA
Read-onlyIdempotent
Inspect

Inspect recent Unipile webhook delivery conversations for this destination. Use when an agent/n8n receiver did not wake or a test event was not observed. This is preferred to guessing whether delivery occurred.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitYes
destination_idYesNilyo webhook destination ID returned by webhook_create_destination/webhook_list_destinations. Never use the Unipile endpoint ID directly.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already disclose read-only, idempotent, non-destructive behavior. The description adds the troubleshooting context (when delivery is suspected to have failed) but not additional behavioral details like response shape or field meanings. It does not contradict any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no fluff. The central action and resource are in the first sentence, and the 'when to use' is in the second and third. Perfectly front-loaded and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the tool is simple enough that the description plus schema cover what an agent needs: the resource, the trigger, and the safe read-only behavior. The only gap is that 'Realtime' from the title isn't echoed in the description, but 'recent' suffices for this low-complexity tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers destination_id with a thorough explanation and a warning not to use the Unipile endpoint ID, while limit has type/default/bounds but no prose. The tool description doesn't elaborate on limit's meaning beyond what the schema gives, so it adds minimal value beyond the existing 50% schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Inspect') and resource ('recent Unipile webhook delivery conversations for this destination'), which clearly differentiates it from sibling tools like webhook_test_destination or webhook_get_destination. It also frames the tool's role in troubleshooting delivery failures.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly names two trigger conditions ('agent/n8n receiver did not wake' and 'test event was not observed') and contrasts with 'guessing whether delivery occurred.' However, it does not name any alternative tool or exclusion criteria, so it stops short of the 5-level.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_get_destinationRealtime: Get destinationA
Read-onlyIdempotent
Inspect

Get one Nilyo-owned webhook destination and its configured events/provider/account selection.

ParametersJSON Schema
NameRequiredDescriptionDefault
destination_idYesNilyo webhook destination ID returned by webhook_create_destination/webhook_list_destinations. Never use the Unipile endpoint ID directly.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is established. The description adds the scoping that this is a single-destination read and lists what is included, but it does not describe response format or error/absence behavior. That is useful but not rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler. The core action, resource, and returned information are front-loaded, making it easy for an agent to scan and act on immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read operation with full schema coverage and strong annotations, the description covers what is needed: what is fetched and what fields are included. No return schema is provided, but the phrase about configured events/provider/account selection gives sufficient context, and there is no additional complexity to document.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the destination_id parameter already has a detailed description in the input schema, including its source and the warning not to use the Unipile endpoint ID directly. The tool description does not need to add parameter semantics and does not go beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Get'), a specific resource ('one Nilyo-owned webhook destination'), and the returned content ('configured events/provider/account selection'). It is clearly distinguished from list/create/update/delete siblings by the 'one destination' framing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance is given; it never points to webhook_list_destinations for retrieving all destinations or to other webhook tools for setup/testing. The only hint is the word 'Get one,' which leaves the choice of tool to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_get_setup_guideRealtime: Get setup guideA
Read-onlyIdempotent
Inspect

Get runtime-specific instructions for receiving Unipile realtime events in n8n, OpenClaw, Hermes, Make or a generic agent. Use BEFORE creating the webhook when the user has not yet produced a public receiver URL.

ParametersJSON Schema
NameRequiredDescriptionDefault
runtimeYes

TDQS

A4.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds context that it returns instructions and provides sequencing guidance, but it does not disclose any additional behavioral traits like output format or the absence of side effects beyond what annotations imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the first states the tool's purpose and scope, the second gives usage timing. The most decision-relevant information is front-loaded and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple guide-retrieval tool with one enum parameter, the description covers purpose, scope, and usage timing. There is no output schema, but 'runtime-specific instructions' adequately conveys what the caller will receive. The only minor gap is not stating the format of the returned instructions, which is unlikely to hinder correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It does so by naming each runtime ('n8n, OpenClaw, Hermes, Make or a generic agent') that maps directly to the 'runtime' enum values, making it clear that the parameter selects which runtime's instructions to return.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and resource ('runtime-specific instructions for receiving Unipile realtime events') and enumerates the exact runtimes supported. This makes it immediately distinguishable from sibling webhook tools like webhook_create_destination, webhook_get_destination, and webhook_list_available_events.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit temporal guidance: 'Use BEFORE creating the webhook when the user has not yet produced a public receiver URL.' This tells the agent both when to invoke it and the precondition that selects it over alternatives, leaving no ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_list_available_eventsRealtime: List available eventsA
Read-onlyIdempotent
Inspect

List realtime Unipile V2 event types Nilyo can subscribe an agent to, plus the common event envelope. Use this before creating a destination if the user's requested trigger is ambiguous.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the 'realtime' qualifier and mentions the return of the common event envelope, which is minor behavioral context, but it does not go deeper (e.g., response shape or filtering).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero filler. The first sentence front-loads the core purpose and output, and the second delivers targeted usage guidance. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list tool, the description is complete enough: it states what is returned (event types + envelope) and when to call it. No output schema exists, but the description partially compensates. It lacks a note about static output or format, but that is a minor gap given the low complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so per the rubric the baseline is 4. The description needs no parameter guidance; the empty schema with 100% coverage fully documents the input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a resource ('realtime Unipile V2 event types'), and a scope ('Nilyo can subscribe an agent to'), plus a secondary output ('the common event envelope'). This clearly distinguishes it from siblings like webhook_list_destinations and webhook_get_setup_guide.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives explicit when-to-use guidance: 'Use this before creating a destination if the user's requested trigger is ambiguous.' This is actionable, but it does not mention alternatives or when not to use it, leaving some room for inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_list_destinationsRealtime: List destinationsA
Read-onlyIdempotent
Inspect

List webhook destinations created by this Nilyo user. These are control-plane records; realtime traffic flows directly Unipile -> destination, not through Nilyo.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the operation's safety is covered. The description adds meaningful context beyond annotations by explaining that these are control-plane records and that realtime traffic flows directly Unipile -> destination, not through Nilyo. This clarifies the nature of the data returned and the architectural role of the destinations, which is valuable for the agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no wasted words. The action and scope are front-loaded ('List webhook destinations created by this Nilyo user'), and the second sentence adds essential context about control-plane vs. data-plane. Every sentence earns its place, and it is highly concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with no parameters, no output schema, and comprehensive annotations (readOnly, idempotent, non-destructive), the description is mostly complete. It specifies the scope (created by this user) and clarifies the architectural role of the records. However, it does not mention what fields are returned or whether pagination is involved, though without an output schema, the agent might need such hints. Still, for a zero-parameter list, the description is adequate and goes beyond minimal requirements.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so schema coverage is trivially 100%. The description does not need to explain any parameters, and the baseline for 0 params is 4. The description adds no parameter-specific semantics because none exist, which is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb (list) and resource (webhook destinations created by this Nilyo user), and the scope is explicit. It distinguishes itself from siblings like webhook_get_destination (which retrieves a single record) by implying a listing operation, and the mention of 'created by this Nilyo user' adds precision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context about control-plane records but does not explicitly state when to use this tool versus alternatives like webhook_get_destination or webhook_list_available_events. The usage is implied (when you need all destinations for the user), but no direct comparison or exclusion is given. Given the simplicity of the tool (no parameters), this is a moderate gap, not a severe one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_test_destinationRealtime: Test destinationA
Read-onlyIdempotent
Inspect

Return the exact test procedure for a destination. In a Unipile Development Application, use Mock accounts/Test & Debug to generate a real fake event, then inspect webhook_get_delivery_logs and the target runtime. Nilyo does not fabricate provider event payloads because the Unipile mock event is the source of truth.

ParametersJSON Schema
NameRequiredDescriptionDefault
destination_idYesNilyo webhook destination ID returned by webhook_create_destination/webhook_list_destinations. Never use the Unipile endpoint ID directly.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, covering the safety profile. The description adds behavioral context: it explains the source of truth (Unipile mock event) and clarifies that Nilyo does not fabricate provider event payloads. This goes beyond annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The purpose is front-loaded, and the usage guidance is compact yet complete. Every sentence contributes value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (one param, no output schema), and the description covers its purpose, usage steps, and key constraints. It references the environment and alternative tools, so nothing critical is missing for correct invocation. A 5 would require explicit return-format details, but the description already sets expectations for a procedure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the parameter description clearly explains destination_id and even warns against using the Unipile endpoint ID directly. The tool description adds no additional parameter semantics, but the baseline 3 applies when schema fully covers the parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('Return the exact test procedure') and clearly differentiates from sibling webhook tools like webhook_get_setup_guide and webhook_get_destination. It also clarifies what it does not do (does not fabricate payloads), leaving no ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs when to use this tool (to retrieve the test procedure) and gives step-by-step context: use Mock accounts/Test & Debug to generate a real fake event, then inspect webhook_get_delivery_logs and the target runtime. It also names the alternative (webhook_get_delivery_logs) and explains the limitation of Nilyo, making the selection obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

webhook_update_destinationRealtime: Update destinationAInspect

Update a webhook destination URL, events or provider/account selection. Common n8n chain: create with Test URL -> receive mock event -> update same destination to Production URL. Nilyo recomputes authorized account_ids server-side.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
eventsNoExact Unipile V2 event types. Call webhook_list_available_events first when unsure. Do not invent event names.
enabledNo
runtimeNo
providersNoOptional provider filter. google includes Gmail and outlook includes Microsoft accounts. With auto_include_new_accounts=true, Nilyo keeps this Unipile endpoint's account_ids synchronized when the user connects matching accounts later.
account_idsNoOptional explicit Unipile account IDs returned by list_connected_accounts. Nilyo rejects the whole request if any ID is not owned by the authenticated user.
request_urlNoPublic HTTPS POST receiver URL supplied by the target runtime. Never guess a URL.
destination_idYesNilyo webhook destination ID returned by webhook_create_destination/webhook_list_destinations. Never use the Unipile endpoint ID directly.
auto_include_new_accountsNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description reveals non-obvious server-side behavior: 'Nilyo recomputes authorized account_ids server-side.' This is valuable because it signals that account_ids may be adjusted automatically. The description also implies a mutating operation, consistent with readOnlyHint=false and idempotentHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler, and the most important information—what can be updated—comes first. The workflow example and server-side behavior note each add distinct value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex 9-parameter mutating tool with no output schema, the description supplies a real workflow and a key server-side behavior note. It does not describe return values or update semantics (e.g., partial vs. full replacement), but the schema and parameter descriptions cover most invocation details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description identifies the main update categories (URL, events, provider/account selection), and some parameters like events, providers, account_ids, and request_url already have schema descriptions. However, it does not add meaning for name, enabled, runtime, or auto_include_new_accounts, and schema coverage is only 56%, so the description only partially compensates for the gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states exactly what the tool does: 'Update a webhook destination URL, events or provider/account selection.' It names a specific verb and resource and enumerates the modifiable aspects, making it easy to distinguish from webhook_create_destination, webhook_delete_destination, and webhook_get_destination.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides concrete usage context: 'Common n8n chain: create with Test URL -> receive mock event -> update same destination to Production URL.' This tells an agent when updating is appropriate in the lifecycle. It does not explicitly contrast with create/delete, but the workflow implication is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_connectWhatsApp: ConnectAInspect

Connect or reconnect the user's WhatsApp account directly in the conversation without leaving the agent. Default mode returns a QR code image to scan from WhatsApp > Linked devices; with phone_number it returns a pairing code to type on the phone instead (useful when the QR image cannot be displayed). Then poll account_connection_status until connected. Requires an active trial/subscription and a free WhatsApp slot on the plan; otherwise the result explains the upgrade. Use account_id to re-authenticate an existing disconnected WhatsApp account.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoNilyo connection ID (unipile_account_id from list_connected_accounts) of an EXISTING account to re-authenticate. Omit to connect a new account.
phone_numberNoOptional. International phone number of the WhatsApp account, digits only (e.g. 33612345678). When provided, a pairing code is returned instead of a QR code.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are all false, so description carries full burden. It discloses that it returns a QR code or pairing code, that it is asynchronous (polling required), and that it explains upgrades if ineligible. Re-authentication behavior is also disclosed. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Five sentences, each earning its place: purpose, mode explanation, polling instruction, prerequisites, and re-auth usage. Front-loaded with the core action, no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-param tool with no output schema, the description covers return behavior (QR/pairing code), next steps (polling), and eligibility conditions. No critical information is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 100% schema coverage, the description adds meaningful context: explains the default QR mode, the phone_number toggling to pairing code, and account_id's role in re-authentication. This goes beyond the schema's already detailed property descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the tool connects/reconnects a WhatsApp account, specifying the resource (WhatsApp) and the action (connect). It distinguishes itself from siblings like account_connection_status by explicitly mentioning polling after initiation, and from telegram_connect by being WhatsApp-specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: when to use phone_number (when QR cannot be displayed), when to use account_id (re-authenticate existing account), and directs to poll account_connection_status afterward. Also states prerequisites (active trial/subscription and free slot) and what happens if unmet.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_get_profileWhatsApp: Get profileA
Read-onlyIdempotent
Inspect

Retrieve a WhatsApp user profile by provider user ID or supported phone-number identifier. Use to resolve/verify the recipient before a new chat.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idYesExact provider user ID returned by the relevant profile/contact resolver; never a display name or profile URL. For LinkedIn, use the stable system ID. LinkedIn system user ID: Stable LinkedIn/Unipile user id, commonly ACo... for Classic profiles. Obtain with: linkedin_get_profile_from_url(profile_url) -> result.id; linkedin_get_profile(user_id_or_public_identifier) -> result.id; linkedin_search_people(...) -> selected result.id Never pass: full linkedin.com/in/... URL, person name, company ID.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint, openWorldHint, idempotentHint, destructiveHint. The description adds 'resolve/verify the recipient' context, which is useful but does not go beyond what annotations imply. It doesn't mention rate limits, caching, or exact data returned, but with annotations covering the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main description is one sentence, efficient. The account_id parameter has a lengthy but useful explanation. The overall structure is clear, but the parameter descriptions add extra detail that, while helpful, could distract from the main description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 2 parameters and no output schema, the description is complete enough for an agent to call it correctly. It explains the identifier requirements, the resolution purpose, and the acaccount_id handling. It might benefit from noting that phone numbers must be in E.164 format, but the current detail is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already describes both parameters including the user_id and account_id. The description clarifies that user_id must come from a resolver and never be a display name or URL, and guides on account_id selection when multiple accounts exist. This adds valuable meaning beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Retrieve a WhatsApp user profile' and specifies the input identifiers (provider user ID or phone number), distinguishing it from other WhatsApp tools like whatsapp_list_contacts or whatsapp_is_number_registered. It could be slightly more specific about what fields are returned, but the purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says 'Use to resolve/verify the recipient before a new chat', providing clear context for when to use this tool. It does not explicitly mention when not to use it or name alternatives, but the purpose is clear enough among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_is_number_registeredWhatsApp: Is number registeredA
Read-onlyIdempotent
Inspect

Check whether a phone number corresponds to a WhatsApp user/account before starting outreach or resolving a WhatsApp recipient. Pass the number in international form.

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
phone_numberYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds the operational context that this is a pre-check, but it does not disclose additional behavioral traits such as return semantics, error behavior, or rate limits. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, and the core purpose is front-loaded. Every part of the description earns its place, including the concrete formatting instruction for the phone number.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a simple, read-only check with one required parameter and no output schema. 'Check whether' implies a boolean-style result, but the description does not explicitly confirm return behavior or how failures are signaled. Still, the essential calling context and parameter requirement are present, so it is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: phone_number has no schema description, and the description compensates by specifying it must be in international form. account_id already has a detailed schema description, so the tool description does not need to repeat it. This adds meaningful guidance beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Check whether') and a clear resource ('a phone number corresponds to a WhatsApp user/account'), and it differentiates the tool by anchoring it to the pre-outreach and recipient-resolution use case. This makes the purpose easy to distinguish from related siblings like whatsapp_get_profile or messaging_resolve_recipient.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: use it before starting outreach or resolving a WhatsApp recipient. It does not explicitly name alternatives or state when not to use it, so it falls short of a 5, but the intended trigger conditions are obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_list_contactsWhatsApp: List contactsA
Read-onlyIdempotent
Inspect

List WhatsApp contacts so a human name/phone can be resolved to an exact provider user identity before starting a new chat. Reuse the returned provider user ID; do not pass display name as whatsapp_user_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNoOpaque pagination cursor returned by previous call; never invent.
offsetNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, openWorldHint=true, and idempotentHint=true, making it a safe, non-destructive read operation. The description adds practical context on how to use the returned IDs and the need to resolve identities, which goes beyond the annotations. It also implies pagination via the 'cursor' parameter, but does not explicitly describe return format or pagination behavior, though this is partially covered by the parameter schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the primary purpose, followed by a key usage directive. Every sentence earns its place with no fluff or repetition of schema details. It is efficiently structured for quick agent consumption.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with no output schema, the description covers the essential context: purpose (identity resolution), key usage guidance (reuse provider user ID), and implied pagination via cursor. With annotations ensuring safety and the schema documenting parameters like account_id, the description is sufficient for an agent to call it correctly. Minor gaps like explicit pagination handling are not critical given the cursor schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%, covering the 'cursor' and 'account_id' parameters. The description adds no additional parameter-specific information; it focuses on usage of the output. Since half the parameters are undocumented in the schema (limit, offset) and the description does not compensate, a baseline 3 is appropriate. The description's mention of resolving identities does not clarify parameter semantics further.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List WhatsApp contacts' and elaborates its purpose: to resolve a human name/phone to an exact provider user identity before starting a chat. This distinguishes it from similar sibling tools like 'messaging_resolve_recipient' and 'whatsapp_list_conversations' by focusing on enumerating contacts for identity resolution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly advises to reuse the returned provider user ID and warns not to pass display name as whatsapp_user_id, which provides clear guidance for using the output. It implies use before starting a new chat, but does not explicitly contrast with alternatives like 'messaging_resolve_recipient' or 'whatsapp_is_number_registered', which could have strengthened the guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_list_conversationsWhatsApp: List conversationsA
Read-onlyIdempotent
Inspect

List WhatsApp chats from the user's own connected WhatsApp account. Use to find a chat_id before reading or sending when the user identifies a conversation by person/name rather than ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, open-world, and non-destructive behavior. The description adds useful scoping context ('from the user's own connected WhatsApp account') and workflow context, but does not disclose output shape, pagination behavior, or how results are ordered—minor gaps given the rich annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, both purposeful: the first identifies the action and scope, the second explains when to use it. No filler or redundant restating of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides the core purpose and use case, but with no output schema it should state more about what the returned conversations look like and whether limit controls the number of returned chats. It is adequate for a simple list tool, but leaves room for ambiguity around return values and edge cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 50%: account_id is well documented in the schema, but limit has only a name and bounds, and the tool description adds no parameter-level meaning. Because the description does not compensate for the undocumented limit parameter, parameter semantics are only partially conveyed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List WhatsApp chats from the user's own connected WhatsApp account.' It also clarifies the operational purpose—finding a chat_id before reading or sending—which distinguishes it from read/send and other provider-specific conversation-listing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to use this when the user identifies a conversation by person/name rather than ID, which is a clear triggering condition. It implies the alternative path (reading/sending after obtaining a chat_id) but does not name alternative sibling tools such as whatsapp_read_conversation or messaging_list_chats.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_read_conversationWhatsApp: Read conversationA
Read-onlyIdempotent
Inspect

Read a WhatsApp chat and recent message history. Use for context, summaries, follow-up detection and cross-channel workflows before sending a reply.

ParametersJSON Schema
NameRequiredDescriptionDefault
chat_idYesExact chat/conversation ID returned by conversation/inbox listing. Never pass a person name or provider user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is known. The description adds the 'recent message history' qualifier, which gives some behavioral insight into the return scope, but does not describe limits, pagination, or authentication requirements. Given annotations cover safety, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no waste. The primary action is stated first, followed by concrete use cases. Every word earns its place, and the description is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with detailed schema and safety annotations, the description is nearly complete. It states the action and purpose, and the schema covers parameters. The only minor gap is not specifying exactly what 'recent' means, but this is not critical for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with detailed explanations for both chat_id and account_id, including what not to pass and how to resolve the account. The description adds no parameter-specific info beyond the schema, so baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Read a WhatsApp chat and recent message history.' It is clear and distinct from generic messaging tools like messaging_list_messages, and the use cases (context, summaries, follow-up detection, cross-channel workflows) clarify its role in the conversation lifecycle.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear when-to-use context: before sending a reply, for context and summaries. It does not explicitly name alternatives or exclusions, but the intended workflow is evident. Since there is no competing WhatsApp read-conversation tool among siblings, the guidance is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_send_messageWhatsApp: Send messageA
Destructive
Inspect

Send a WhatsApp message in an existing chat from the user's own account. If chat_id is unknown, call whatsapp_list_conversations first. Use only after the final message is explicitly requested/approved.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
chat_idYesExact chat/conversation ID returned by conversation/inbox listing. Never pass a person name or provider user ID. Chat ID: Exact provider chat/conversation ID. LinkedIn chat IDs may also be visible in /messaging/thread/{chat_id}/ URLs. Obtain with: provider list conversations/inbox chats -> chat.id Never pass: person name, user_id, message_id.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal a non-readonly, destructive, non-idempotent external action. The description adds valuable behavioral context beyond that: the action is scoped to the user's own account, requires an existing chat, and is gated on explicit user approval, which mitigates the risk of unsolicited sends.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences with no filler. The core action is front-loaded, followed by the prerequisite for chat_id and the approval guardrail, making it easy for an agent to parse in order.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a side-effecting send action, the description supplies the critical missing context: how to resolve an unknown chat_id and when sending is permitted. It leaves implicit the fallback to whatsapp_start_conversation for a new chat and does not describe the return value, but the tool is otherwise simple enough to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents chat_id and account_id in detail, and the description adds no new parameter-level meaning beyond saying chat_id must refer to an existing chat. With schema coverage at 67% and text being self-explanatory, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Send a WhatsApp message in an existing chat from the user's own account.' It clearly distinguishes this tool from related siblings like whatsapp_start_conversation by limiting it to existing chats, and the provider-specific name prevents confusion with generic messaging_send_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit operational guidance: call whatsapp_list_conversations first if chat_id is unknown, and only send after the final message is explicitly requested or approved. It does not explicitly mention when to use whatsapp_start_conversation for new chats, so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whatsapp_start_conversationWhatsApp: Start conversationA
Destructive
Inspect

Start a new 1-to-1 WhatsApp chat and send the first message. Resolve/verify recipient first with whatsapp_list_contacts or WhatsApp profile/number lookup. whatsapp_user_id must be provider identity, never a contact display name.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesFirst message text explicitly requested/approved by user.
account_idNoOptional Nilyo connection ID (unipile_account_id from list_connected_accounts). Omit when the user has one account for this provider. When several exist, Nilyo never guesses: list them (display name, identifier, provider user ID), choose the one the user named or ask, and pass its ID here.
whatsapp_user_idYesExact WhatsApp provider user ID returned by contact/profile/number resolution; not a human name.

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, so the description does not need to re-state that sending a message is a side effect. It adds useful behavioral context by requiring recipient verification and that whatsapp_user_id be a provider identity, but does not elaborate on consequences like irreversibility or sending limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver the action, the prerequisite, and an identity constraint with no filler. The key scoping detail ('new 1-to-1 chat') is front-loaded, and each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the schema covers all parameters, annotations convey destructive behavior, and the description adds the essential recipient-resolution workflow and provider-identity constraint, the definition is complete for an agent to select and invoke the tool correctly. No output schema is present, so return-value details are not required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema describes each parameter, but the description adds critical meaning by clarifying that whatsapp_user_id must be a provider identity, never a display name, and that recipient resolution must come first. This goes beyond the bare schema definition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Start a new 1-to-1 WhatsApp chat and send the first message') and clearly identifies the resource. It differentiates from related messaging tools by emphasizing 'new' chat and first message, signaling this is not for continuing an existing conversation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear context on when to use the tool by instructing the agent to resolve/verify the recipient first with whatsapp_list_contacts or a profile/number lookup. It does not explicitly name an alternative like whatsapp_send_message for existing chats, but the 'new' framing implies the distinction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 173 tool updates
    • First observedaccount_change_plan
    • First observedaccount_connect
    • First observedaccount_connection_status
    • First observedaccount_get_subscription
    • First observedaccount_list_attention
    • First observedaccount_start_subscription
    • First observedagent_capability_guide
    • First observedagent_id_guide
    • First observedcalendar_cancel_event
    • First observedcalendar_create_calendar
    • First observedcalendar_create_event
    • First observedcalendar_delete_calendar
    • First observedcalendar_delete_event
    • First observedcalendar_get_calendar
    • First observedcalendar_get_event
    • First observedcalendar_list_calendars
    • First observedcalendar_list_events
    • First observedcalendar_restore_event
    • First observedcalendar_rsvp_event
    • First observedcalendar_update_calendar
    • First observedcalendar_update_event
    • First observedchat_add_participant
    • First observedchat_delete
    • First observedchat_list_participants
    • First observedchat_remove_participant
    • First observedchat_update
    • First observedemail_create_draft
    • First observedemail_create_folder
    • First observedemail_delete_draft
    • First observedemail_delete_folder
    • First observedemail_get_attachment
    • First observedemail_get_draft
    • First observedemail_get_folder
    • First observedemail_get_thread
    • First observedemail_list_contacts
    • First observedemail_list_drafts
    • First observedemail_list_folder_messages
    • First observedemail_list_folders
    • First observedemail_list_messages
    • First observedemail_mark_read
    • First observedemail_mark_unread
    • First observedemail_move_or_label
    • First observedemail_read_message
    • First observedemail_resolve_folder
    • First observedemail_resolve_message
    • First observedemail_send
    • First observedemail_send_draft
    • First observedemail_trash
    • First observedemail_update_draft
    • First observedemail_update_folder
    • First observedfeedback_report_bug
    • First observedfeedback_request_feature
    • First observedimap_connect
    • First observedinstagram_get_my_profile
    • First observedinstagram_get_profile
    • First observedinstagram_list_conversations
    • First observedinstagram_list_followers
    • First observedinstagram_list_following
    • First observedinstagram_read_conversation
    • First observedinstagram_send_message
    • First observedinstagram_update_my_profile
    • First observedlinkedin_accept_invitation
    • First observedlinkedin_cancel_or_refuse_invitation
    • First observedlinkedin_classic_get_applicant_resume
    • First observedlinkedin_classic_get_job_applicant
    • First observedlinkedin_classic_list_job_applicants
    • First observedlinkedin_comment_on_post
    • First observedlinkedin_create_post
    • First observedlinkedin_endorse_skill
    • First observedlinkedin_follow_user
    • First observedlinkedin_get_company
    • First observedlinkedin_get_inmail_credits
    • First observedlinkedin_get_job_posting
    • First observedlinkedin_get_job_posting_budget
    • First observedlinkedin_get_my_profile
    • First observedlinkedin_get_post
    • First observedlinkedin_get_profile
    • First observedlinkedin_get_profile_from_url
    • First observedlinkedin_get_search_parameters
    • First observedlinkedin_list_comment_replies
    • First observedlinkedin_list_contracts
    • First observedlinkedin_list_conversations
    • First observedlinkedin_list_followers
    • First observedlinkedin_list_following
    • First observedlinkedin_list_inbox_chats
    • First observedlinkedin_list_inboxes
    • First observedlinkedin_list_invitations
    • First observedlinkedin_list_job_postings
    • First observedlinkedin_list_managed_company_pages
    • First observedlinkedin_list_my_connections
    • First observedlinkedin_list_post_comments
    • First observedlinkedin_list_post_reactions
    • First observedlinkedin_list_user_posts
    • First observedlinkedin_list_user_relations
    • First observedlinkedin_react_to_message
    • First observedlinkedin_react_to_post
    • First observedlinkedin_read_conversation
    • First observedlinkedin_recruiter_get_applicant
    • First observedlinkedin_recruiter_get_applicant_resume
    • First observedlinkedin_recruiter_list_applicants
    • First observedlinkedin_recruiter_search_people
    • First observedlinkedin_remove_connection
    • First observedlinkedin_reply_to_comment
    • First observedlinkedin_resolve_company
    • First observedlinkedin_resolve_my_post
    • First observedlinkedin_resolve_person
    • First observedlinkedin_sales_navigator_search_people
    • First observedlinkedin_search_companies
    • First observedlinkedin_search_from_url
    • First observedlinkedin_search_jobs
    • First observedlinkedin_search_people
    • First observedlinkedin_search_posts
    • First observedlinkedin_select_contract
    • First observedlinkedin_send_invitation
    • First observedlinkedin_send_message
    • First observedlinkedin_start_conversation
    • First observedlinkedin_start_conversation_from_inbox
    • First observedlinkedin_submit_company_member_otp
    • First observedlinkedin_unfollow_user
    • First observedlinkedin_update_my_profile
    • First observedlinkedin_verify_company_member_email
    • First observedlinkedin_visit_profile
    • First observedlist_connected_accounts
    • First observedmessage_add_reaction
    • First observedmessage_delete
    • First observedmessage_edit
    • First observedmessage_forward
    • First observedmessage_get
    • First observedmessage_list_reactions
    • First observedmessage_mark_read
    • First observedmessage_remove_reaction
    • First observedmessage_resolve_chat
    • First observedmessage_send_native_media
    • First observedmessage_send_voice_note
    • First observedmessaging_find_chat_by_user
    • First observedmessaging_list_chats
    • First observedmessaging_list_messages
    • First observedmessaging_resolve_recipient
    • First observedmessaging_send_message
    • First observedmessaging_send_to_contact
    • First observedmessaging_set_chat_state
    • First observedmessaging_set_composing
    • First observedmessaging_set_presence
    • First observedmessaging_start_chat
    • First observedsocial_delete_comment
    • First observedsocial_delete_post
    • First observedsocial_list_comment_reactions
    • First observedsocial_react_to_comment
    • First observedsocial_remove_comment_reaction
    • First observedsocial_remove_post_reaction
    • First observedsocial_resolve_comment
    • First observedsocial_update_comment
    • First observedsocial_update_post
    • First observedteam_add_seats
    • First observedteam_invite_member
    • First observedtelegram_connect
    • First observedwebhook_create_destination
    • First observedwebhook_delete_destination
    • First observedwebhook_get_delivery_logs
    • First observedwebhook_get_destination
    • First observedwebhook_get_setup_guide
    • First observedwebhook_list_available_events
    • First observedwebhook_list_destinations
    • First observedwebhook_test_destination
    • First observedwebhook_update_destination
    • First observedwhatsapp_connect
    • First observedwhatsapp_get_profile
    • First observedwhatsapp_is_number_registered
    • First observedwhatsapp_list_contacts
    • First observedwhatsapp_list_conversations
    • First observedwhatsapp_read_conversation
    • First observedwhatsapp_send_message
    • First observedwhatsapp_start_conversation

Publisher details

Operator
Nilyo · Publisher source
Vendor relationship
First-party · Publisher source
Restrictions
Requires a Nilyo account (created during the OAuth flow, 7-day free trial, no card; paid plans afterwards at https://nilyo.com/pricing). Users connect their own provider accounts (LinkedIn, WhatsApp, Instagram, Telegram, Gmail, Outlook, IMAP, calendars). No admin approval, no custom OAuth app to create, no regional limit beyond ChatGPT/Claude availability.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to manage social media accounts and CRM operations, including posting, analytics, inbox management, and customer management.
    22
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    Your real mailbox and calendar for your AI agent — Microsoft 365 via Graph or any IMAP — as 24 tools: read, search, attachments as text, sender history, drafting from identity and knowledge files, free-slot computation. Send, reply, delete and calendar writes need out-of-band human approval: the agent cannot approve its own actions.
    29
    326 PyPI
    5
    AGPL 3.0
  • A
    license
    A
    quality
    B
    maintenance
    Lets any AI agent post to TikTok, Instagram, YouTube, X, LinkedIn, Bluesky, Telegram, Mastodon and Discord through a single post_to_social tool. Connect an account once, then publish everywhere.
    2
    127 npm
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources