MCP tools
The Avtrz MCP server exposes three read-only tools. get_profile_avatar returns a real profile photo inline (plus a ready-to-paste imageUrl); get_profile returns structured person data plus Markdown; and get_publishable_key returns the workspace's avatar key and a URL template for building durable image URLs.
The two lookup tools (get_profile_avatar, get_profile) accept exactly one of linkedin_url or username. All three are annotated readOnlyHint: true, destructiveHint: false, openWorldHint: false, so clients can call them freely without a write-confirmation prompt. See Working image URLs on the overview for why agents can emit durable Avtrz <img> URLs that render anywhere.
get_profile_avatar
Fetch the avatar image for a business profile by LinkedIn URL or username. Returns the photo as an inline image. While the avatar is still being enriched, it returns deterministic initials art and the URL where the final image will appear.
Input
| Name | Type | Description | |
|---|---|---|---|
| linkedin_url | string (URL) | Optional | Full LinkedIn profile URL, e.g. https://www.linkedin.com/in/janedoe. Pass exactly one of linkedin_url or username. |
| username | string | Optional | LinkedIn vanity username (the slug after /in/), e.g. janedoe. |
| size | enum | Optional | Avatar dimensions in pixels (square): one of 32, 64, 128, 256, 512. Defaults to 256. |
Output
Alongside the inline image, the tool returns structuredContent.imageUrl: a durable, ready-to-use Avtrz image URL built from the workspace's publishable key (https://avtrz.dev/v1/avatar?key=pk_…&linkedin_url=…&size=…). This is the fast path for "give me a URL I can paste" — drop it straight into a CRM, doc, email, or <img> tag and it renders immediately, no base64 handling. The inline image is for showing the face in-chat; the imageUrl is for embedding it elsewhere. If the publishable key can't be resolved, the tool still returns the inline image and simply omits imageUrl.
- Resolved (cache hit / ready): an inline
imagecontent block with the avatar bytes, atextblock carrying the stable CDN URL plus the embeddable URL, andstructuredContent.imageUrl. - Enriching (queued / fallback): an inline
imageblock containing the deterministic initials SVG, plus atextblock telling the model the avatar is being enriched and where the final image will appear shortly (theimageUrlresolves once enrichment lands).structuredContent.imageUrlis still returned. The tool never polls — call again in a moment. - No avatar: an error text block — the profile picture could not be found.
- Quota exhausted: an error text block — monthly avatar quota exceeded for this workspace.
Example
Prompt: "Show me Jane Doe's photo — here's her LinkedIn: …"
{
"name": "get_profile_avatar",
"arguments": {
"linkedin_url": "https://www.linkedin.com/in/janedoe",
"size": 256
}
}{
"content": [
{ "type": "image", "data": "<base64 bytes>", "mimeType": "image/webp" },
{
"type": "text",
"text": "Avatar for janedoe: https://cdn.avtrz.dev/…\nEmbeddable URL: https://avtrz.dev/v1/avatar?key=pk_…&linkedin_url=https://www.linkedin.com/in/janedoe&size=256"
}
],
"structuredContent": {
"imageUrl": "https://avtrz.dev/v1/avatar?key=pk_…&linkedin_url=https://www.linkedin.com/in/janedoe&size=256"
}
}get_profile
Fetch enriched business-profile data — name, headline, summary, industry, location, profile picture URL, open-to-work — for a person by LinkedIn URL or username. If the profile hasn't been enriched yet, it enqueues enrichment and asks the caller to retry.
Input
| Name | Type | Description | |
|---|---|---|---|
| linkedin_url | string (URL) | Optional | Full LinkedIn profile URL. Pass exactly one of linkedin_url or username. |
| username | string | Optional | LinkedIn vanity username (the slug after /in/). |
Output
- Profile found: a
structuredContentobject plus atextblock rendering it as Markdown. - Enrichment queued: a
textblock telling the model data will be available shortly — Avtrz has already kicked off enrichment, so the model should retry. - No profile: an error text block — the profile could not be found.
- Quota exhausted: an error text block — monthly profile quota exceeded for this workspace.
The structuredContent shape deliberately omits internal identifiers (provider/entity URNs, raw payloads). Read-only callers never see secrets or internal IDs.
{
"linkedin_url": "https://www.linkedin.com/in/janedoe",
"username": "janedoe",
"first_name": "Jane",
"last_name": "Doe",
"headline": "VP Engineering at Acme",
"summary": "Building reliable infra…",
"industry": "Software",
"location": "San Francisco, CA, United States",
"picture_url": "https://cdn.avtrz.dev/…",
"open_to_work": false,
"premium": true,
"verified": true
}Example
Prompt: "Who is janedoe on LinkedIn? Give me their role and location."
{
"name": "get_profile",
"arguments": { "username": "janedoe" }
}get_publishable_key
Return the workspace's publishable avatar key and a ready-to-fill URL template, so the model can build durable image URLs without calling get_profile_avatar per person. Read-only and takes no input — the key is provisioned server-side when you connect, and this tool just reads it back. Use it when a user asks for "a URL I can paste" or wants <img> URLs for a whole list of people at once.
Output
A text block with the URL template and instructions, plus structuredContent:
| Name | Type | Description | |
|---|---|---|---|
| publishable_key | string | Optional | The workspace's unrestricted publishable key (pk_…). Never a secret (sk_) key — the server refuses to return anything that isn't publishable. |
| url_template | string | Optional | https://avtrz.dev/v1/avatar?key=<pk>&linkedin_url=<LINKEDIN_URL>&size=128. Replace <LINKEDIN_URL> with a full LinkedIn URL (or swap to username=<USERNAME>) and set size. |
| sizes | array | Optional | The accepted square sizes: [32, 64, 128, 256, 512]. |
| note | string | Optional | The plain-language caveat about how the key behaves. |
{
"publishable_key": "pk_…",
"url_template": "https://avtrz.dev/v1/avatar?key=pk_…&linkedin_url=<LINKEDIN_URL>&size=128",
"sizes": [32, 64, 128, 256, 512],
"note": "This is your workspace's unrestricted publishable key. Embed it in avatar URLs to render images anywhere (CRMs, docs, emails, sites). Anyone with a URL can use it against this workspace's avatar quota, so treat it like a public token. Revoke or rotate it any time from the avtrz dashboard under API keys."
}The key caveat
The MCP key is unrestricted by design — no domain firewall — so the avatar URLs render from any context (CRMs, server-side image fetchers, static sites) that can't send a Referer. The trade-off:
- Anyone holding a URL can draw on this workspace's avatar quota — treat the key like a public token, not a secret.
- It is publishable only (
pk_). A secret key is never exposed over MCP. - It is revocable any time from the dashboard under API keys; it does not expire on its own.
Member-role caveat
The key is provisioned server-side under a workspace owner or admin (only those roles can create API keys). If a plain member connects, Avtrz provisions the shared key under an available owner/admin automatically. But if a member-only workspace has no owner or admin to provision under, the tool returns an actionable error instead of a key:
Retrying won't help — a workspace owner or admin must connect once to mint the shared key.
Example
Prompt: "Get me paste-ready avatar URLs for these three people: janedoe, johndoe, samlee." The model fetches the key once, then templates working <img> URLs for the whole list — no per-person tool call.
{
"name": "get_publishable_key",
"arguments": {}
}<img src="https://avtrz.dev/v1/avatar?key=pk_…&linkedin_url=https://www.linkedin.com/in/janedoe&size=128" /> <img src="https://avtrz.dev/v1/avatar?key=pk_…&linkedin_url=https://www.linkedin.com/in/johndoe&size=128" /> <img src="https://avtrz.dev/v1/avatar?key=pk_…&linkedin_url=https://www.linkedin.com/in/samlee&size=128" />
Quota and billing
The lookup tools meter the workspace the connection is bound to — there is no separate MCP billing:
- Every metered tool call is written to the same
avatarRequestanalytics theGET /v1/avatarAPI uses, so MCP traffic appears in your dashboard alongside API traffic. - Every
get_profile_avatar/get_profilecall consumes oneavatar_requestsunit — whether or not a photo is resolved, since the request quota is checked and metered before the cache lookup. A profile your workspace hasn't looked up before also counts againstavatar_new_profiles. get_publishable_keytakes no input and doesn't hit the avatar pipeline, so it isn't metered.- Rate limits bucket per user, not per connection: the limiter keys off your user identity (
mcp:<userId>), so all of one user's connections and sessions share a single bucket. If a call is rate-limited, the tool returns the limit message and the number of seconds to wait before retrying.
Errors and edge cases
| Name | Type | Description | |
|---|---|---|---|
| Both / neither lookup field | validation | Optional | Validation error: Pass exactly one of linkedin_url or username. |
| Still enriching | retry | Optional | get_profile_avatar returns initials art + the future CDN URL; get_profile returns "enrichment queued". Retry shortly. |
| Not found | error | Optional | Error text: the avatar / profile could not be found. |
| Quota exhausted | error | Optional | Error text: quota exceeded for this workspace. The connection stays valid. |
| Rate-limited | error | Optional | Error text with a Retry after Ns hint. |
| Token expired / revoked | auth | Optional | Tool returns Not authenticated. Reconnect the connector. |