GTM Otto

com.gtmotto由 gtmotto.com 發布官方發布者v1.2.1更新於 Nov 2, 2026

Self-driving LinkedIn prospecting: it sources, warms and invites daily. You approve every message.

已驗證Streamable HTTP可網頁執行效率與工作流溝通與協作商業與電商

概覽

AI 產生的概覽

GTM Otto 的遠端 MCP 伺服器,提供自動運作的 LinkedIn 開發客源服務:助理可建立、評估、預覽、啟動與檢視外聯計畫。

可以做什麼
  • 檢視工作區資訊:組織、方案、潛在客戶額度、計畫清單、漏斗統計與 LinkedIn 席次狀態
  • 讀取並設定計畫的五條客源通道,查看執行紀錄,並試跑通道以取得規模與樣本
  • 估算候選 ICP 的受眾規模,建立或修改計畫、ICP 面向、每日上限與工作時段
  • 列出等待人工處理的草稿訊息,並逐筆核准或拒絕
  • 回傳瀏覽器連結,供人工連接或重新連接其 LinkedIn 帳號
適用情境
適合想在對話中直接建立與監控 LinkedIn 開發活動、而不必操作另一套外聯工具的情境,例如在正式投入前評估 ICP 規模、調整客源通道,或檢視每週成果與待核准佇列。
執行需求
遠端 Streamable HTTP 端點,無需本機安裝。驗證方式為 OAuth(首次呼叫受保護工具時顯示連接卡片),或在 Authorization 標頭中送出 API 金鑰。需要 GTM Otto 帳號、方案,以及已連接的 LinkedIn 席次,計畫才能真正執行。
安裝前請注意
啟用後會以使用者本人的 LinkedIn 帳號行動並送出真實邀請與訊息,因此只應在使用者明確要求時啟用、恢復或執行。執行通道會消耗真實潛在客戶預算與第三方呼叫,清除貼文通道記憶也會產生費用。核准草稿會向真人送出訊息。Authorization 標頭中的 API 金鑰屬於機密。潛在客戶資料與帳號活動由第三方服務處理。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 GTM Otto,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/com.gtmotto%2Flinkedin/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "gtm-otto": {
      "type": "http",
      "url": "https://agent.gtmotto.com/mcp"
    }
  }
}

README

GTM Otto MCP

Give Claude a LinkedIn seat that works while you sleep.

GTM Otto is self-driving LinkedIn prospecting. From Claude, Cursor or ChatGPT you describe who you want to meet; GTM Otto finds them daily, warms them up from your own LinkedIn account (visit, like, comment), invites them, and opens the conversation. Nothing is said without you.

This repository is the public home of the GTM Otto MCP server: the registry manifest (server.json), the Claude Code plugin with eight skills, the tool reference and the onboarding guide. The server itself runs at https://agent.gtmotto.com/mcp (Streamable HTTP).

Release status (2026-09-22): listed on the official MCP Registry as com.gtmotto/linkedin (manifest 1.2.1). https://agent.gtmotto.com/mcp answers initialize with no credentials; OAuth is served at /.well-known/oauth-protected-resource (authorization server clerk.gtmotto.com); 21 tools are deployed, including gtm_connect_linkedin and the three approval tools.

What it is, in one paragraph

Every other LinkedIn MCP is a remote control for a tool you still have to operate: lists to upload, sequences to build, seats to rotate. GTM Otto is the only one where the outreach keeps running after the chat ends. A play is an ICP plus up to five sourcing lanes plus an autonomy level. The server exposes 21 tools and, deliberately, no send verb: the agent can set up, size, preview, launch, pause and review a play, and it can approve or reject one drafted message at a time, but it cannot write to a stranger on your behalf.

Install

The endpoint is the same everywhere: https://agent.gtmotto.com/mcp.

Authentication. Add the server with no credentials. The first time the agent calls a protected tool, the client shows a Connect card; sign in (or sign up) in the popup and the call is retried. Scripts and clients that cannot do OAuth can send an API key instead: Authorization: Bearer gtm_sk_..., minted at app.gtmotto.com/connect.

Claude (web and desktop)

Settings, then Connectors, then Add custom connector. Name it GTM Otto, paste https://agent.gtmotto.com/mcp, save. Start a chat and say what you want; the Connect card appears on the first protected call.

Claude Code

bash
claude mcp add --transport http gtmotto https://agent.gtmotto.com/mcp

Then /mcp inside a session to authenticate in the browser. To use an API key instead:

bash
claude mcp add --transport http gtmotto https://agent.gtmotto.com/mcp \  --header "Authorization: Bearer gtm_sk_..."

Cursor

[Install MCP Server] [Install MCP Server]

The deeplink is cursor://anysphere.cursor-deeplink/mcp/install?name=gtmotto&config=eyJ1cmwiOiJodHRwczovL2FnZW50Lmd0bW90dG8uY29tL21jcCJ9, where the config value is the base64 of {"url":"https://agent.gtmotto.com/mcp"}. By hand, add this to .cursor/mcp.json:

json
{  "mcpServers": {    "gtmotto": { "url": "https://agent.gtmotto.com/mcp" }  }}

ChatGPT

Settings, then Connectors, then Create (developer mode must be on). Name GTM Otto, URL https://agent.gtmotto.com/mcp, authentication OAuth. Enable the connector in a chat from the tools menu.

Any other client

Any MCP client that speaks Streamable HTTP works: point it at https://agent.gtmotto.com/mcp, with OAuth or the Authorization header above. n8n, Windsurf, VS Code and the reference mcp-remote shim all fit.

Skills for Claude Code

The gtm-otto plugin connects the server and adds eight skills that turn a sentence into a running play:

/plugin marketplace add gtmotto/mcp/plugin install gtm-otto@gtmotto
SkillWhat it does
launch-a-playEstimate the ICP, create a draft play, connect LinkedIn, preview each lane, confirm, activate, explain the next 48 hours.
icp-to-playA sentence, a URL or a persona into the seven ICP facets, a company count, and a people_search lane on a new draft or an existing play.
post-discoveryTurn "people complaining about X on LinkedIn" into a Post discovery lane, with a worked French example.
hiring-signals"Companies hiring for X" into a Job offers lane that reaches the buyer inside each hiring company, not the recruiter.
weekly-play-reviewStats, run history and the approval queue folded into a one-page review with concrete changes.
instantly-to-linkedinWith the Instantly MCP also connected: companies that opened or replied to a campaign become an account list on LinkedIn.
heyreach-migrationFrom an exported HeyReach lead list: companies to an account list, facets to the ICP, and an honest note on what does not carry over.
linkedin-safety-checkSeat state, daily cap and working hours turned into a plain-English health report.

Each skill names the exact tools and arguments it calls, what to show you, and where it stops to ask.

Example prompts

  • "Find me CFOs at Swiss fintechs and set up a play, but do not launch it yet."
  • "People on LinkedIn complaining about paying 100 euros a month for Sales Navigator. Build a Post discovery lane on that and show me a sample."
  • "Take every company that replied to my Instantly campaign 'Q3 agencies' and add them to the LinkedIn play."
  • "Review my play 'Fintech CFOs' for the week and tell me what to change."
  • "Is my LinkedIn account safe at the current daily cap?"

Tools

Full reference with arguments: docs/tools.md.

ToolScopeOne line
gtm_whoamireadOrg, plan, lead meter, and the next step to follow. Start here.
gtm_list_playsreadEvery play with product, status, seat and pipeline spread.
gtm_show_playreadOne play in full: ICP, lanes, autonomy ladder, cap, working hours, seat.
gtm_play_statsreadThe pipeline over four windows, each with its delta versus the window before.
gtm_linkedin_statusreadThe play's seat state and today's headroom against LinkedIn's limits.
gtm_sources_referencereadThe reference for every sourcing lane. Read before configuring one.
gtm_show_sourcesreadAll five lanes of a play: config, switch, blockers, last run, memory.
gtm_source_runsreadRun history of one lane, newest first.
gtm_list_approvalsreadDrafted messages waiting for a human, with their approval ids.
gtm_estimate_icpwrite"About N companies match" for a candidate ICP. Writes nothing.
gtm_create_playwriteCreate a fully configured play. Draft by default; activate flag.
gtm_update_icpwriteChange a play's seven ICP facets. Only the ones you name.
gtm_update_playwriteName, goal, voice, paused, status active or draft, dailyCap, workingHours.
gtm_configure_sourcewriteWrite a lane's settings (merge). Can switch it on in the same call.
gtm_set_sourcewriteSwitch a lane on or off. Refused when there is nothing to run on.
gtm_preview_sourcewriteDry-run one lane: size and a 10-person sample. No side effects.
gtm_run_sourcewriteRun one lane now. Real leads, real budget. Only when asked.
gtm_forget_harvested_postswriteClear a post lane's memory so a settings change can be re-tested. Costs.
gtm_connect_linkedinwriteReturns a browser link to connect the LinkedIn seat; then poll gtm_linkedin_status.
gtm_approvewriteApprove one drafted message by approval id. The client asks you first.
gtm_rejectwriteReject one drafted message by approval id. The client asks you first.

What it deliberately does not do

  • No send verb. No invite, DM, comment or like tool. The agent configures the play; GTM Otto runs it from your account on its own cadence; anything that speaks waits for your approval, one message at a time, in the chat or in the cockpit.
  • Nothing runs inside a write. Configuring a lane is not switching it on, and switching it on does not run it. A lane runs once per 24 hours on the 5-minute tick, when the play is active and not paused. gtm_preview_source is free of side effects; gtm_run_source spends real budget and is only called when you asked.
  • No launching without you. The agent never activates a play, resumes a paused one, or runs a lane unless you asked for it in the conversation. Activation acts from your own LinkedIn account.
  • No lead browsing, no autonomy changes after creation, no delete.
  • No list of people. The server takes companies (account_list, at most 100) and post URLs, never a CSV of individual LinkedIn profiles.
  • Warm-up is real. The first invites land about two days after activation. The silent days are the product working, not a bug.

Repository layout

server.json                          registry manifest (com.gtmotto/linkedin).claude-plugin/marketplace.json      Claude Code marketplace "gtmotto"plugins/gtm-otto/                    the plugin: MCP server + eight skills  .claude-plugin/plugin.json  skills/<name>/SKILL.mddocs/tools.md                        the 21 tools with argumentsdocs/onboarding.md                   the ideal first conversationCHANGELOG.md

Links

The free skills

The playbooks that need nothing but LinkedIn (find buyers in comments, ICP to a Sales Navigator search, hiring-signal prospecting by hand, LinkedIn limits, the comment and invite writer) live in gtmotto/gtm-skills. That repository registers no server and needs no account; each of its skills ends with a pointer to the skill here that runs the same recipe daily.

Contributing

This repository is mirrored out of the GTM Otto monorepo. Issues and pull requests are welcome here and are read; fixes are applied upstream and land in the next mirror, so a PR may be closed with a "merged upstream" note rather than merged in place. Keep prose free of em dashes, and never describe the product as an automated sales rep of any kind: it is self-driving LinkedIn prospecting.

License

MIT. See LICENSE.

來源:README.md,提交 86511e1

工具

21

gtm_whoami

Who am I, and what next

Who this key belongs to, and what the workspace may do: org name, plan, subscription status, how many products and plays exist, and the LEAD METER (leads added this calendar month, the plan's cap, and what is left). Start here — the remaining lead allowance is the one number that changes what is worth proposing. Read-only.

無需輸入參數。

gtm_list_plays

List plays

Every play in the workspace with enough context to route on: which product it sells, whether it is active or paused, whether a LinkedIn seat is actually connected (`seatConnected: false` means the play cannot act, whatever its status says), and how its leads are spread across the pipeline stages. Read-only.

無需輸入參數。

gtm_show_play

Show a play

ONE play in full — everything needed to judge it or copy it into a better one: goal and voice, the account's daily cap and working hours (shared by every play on the seat), the ICP facets, the five sourcing lanes with their config and last run, the autonomy ladder (which rungs run alone and which wait for a human), the LinkedIn seat, and today's used/cap for the seat plus this play's share. Read-only. Pass a playId from gtm_list_plays.

輸入參數playId必填

gtm_play_stats

Play stats

The play's Stats screen: the pipeline (leads sourced → warmed → invited → new connections → conversations started) over four windows — all time, last 30 days, last 7 days, last 24 hours — each windowed count paired with the window before it as a percentage delta. 'Conversations started' counts real replies, never the openers Otto sent. Read-only.

輸入參數playId必填

gtm_linkedin_status

LinkedIn seat status

The play's LinkedIn seat and today's headroom against the LinkedIn limits. States: `no_seat` (nothing connected — the play cannot act), `seat_broken` (the account was disconnected or deleted; the queue is parked until a human reconnects), `pending`, `classic`, or `sales_navigator` (which search backend the ICP compiles to). Read-only. Connecting a seat is a browser flow — link the human to the cockpit for it.

輸入參數playId必填

gtm_estimate_icp

Estimate ICP size

How big an audience a CANDIDATE ICP would reach — '≈ N companies match' — before committing to it. Writes nothing: no play, no ICP row, no cache. Use it to iterate (propose facets → see 40 → widen the locations → see 900 → then create the play). Returns null when the data provider has no key configured, which is not an error. Needs a write-scoped key only because it rides the gateway's action channel.

輸入參數sizeslocationsindustries

gtm_create_play

Create a play (draft)

Create a fully-configured play in one call: the product (an existing productId, or a websiteUrl which seeds one and kicks its research), the play itself, the ICP facets, which sourcing lanes are on, the autonomy ladder and the caps. Three rules are enforced server-side and cannot be talked around. (1) `activate` DEFAULTS TO FALSE — turning a play on spends the month's lead quota and takes real actions from the user's own LinkedIn account, so hand the human the returned cockpit link and let them press go. (2) A play with no live LinkedIn seat stays a draft whatever you pass. (3) Autonomy rules are written ONLY for the steps you name; every step you omit keeps gtmotto's own default, which is 'wait for a human'. Lanes that need their own seeds (post_engagers, competitor_posts, account_list) are refused if switched on without them.

輸入參數icpgoalname必填voicesourcesactivateautonomydailyCapproductIdwebsiteUrlproductNameworkingHours

gtm_sources_reference

Sourcing lanes reference

THE REFERENCE for configuring sourcing lanes — read it before your first gtm_configure_source / gtm_set_source / gtm_run_source call. Every lane (people_search, competitor_posts a.k.a. Post discovery, job_offers, account_list, and the retired post_engagers), every config field with its meaning, default and cap, the fit/intent/post gates, what makes a lane runnable, how the 5-minute tick and the 24h cadence work, what a preview costs versus a run, and what this surface deliberately will not do. No backend call; safe to call any time.

無需輸入參數。

gtm_show_sources

Show sourcing lanes

All five sourcing lanes of a play, configured or not — the read to make before touching any of them. Per lane: `configured`, `on`, the parsed `config` (defaults filled), the cockpit's `summary` (null = needs setup), `blocked` (why it cannot run, judged without running: needs_config / icp_empty / null), last/next run and the last run's funnel, `addedToday`, `failures`, and the lane's memory — `accounts[]` with `found: true|false` per typed company on account_list, `harvestedPosts` on the post lanes, the cached `searches` the model wrote on Post discovery. Play level: `state` is the same verdict the cockpit shows when the Leads table is empty (no_sources / paused / draft / no_seat / seat_broken / icp_empty / needs_config / lead_quota / never_ran / no_results / provider_error / added_nothing / ok), plus provider, seat, ICP facet count and the month's remaining lead quota. Read-only.

輸入參數playId必填

gtm_source_runs

Lane run history

The run history of ONE lane, newest first — the funnel over time (scanned → dropped by fit → dropped by intent → added / duplicates / capped), the ICP facets LinkedIn could not filter on, and the provider's status and message when it refused. Use it to tell 'the query returns nobody' from 'everyone was already a lead' from 'LinkedIn is rate-limiting the seat'. Read-only.

輸入參數key必填limitplayId必填

gtm_configure_source

Configure a sourcing lane

Write a lane's settings — upload an account list, set the Post-discovery intent and anchors, change the job keywords, move a gate. MERGE semantics: only the fields you send change. Lists (companies, postUrls, competitors) REPLACE by default; pass listMode 'append' to add to what is there (deduped, case-insensitive). Caps: 100 companies, 25 posts, 25 anchors — what did not fit comes back in `truncated`. Unknown fields are refused. Saving creates the lane's row if it never had one (OFF, because configuring is not switching on), makes the lane due again immediately and resets its retry backoff; on account_list it also forgets the cached misses so unfound companies are looked up again. Pass `on: true` to switch it on in the same call — refused, with nothing saved, if the lane would still have nothing to run on. Nothing runs inside this call: an ON lane on an ACTIVE play runs on the next tick (≤5 min); otherwise use gtm_run_source. Read gtm_sources_reference for each field's meaning.

輸入參數onkey必填config必填playId必填listMode

gtm_set_source

Switch a lane on or off

Switch a lane on or off — the toggle on the Sources list. Switching ON a lane that has nothing to run on (no companies, no intent/anchors/posts, no role) is refused: configure it first. An empty ICP is not a refusal — people_search may go on ahead of the ICP and comes back `blocked: icp_empty` until gtm_update_icp fills it. Switching OFF never fails and creates nothing. The lane then runs (or stops running) on the daily cadence; nothing runs inside this call.

輸入參數on必填key必填playId必填

gtm_preview_source

Preview a lane (dry run)

Dry-run ONE lane: '≈ N people match' and a 10-person sample, WITHOUT inserting a lead, spending the day's budget or moving the run clock. Same query, same gates, same scorers as a real run, on up to 50 people — so what it shows is what a run would keep. `size.precision` is honest: 'exact' (the query ran out inside the probe), 'atLeast' (the probe filled up; LinkedIn reports no total) or 'unavailable' (no seat, no config, paused play — `skipped` says which). Reports the ICP facets LinkedIn could not filter on (`unmapped`), facet values it had no id for (`unresolved`), which sampled people are `alreadyALead`, and on account_list what each company resolved to. Costs provider calls and, when a gate is on, model tokens. Refused on a paused play.

輸入參數key必填playId必填

gtm_run_source

Run a lane now

'Run once now' — run ONE lane immediately through the same code the sourcing tick runs, with force: an OFF lane still runs (that is what run-once means while configuring), a DRAFT play still runs (how you try a lane before launch), a PAUSED play does not. REAL: provider calls are made, leads are inserted, the play's daily budget and the org's monthly lead quota are spent. Only call it when the human asked for a run in this conversation; to look without spending, use gtm_preview_source. Returns the run's funnel (scanned / dropped / droppedIntent / added / duplicates / capped), the unmapped ICP facets, and `skipped` + `reason` when it could not run (no_seat, needs_config, icp_empty, daily_cap, lead_quota, no_results, provider_error).

輸入參數key必填playId必填

gtm_forget_harvested_posts

Forget harvested posts

The tuning escape hatch for the post lanes. A post lane remembers every post it already paid to harvest so it never buys the same engagers twice — which makes it impossible to TUNE: change the intent or a gate, run, and the answer is 'no new posts since last time'. This clears that memory so the next run (or gtm_run_source) judges today's posts against the new settings. It COSTS: every forgotten post is a fresh engager fetch. Call it only after a deliberate settings change the human wants re-tested. Only competitor_posts and post_engagers have this memory.

輸入參數key必填playId必填

gtm_update_icp

Update the ICP

Change the ICP a play runs — the query behind people_search and the fit gate on every other lane. Seven string arrays, plain words (gtmotto normalises 'Swiss' → Switzerland, 'Fintech' → Financial Services itself): titles, seniority, languages, industries, sizes (headcount bands like '11-50'), locations, exclude ('never contact' — absolute). ONLY the facets you name change; the first write on a play forks its own ICP row from the product baseline (or a sibling play's row), so no other play's targeting is rewritten. Filling an empty ICP unblocks lanes parked on icp_empty and kicks the play's due lanes if it is active. Size a candidate first with gtm_estimate_icp.

輸入參數sizesplayId必填titlesexcludelanguageslocationsseniorityindustries

gtm_update_play

Update, pause or launch a play

Change a play's own knobs — name, goal, voice — its two switches, and the ACCOUNT's pacing (daily action cap, working hours: shared by every play on the LinkedIn account, not per play). `paused: true` is the human's stop button (nothing runs, nothing is sent); `paused: false` resumes. `status: 'active'` LAUNCHES a draft; `status: 'draft'` takes it back off the road. Seat rule, enforced server-side: no live LinkedIn seat ⇒ neither launch nor resume makes it active — it stays/falls back to draft and the note says so. Launching or resuming kicks the play's due lanes at once. Only launch, resume or raise the cap when the human asked for it in this conversation: an active play spends the month's lead quota and acts from the human's own LinkedIn account. Does not touch the autonomy ladder.

輸入參數goalnamevoicepausedplayId必填statusdailyCapworkingHours

gtm_connect_linkedin

Connect LinkedIn

The link a human opens to connect (or reconnect) their LinkedIn account to a play — the one cockpit step the play cannot run without. Hand the URL to the human, tell them to say when it is done, then call gtm_linkedin_status: the seat reads `classic` or `sales_navigator` once bound. The link expires in 15 minutes; call again for a fresh one. Nothing is sent, nothing is read from their account by this call.

輸入參數playId必填

gtm_list_approvals

List drafted messages waiting for you

Every drafted action that waits for the human — an invite note, a first message, a follow-up, a reply or a comment the planner wrote — with the draft, the 'why now', the lead, and a cockpit link. One play, or the whole workspace when playId is omitted. Show each draft to the human before gtm_approve / gtm_reject; never decide for them. Read-only.

輸入參數playId

gtm_approve

Approve a drafted message

Approve ONE drafted action by its approvalId (from gtm_list_approvals). It then leaves on the seat's next slot, inside LinkedIn's limits — this is the human's tap, moved from the cockpit to the chat, so ONLY call it after showing them the draft and getting a yes in this conversation. An already-decided card is refused.

輸入參數approvalId必填

gtm_reject

Reject a drafted message

Reject (skip) ONE drafted action by its approvalId. Nothing is sent; the planner records the decline and re-plans around it instead of proposing the same step again. Ask the human first, as for gtm_approve.

輸入參數approvalId必填

版本歷史

1
  1. v1.2.1最新Sep 22, 2026

評分

已滿足適用檢查項的 100%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分