Skip to main content
Glama

Query people

query_people
Read-only

Columns: id, display_name, title, headline, company, location, timezone, summary, linkedin_slug, linkedin_provider_id, email, mail_host, connections_count, follower_count, is_open_profile, is_premium, work_experience (JSONB), education (JSONB), linkedin_looked_up_at, company_profile_id, owner_email, data (JSONB), created_at, updated_at. company_profile_id is the person's canonical employer FK (NULL when unresolved). Sliq's CRM is deals and tasks: to see whether someone has a deal or a task, use query_deals (status='all') / query_crm_tasks with person_id. mail_host is the email provider hosting this person's address (Google Workspace, Microsoft 365, …), read from their domain's MX record: google, microsoft, gateway, other, unknown (no mail record, or the domain's DNS is broken), or '' with no email or no successful lookup yet. gateway means a security gateway (Mimecast, Proofpoint) receives the mail first, which hides the provider behind it. timezone is the IANA time zone the person is in (such as America/Los_Angeles): one set by hand, else the one their location names. It is '' when unknown: they have no location, it names no single zone (a country spanning several), or it isn't classified yet. For a prospect, set it with update_prospect's timezone when you know where they are. connections_count / follower_count are NULL when never fetched (not 0); is_open_profile / is_premium are NULL likewise. JSONB queries: data->>'some_key' ILIKE '%...%'.

work_experience and education are the person's full LinkedIn employment and education history — the same arrays enrich_linkedin_profiles returns, already stored on the person from the last profile lookup, so reading them here costs nothing (answer "where did they go to school", "are they an LSU alum", "how long in seat" from these instead of a fresh enrich). Each is a list, in LinkedIn display order (NOT sorted by date). linkedin_looked_up_at is when the person's full LinkedIn profile was first looked up: NULL means it never was, and a time with empty lists means LinkedIn had no history to give. These arrays are large for senior people — a broad limit=200 read that returns them can exceed the 50KB direct-return cap and truncate; for a wide pull, either narrow the where_clause or call this from run_code (nothing truncates there) and print only the fields you need.

To list the outreach prospects tracking a person, take an id from here and call query_prospects with where_clause="person_id = <id>".

Each row also carries segments: the person's segment tags across every segment group they're classified into — [{group_id, group_name, tag}], tag 'No match' where the classifier couldn't place them (empty when no group has classified them). Segments are the LLM-defined people dimensions from the Explore Segments surface (e.g. Seniority -> VP); manage them with the segment tools (list_segment_groups etc.).

Each row also carries degree: the user's LinkedIn degree to the person, '1', '2', '3' or 'out_of_network', null when unknown — from the user's synced LinkedIn connections and what every one of their campaigns' searches and lookups recorded. A person the user is connected to reads '1'. It is the degree the person's profile shows beside their name.

For how many people are in each title, company, location, outreach stage or segment, or who is in one of those groups, call list_people: it reads the People table the way the user sees it, over everyone without paging for the counts. A dict with count, truncated, and items array (each row {id, display_name, title, headline, company, location, timezone, summary, linkedin_slug, linkedin_provider_id, email, mail_host, connections_count, follower_count, is_open_profile, is_premium, work_experience, education, linkedin_looked_up_at, company_profile_id, owner_email, segments: [{group_id, group_name, tag}], degree, data, created_at, updated_at}).

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "query_people"
  }
}

Input Schema

NameRequiredDescriptionDefault
limitNoMax results (default 50, capped at 200).
offsetNoRows to skip for paging (default 0). When the result is truncated, re-call with offset += limit for the next page.
order_byNoSQL ORDER BY (default: created_at DESC).created_at DESC
on_behalf_ofNoA teammate's email, or an agency client's from list_agency_clients, to run this call in that account: their agents, settings, connected accounts, and credits. Omit it to act on your own account.
where_clauseNoSQL WHERE condition (default: all your people). Examples: "display_name ILIKE '%chen%'", "title ILIKE '%VP%'", "company_profile_id = 42", "linkedin_slug = 'some-slug'".1=1

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / on_behalf_of / description
      Previous value: -"An agency client's email, from list_agency_clients, to run this call in that client's account: their agents, settings, connected accounts, and credits. Omit it to act on your own account."New value: +"A teammate's email, or an agency client's from list_agency_clients, to run this call in that account: their agents, settings, connected accounts, and credits. Omit it to act on your own account."
  2. Changed1 schema field changed
    • changedInput schema / properties / where_clause / description
      Previous value: -"SQL WHERE condition (default: all your people). Examples:\n\"display_name ILIKE '%chen%'\", \"title ILIKE '%VP%'\",\n\"company_profile_id = 42\", \"linkedin_url = 'some-slug'\"."New value: +"SQL WHERE condition (default: all your people). Examples:\n\"display_name ILIKE '%chen%'\", \"title ILIKE '%VP%'\",\n\"company_profile_id = 42\", \"linkedin_slug = 'some-slug'\"."
  3. Changed2 schema fields changed
    • removedInput schema / properties / group_by
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "enum": [
      -        "title",
      -        "company",
      -        "location",
      -        "outreach_stage",
      -        "segment"
      -      ],
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that column's value; \"outreach_stage\" by the person's collapsed lead-funnel bucket;\n\"segment\" by the person's tag in the `segment_group_id` group. Omit for the row list."
      -}
    • removedInput schema / properties / segment_group_id
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "integer"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Required with group_by=\"segment\" — the segment group (from\nlist_segment_groups) to bucket by. Ignored otherwise."
      -}
  4. Changed1 schema field changed
    • addedInput schema / properties / on_behalf_of
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "An agency client's email, from list_agency_clients, to run this call in that client's account: their agents, settings, connected accounts, and credits. Omit it to act on your own account."
      +}
  5. Changed1 schema field changed
    • changedInput schema / properties / group_by / description
      Previous value: -"Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that firmographic — \"title\" falls back to the headline when the title is blank, so\nlist a title bucket's people with \"COALESCE(NULLIF(title, ''), headline) = '<key>'\";\n\"outreach_stage\" by the person's collapsed lead-funnel bucket;\n\"segment\" by the person's tag in the `segment_group_id` group. Omit for the row list."New value: +"Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that column's value; \"outreach_stage\" by the person's collapsed lead-funnel bucket;\n\"segment\" by the person's tag in the `segment_group_id` group. Omit for the row list."
  6. Changed1 schema field changed
    • changedInput schema / properties / group_by / description
      Previous value: -"Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that firmographic; \"outreach_stage\" by the person's collapsed lead-funnel bucket;\n\"segment\" by the person's tag in the `segment_group_id` group. Omit for the row list."New value: +"Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that firmographic — \"title\" falls back to the headline when the title is blank, so\nlist a title bucket's people with \"COALESCE(NULLIF(title, ''), headline) = '<key>'\";\n\"outreach_stage\" by the person's collapsed lead-funnel bucket;\n\"segment\" by the person's tag in the `segment_group_id` group. Omit for the row list."
  7. Changed3 schema fields changed
    • changedInput schema / properties / group_by / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "title",
      -      "company",
      -      "location",
      -      "outreach_stage"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "title",
      +      "company",
      +      "location",
      +      "outreach_stage",
      +      "segment"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / group_by / description
      Previous value: -"Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that firmographic; \"outreach_stage\" by the person's collapsed lead-funnel bucket.\nOmit for the row list."New value: +"Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that firmographic; \"outreach_stage\" by the person's collapsed lead-funnel bucket;\n\"segment\" by the person's tag in the `segment_group_id` group. Omit for the row list."
    • addedInput schema / properties / segment_group_id
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Required with group_by=\"segment\" — the segment group (from\nlist_segment_groups) to bucket by. Ignored otherwise."
      +}
  8. Changed1 schema field changed
    • addedInput schema / properties / group_by
      Added value: +{
      +  "anyOf": [
      +    {
      +      "enum": [
      +        "title",
      +        "company",
      +        "location",
      +        "outreach_stage"
      +      ],
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Aggregate mode, returned instead of the row list — whole-set per-bucket counts\nover all your people (not capped by `limit`). \"title\" / \"company\" / \"location\" bucket\nby that firmographic; \"outreach_stage\" by the person's collapsed lead-funnel bucket.\nOmit for the row list."
      +}
  9. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the read-only annotation, the description discloses many behavioral details: NULL semantics for counts and profile flags, `mail_host` enum meanings, timezone resolution, LinkedIn array ordering, and the 50KB direct-return truncation risk with a `run_code` workaround. It also explains that `segments` and `degree` are computed fields included on each row.

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 front-loaded and organized around purpose, alternatives, column semantics, and return shape. Most detail earns its place for such a field-rich query tool, though the full column list and some field explanations could be trimmed without losing selection-critical information.

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 tool's complexity and lack of a formal output schema, the description is complete: it includes a returns block, explains computed fields like `segments` and `degree`, covers NULL and empty-value semantics, and warns about truncation. An agent has enough information to query, filter, and interpret results 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 schema already documents the five parameters, but the description adds useful query-building guidance beyond it: JSONB filtering via `data->>'some_key' ILIKE '%...%'`, narrowing `where_clause` for wide pulls, and using `run_code` when a `limit=200` read would truncate. It does not add much for `on_behalf_of` or `order_by`, but it meaningfully supplements the filter and paging behavior.

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: query canonical `person_profiles`, one deduped row per real person. It explicitly distinguishes the tool from `query_prospects` by explaining that prospects are per-owner tracking rows while people are canonical entities, so an agent can select it confidently.

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 concrete usage examples such as 'is <name> someone we know' and 'people who are VPs at fintech companies', and explicitly routes outreach-stage questions to `query_prospects`, deal/task questions to `query_deals`/`query_crm_tasks`, and aggregate/count questions to `list_people`. This is explicit 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.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources