linkedin-mcp
This server lets you manage your own LinkedIn profile through an MCP agent, with a strict propose-then-approve flow so the model can draft changes but only write after you approve.
Authenticate with LinkedIn using your own developer app (
auth_start,auth_status).Read your profile data (
get_profile).Draft profile edits (headline, summary, positions, skills, educations) without writing to LinkedIn (
propose_edit), returning a diff and proposal ID.List saved proposals (
list_proposals) and delete rejected or unwanted ones (discard_proposal).Apply a single proposal to LinkedIn — the only write tool — only when you supply the exact approval phrase after reviewing the diff (
apply_proposal).Store proposals locally so approvals can happen in later sessions.
Note: the final write requires LinkedIn partner approval; until then,
apply_proposalmay return an invalid-scope error.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@linkedin-mcpDraft a proposal to update my LinkedIn headline to 'Senior Product Manager'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
linkedin-mcp
MCP server for editing your own LinkedIn profile from Claude Code — with a hard propose-then-approve split: the model can draft a change and show you the diff, but only one tool can ever write, and it acts only on a proposal you have seen.
Read this before you install
1. You bring your own LinkedIn app. There is no shared or hosted service
here. You create your own app at
linkedin.com/developers/apps, and
your own client ID and secret go in a file on your own machine
(~/.config/linkedin-mcp/.env, permissions 600). The server itself makes no
outbound call to anything but LinkedIn's own API — there is no telemetry and
no third party. Note that it is still an MCP server: profile data and diffs it
returns go to whichever agent you connect, so if that agent is cloud-backed,
your profile content reaches that provider like any other chat content. See
PRIVACY.md.
2. Writing to your profile needs LinkedIn partner approval — which you must
apply for yourself. LinkedIn's Profile Edit API is restricted to
LinkedIn-approved partner developers (w_compliance is "a private permission
and access is granted to select developers" — see
docs/api-notes.md). Approval is granted per developer app,
so your app needs your approval; nobody else's carries over. Until
it lands, apply_proposal returns an invalid-scope error. That is expected,
not a defect — and it may never land, since the permission goes to "select
developers".
Everything else works today without partner approval: OAuth sign-in, reading your profile, drafting edits, and reviewing diffs. Only the final write is gated.
Related MCP server: kaushik-linkedin-mcp
How it works
Tool | What it does | Writes to LinkedIn? |
| Prints the LinkedIn OAuth URL, catches the one-shot localhost redirect, exchanges the code, stores tokens | no (OAuth only) |
| Reports whether a token exists and when it expires | no |
| Fetches your profile ( | no |
| Builds the exact API request for a change (headline, summary, positions, skills, educations), saves it as a proposal, returns a unified diff + | never |
| Lists saved proposals | no |
| Deletes a saved proposal | no |
| Sends ONE saved proposal to LinkedIn — the only write tool. Code-enforced confirm gate: it refuses unless called with | yes |
Proposals persist under ~/.config/linkedin-mcp/proposals/ so an approval
can happen in a later session. Tokens and client credentials live in
~/.config/linkedin-mcp/.env with permissions 600 — entered by you, never
by an agent, never committed (see .env.example).
Install
Requires Python ≥ 3.11. Clone the repo, then register it as an MCP server in
your agent — add this to your client's MCP config (for Claude Code that is
~/.claude.json, or run claude mcp add linkedin -- bash /path/to/linkedin-mcp/run.sh):
{
"mcpServers": {
"linkedin": {
"command": "bash",
"args": ["/path/to/linkedin-mcp/run.sh"]
}
}
}Replace /path/to/linkedin-mcp with the absolute path to your clone. run.sh
creates .venv/ and installs pinned dependencies on first launch (stamp-gated;
all bootstrap output goes to stderr, keeping the MCP stdio channel clean).
Then follow docs/SETUP.md to create your LinkedIn app and sign in — the server has no credentials until you do.
Setup
Follow docs/SETUP.md — it walks through creating your own
LinkedIn Developer app, registering the redirect URL, filling
~/.config/linkedin-mcp/.env with your own client ID and secret, running
auth_start, and applying for the partner program.
Development
bash run.sh --help # bootstraps the venv (runtime deps only)
.venv/bin/pip install -r requirements-dev.txt # adds pytest + coverage tooling
.venv/bin/python -m pytest # offline — every test runs against a mock transportThe test suite includes a granted-write fixture: a mock LinkedIn where
every documented write endpoint happily returns 200. Tests assert that
propose_edit leaves zero non-GET requests in the recorded log even
when writes would succeed, and (positive control) that apply_proposal does
record the documented write call in the same fixture. --live-probe is a
diagnostic flag (single real request, discriminates "endpoint right but
scope not granted" from "endpoint wrong"); it never runs in tests or CI and
requires LINKEDIN_MCP_LIVE_PROBE=1.
The API surface is pinned to dated verbatim excerpts from the official docs in docs/api-notes.md.
License
MIT — see LICENSE.
Available Tools
7 toolsapply_proposalA
THE ONLY TOOL THAT WRITES TO LINKEDIN. Sends the single prepared request stored in one proposal. Requires the human to have approved the returned diff in chat first — never call it on your own initiative, and never immediately after propose_edit without that approval. The approval is code-enforced: the 'approval' argument must be exactly 'approve ', supplied only after the human has seen the diff and said yes in chat. Until LinkedIn grants partner access to the Profile Edit API, an invalid-scope / permission error here is EXPECTED and is not a defect: report it plainly and stop, do not attempt any workaround.
| Name | Required | Description | Default |
|---|---|---|---|
| approval | No | ||
| proposal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the mutation side effect (writes to LinkedIn), the code-enforced approval format that must match exactly, the expectation of invalid-scope/permission errors until LinkedIn grants API access, and the instruction to report errors plainly without workarounds. This is exceptional transparency for a write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each dense with purpose. The critical differentiator is front-loaded, followed by the approval gating and error-handling context. There is zero filler; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no annotations, the description covers the full operational context: the single-write constraint, the mandatory human approval with exact argument format, the expected error condition and correct response (report and stop), and the relationship to propose_edit. With an output schema available to describe return values, nothing essential is missing 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Given schema description coverage is 0%, the description must fully explain parameter meaning. It does for 'approval' by specifying the exact string format ('approve <proposal_id>') and its role in the approval flow. For 'proposal_id', it links it to 'the single prepared request stored in one proposal', conveying its purpose, although it doesn't explicitly state where to obtain it (though imply it via propose_edit). This is sufficient value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'THE ONLY TOOL THAT WRITES TO LINKEDIN', which immediately identifies the unique action (write) and resource (LinkedIn) while distinguishing it from every sibling. It then specifies it sends the single prepared request stored in one proposal, making the verb and object unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states the precondition (human approval of the diff) and the prohibition against calling it on your own initiative or immediately after propose_edit without approval. This clearly delineates when to use it vs. alternatives like propose_edit, which creates the proposal that this tool then applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
auth_startA
Run the LinkedIn OAuth sign-in. Opens the consent page in a browser, catches the one-shot localhost redirect, exchanges the code, and stores the token in the owner-only config file (0600). Does NOT modify the profile. Returns only non-secret token status — never the token itself. Set url_only=true to just print the authorization URL without starting the listener.
| Name | Required | Description | Default |
|---|---|---|---|
| url_only | No | ||
| timeout_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden — and it delivers. It discloses side effects (consent page, redirect listener, code exchange, token storage in owner-only 0600 config), explicit non-effects (does not modify profile), and security posture (returns only non-secret status, never the token). This is rich, safety-relevant behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense yet efficient; it front-loads the core purpose and then packs flow details, security caveats, and the alternate mode into a tight sequence of sentences. No word is wasted, and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value structure is already covered. The description handles the flow, the url_only alternate mode, and the critical security behavior (never returning the token). The only notable gap is the unexplained timeout_seconds parameter, which leaves a small but real hole in completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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. It fully explains url_only ('just print the authorization URL without starting the listener'), adding real meaning beyond the schema's default. However, timeout_seconds is left entirely unexplained in both schema and description — a genuine gap given no coverage exists anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Run the LinkedIn OAuth sign-in') with a precise breakdown of the flow: opens consent page, catches redirect, exchanges code, stores token. The sentence 'Does NOT modify the profile' distinguishes it from profile-editing siblings like propose_edit and apply_proposal. This clearly differentiates it from auth_status, which merely reports status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for the primary OAuth startup flow and explicitly explains the url_only=true alternate mode ('just print the authorization URL without starting the listener'). However, it does not explicitly route the agent to auth_status for checking existing auth state, though the 'Does NOT modify the profile' statement offers a weak exclusion against profile tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
auth_statusA
Report whether a LinkedIn access token is stored and when it expires. Reads local config only: no network call, no profile change, and the token value is never returned.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states that it reads local config only, makes no network call, causes no profile change, and never returns the token value. This is a thorough disclosure of its operational limits and side effects, leaving no ambiguity about its safety and read-only nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, front-loaded with the primary purpose ('Report whether...') followed by critical behavioral constraints. Every clause adds value, with no waste or redundancy. The structure is efficient and immediately actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and an output schema exists (so return values are handled externally), the description is complete for an agent to call it correctly. It covers what, how, and safety considerations. The only omission is usage timing relative to siblings, but that is adequately covered by usage guidance and does not detract from completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline of 4 applies. The description does not need to explain parameters because there are none. The schema is trivially complete at 100% coverage, and the description adds no parameter-related information, which is appropriate given the absence of parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb 'Report' and specifies the resource: 'whether a LinkedIn access token is stored and when it expires.' It clearly distinguishes this tool from siblings like auth_start (which would initiate authentication) and get_profile (which retrieves profile data). The scope is well-defined.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states 'Reads local config only: no network call, no profile change' which implies it is a safe, read-only check, but it does not explicitly name alternatives or exclusions. The context is clear enough that an agent would infer this is for checking auth status before proceeding, but it could be more explicit about when to use it versus auth_start.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
discard_proposalA
Delete a saved proposal that the human rejected or that is no longer wanted. Local file removal only — it never touches LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| proposal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states that the tool is destructive ('Delete'), scopes behavior to local file removal only, and explicitly excludes external action (LinkedIn). This covers the key behavioral aspects for a simple deletion tool, though it doesn't mention reversibility or side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the core action ('Delete a saved proposal'), then adds relevant conditions and scope. There is no wasted wording; every part adds value, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter delete tool with an output schema present, the description is sufficiently complete. It covers purpose, conditions, and scope. It doesn't detail error handling or edge cases, but those are not essential for basic usage. The scope and behavior are well communicated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single parameter 'proposal_id', but the description implies the parameter is the identifier of the proposal to delete. It doesn't add explicit details about the parameter, but the intuitive meaning is clear from the context. Since there's only one parameter, the description's implication partially compensates for the lack of schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation ('Delete a saved proposal') and specifies the resource and conditions ('that the human rejected or that is no longer wanted'). It explicitly distinguishes from siblings by noting 'Local file removal only — it never touches LinkedIn,' preventing confusion with apply_proposal or other LinkedIn-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool (when a proposal is rejected or unwanted) and clarifies what it does not do (never touches LinkedIn). It implicitly differentiates from apply_proposal (which would send to LinkedIn) and propose_edit (which edits). It could be stronger by naming alternatives, but the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_profileA
Fetch the owner's LinkedIn profile with GET /v2/me. Read-only — it cannot change anything. Use it to get the person id and current values before calling propose_edit.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are absent, so the description carries the full burden of behavioral disclosure. It explicitly states 'Read-only — it cannot change anything,' which is the key behavioral trait an agent needs. It also mentions the HTTP method (GET), adding useful implementation context, though it does not discuss authentication or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no wasted words. The primary action and read-only guarantee are front-loaded, and the usage guidance is appended in a single clause. Every piece of information earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no parameters and an output schema present, the description is complete: it names the resource, declares side-effect safety, and explains its role in the edit workflow. No missing information prevents an agent from calling it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema description coverage is 100% (vacuously). Per the rubric, a baseline of 4 applies to 0-parameter tools; the description does not need to add parameter details and doesn't.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch'), a specific resource ('the owner's LinkedIn profile'), and even includes the API endpoint (GET /v2/me). It also clarifies its role relative to a sibling ('before calling propose_edit'), effectively distinguishing it from the editing tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when to use this tool — 'get the person id and current values before calling propose_edit' — providing a concrete use case and sequence. It does not explicitly mention when not to use it or name alternative access tools like auth_status, but its position in the edit workflow is implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_proposalsA
List saved edit proposals with their diffs. Local read only — no network call and no profile change. Set include_applied=true to also show proposals that have already been sent.
| Name | Required | Description | Default |
|---|---|---|---|
| include_applied | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It explicitly discloses that the tool is local, read-only, makes no network call, and doesn't alter the profile. This transparently conveys the non-destructive nature. It doesn't mention error behavior or sorting, but for a read-only list tool this coverage is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no filler. The primary purpose is front-loaded, followed by the read-only note and the parameter explanation. Every sentence earns its place and the structure is easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 optional parameter and an output schema present, the description is complete. It explains purpose, behavior, and the parameter. No additional information is needed 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite schema coverage of 0%, the description directly explains the only parameter: 'Set include_applied=true to also show proposals that have already been sent.' This adds clear meaning beyond the schema's bare 'Include Applied' title, enabling correct usage without needing to inspect the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action (list) and resource (saved edit proposals) along with what's included (their diffs). It distinguishes itself from sibling tools like propose_edit, apply_proposal, and discard_proposal by being the read-only listing operation, leaving no ambiguity about its role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use it: 'Local read only — no network call and no profile change' indicates it's for inspecting proposals without side effects. However, it doesn't explicitly state when not to use it or name alternatives, so it lacks direct exclusions, but the context is sufficient for an agent to infer its usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
propose_editA
Draft a profile change WITHOUT sending it. This tool NEVER writes to LinkedIn: it builds the exact API request, saves it as a proposal, and returns a unified diff of the current value versus the proposed one for human review. Show the diff to the human and wait for their approval; only then may apply_proposal be called with the returned proposal_id. section: headline | summary | position | skill | education. changes: for headline/summary use {'text': '...'}; for position/skill/education use {'action': 'create'|'update'|'delete', 'entity_id': '' (for update/delete), 'fields': {...}}. Localized text fields (skill name, position title/companyName/description, education schoolName/degreeName/...) may be given as plain strings — they are wrapped in LinkedIn's documented MultiLocale shape for the chosen locale.
| Name | Required | Description | Default |
|---|---|---|---|
| locale | No | en_US | |
| changes | Yes | ||
| section | Yes | ||
| person_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden. It clearly states the tool does not write, builds a request, saves a proposal, and returns a diff. It also discloses localization handling for text fields. It does not mention idempotency or error cases, but the non-destructive nature is well communicated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is fairly long but every sentence adds value. It front-loads the core behavioral guarantee, then explains the parameter formats, and ends with locale localization details. There is no redundant fluff; it is compressed for the amount of information conveyed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described in detail. The description covers the tool's purpose, parameters, workflow, and localization behavior, which is sufficient for an agent to call it correctly. Missing edge cases (e.g., invalid entity_id) are likely handled by the tool's error responses and the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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. It provides detailed structure for the 'changes' parameter, distinguishing between simple text for headline/summary and action-based objects for position/skill/education. It also explains the locale wrapping behavior, adding significant semantic value beyond the bare schema. The other params (person_id, locale) are self-explanatory via defaults and names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('draft'), a specific resource ('profile change'), and explicitly distinguishes its behavior from the sibling apply_proposal by stating it 'NEVER writes to LinkedIn' and returns a diff for human review. This unambiguously differentiates it from the other proposal-related siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs the agent to show the diff to the human, wait for approval, and only then call apply_proposal with the returned proposal_id. This gives both when-to-use and when-not-to-use guidance, clearly routing the agent to the correct sibling after this tool.
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. Dates show when Glama detected each change.
7 tool updates
v0.1.0- First observed
apply_proposal - First observed
auth_start - First observed
auth_status - First observed
discard_proposal - First observed
get_profile - First observed
list_proposals - First observed
propose_edit
TDQS
Each tool has a distinct, unambiguous purpose: authentication start/status, profile retrieval, proposal creation, listing, discarding, and applying. No two tools overlap in function, and the descriptions clarify the exact role of each.
All tools follow a consistent verb_noun pattern (e.g., auth_start, get_profile, propose_edit, apply_proposal). The naming is uniform, predictable, and clearly indicates the action and target resource.
With 7 tools, the server is well-scoped for its purpose of LinkedIn profile editing. Each tool serves a necessary step in the workflow (auth, read, propose, manage, apply) without redundancy or bloat.
The tool surface covers the full lifecycle: authentication, profile reading, proposal creation with review, proposal management (list/discard), and the single write operation. The workflow is logically complete, and the explicit guardrails prevent dead ends.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
LinkedIn outreach, commenting, scheduling, and data via Claude and human approval gates.
LinkedIn outreach, commenting, scheduling, and data via Claude and human approval gates.
Draft, revise and review LinkedIn posts; a human approves each one before it goes live.
Draft, reshape and schedule LinkedIn posts in the writer's own voice, not a generic AI one.
1
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables Claude to interact with LinkedIn for posting, commenting, sharing media, and viewing feed and profile.92143MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude AI to interact with LinkedIn through browser automation, including profile reading, people and job search, company research, post publishing, and profile editing.MIT
- AlicenseAqualityDmaintenanceEnables posting content, sharing articles, and managing your LinkedIn profile through Claude using the official LinkedIn API with OAuth 2.0.618MIT
- AlicenseBqualityCmaintenanceEnables drafting, formatting, analyzing, and publishing LinkedIn posts directly from MCP-compatible clients like Claude.5214MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/kyle-nelson-berkeley/linkedin-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server