npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thenavidm/tiktok-mcp-cli

v2.0.1

Published

TikTok MCP server and CLI for Claude Code and AI agents. 14 tools for your profile, video stats, top posts, publishing videos and photo carousels, drafts and post status.

Readme

TikTok MCP Server & CLI

npm License CI YouTube X LinkedIn

TikTok MCP server and CLI for Claude Code, Codex and AI agents. 14 tools for your profile, video stats, top posts, publishing videos and photo carousels, drafts and post status.

One install gives you both surfaces, the same 14 tools under the same names.

It reads your real numbers. Views, likes, comments and shares per post, straight from TikTok rather than a scraper's guess.

It publishes too: a video or a photo carousel, or a draft into your TikTok inbox that you finish in the app.

Everything is scoped to accounts you connect yourself.

Built and maintained by Navid Moazzez. Built on Slipway, which turns one definition of each tool into the MCP server and the CLI.

You:    Which of my TikToks beat my median view count this year, and what do they share?

Claude: [stats_summary -> top_videos]
        Median is 4,180 views across your last 60. Eleven beat it.

        Nine of the eleven open on a face with no text overlay. Your
        median post opens on a title card. The two exceptions are both
        under 12 seconds.

        Your best is 214k, which is why your mean reads 21,600 and is
        not a number any other post of yours has come close to.

Two ways to use it

Command line

tiktok-cli in your terminal, for scripting, cron, pipes, or just asking a quick question without opening anything:

tiktok-cli                                        # every command, one line each
tiktok-cli get-profile                            # followers, total likes, video count
tiktok-cli list-videos --limit 50                 # your posts, newest first
tiktok-cli top-videos --metric shares --limit 10  # ranked by what travels
tiktok-cli stats-summary --scan 200               # mean, median, p90, cadence
tiktok-cli search-my-videos --query "AI OS"
tiktok-cli send-video-to-drafts --video-url https://cdn.example.com/clip.mp4
tiktok-cli post-video --video-url https://cdn.example.com/clip.mp4 \
  --privacy-level SELF_ONLY --title "Shipped." --confirm
tiktok-cli list-videos --limit 200 --json | jq '[.videos[] | select(.views > 10000)] | length'
tiktok-cli <command> --help                       # what any command takes

--confirm is the shell spelling of the confirmation that post-video, post-photos and revoke-access require. --json gives JSON, --compact puts it on one line, --select id,views keeps only the fields you name, and errors are JSON on stderr whichever you pick.

Reading commands return real objects rather than prose, so jq and --select reach the fields directly. Section 8 has the exit codes a script branches on.

MCP server, for your AI app

tiktok-mcp is what Claude Code, Claude Desktop, Cursor and the rest launch. You never run it by hand:

claude mcp add tiktok \
  -e TIKTOK_CLIENT_KEY=your_client_key \
  -e TIKTOK_CLIENT_SECRET=your_client_secret \
  -e TIKTOK_REFRESH_TOKEN=your_refresh_token \
  -- npx -y @thenavidm/tiktok-mcp-cli@latest

Then just ask: "rank my last 200 posts by shares and tell me what the top ten have in common."

Each publish waits for your approval in the client, as section 10 explains.

Every other client is in section 4.

Which one

| Where you are | What you can reach | |---|---| | An agent that can run shell commands, like Claude Code or Cursor | Both. The CLI is the cheaper one: it costs nothing until you type it | | claude.ai, the Claude Desktop chat tab, or a phone | The server only. There is no shell to run a command in | | A terminal, a script, cron or CI | The CLI only. There is no MCP client in a shell |

They are the same program reading the same array of tool definitions, so anything one can do, the other can, and a tool added tomorrow is a command tomorrow.

Features

Every tool is both a command and an MCP tool, with the same name. The command is the tool name with dashes.

| Capability | CLI command | MCP tool | |---|---|---| | Your accounts and profile | tiktok-cli list-accounts / get-profile | list_accounts / get_profile | | Your videos and what worked | tiktok-cli list-videos / get-videos / top-videos / stats-summary | list_videos / get_videos / top_videos / stats_summary | | Publish | tiktok-cli get-creator-info / post-video / post-photos / get-post-status | get_creator_info / post_video / post_photos / get_post_status | | Send to drafts | tiktok-cli send-video-to-drafts / send-photos-to-drafts | send_video_to_drafts / send_photos_to_drafts | | Hand the token back | tiktok-cli revoke-access | revoke_access | | Sign in once | tiktok-cli login | not a tool | | Check your setup | tiktok-cli doctor | not a tool |

All 14 are in section 7.

Contents

| # | Section | What it covers | |---|---|---| | 1 | What you can ask it | Real prompts, not features | | 2 | Quick install | The package, no account needed | | 3 | Set up your TikTok app | Every click | | 4 | Connect your client | Claude Code, Desktop, Cursor | | 5 | Check it worked | doctor | | 6 | Which surface, and what each costs | Measured in Claude Code, and how to spend less | | 7 | Tools | All 14, by what they reach | | 8 | Output and exit codes | What scripts branch on | | 9 | Environment variables | Credentials, safety, tuning | | 10 | Writing safely | What is guarded and what is not | | 11 | Notes and gotchas | The platform's real behavior | | 12 | Troubleshooting | Symptom to cause | | 13 | FAQ | Including what an MCP server is |

1. What you can ask it 💬

  • Which of my TikToks beat my median view count, and what do they have in common?
  • What is my actual engagement rate per post, not the number the app shows me?
  • How often am I posting, and has that changed over the last 60 videos?
  • Find every video where I mentioned the AI OS and tell me how they performed.
  • Rank my last 200 posts by shares rather than views. Shares are the ones that travel.
  • Draft a TikTok from this MP4 and put it in my inbox so I can review it on my phone.
  • Publish this photo carousel with the first image as the cover, comments off.
  • Did the video I posted twenty minutes ago clear moderation yet?
  • My follower count and total likes, then work out my average views per follower.

The thing you cannot do anywhere else: rank your own catalog by a metric TikTok's app will not sort by. The app shows you a grid ordered by date. Asking "which posts actually travelled, by shares, across two hundred videos" has no answer inside TikTok, and it is one call here.

2. Quick install ⚡

Node 22 or newer. Nothing else.

npx -y @thenavidm/tiktok-mcp-cli --version

That is the whole install for the MCP server. npx fetches it on demand, so there is nothing to update later, and the claude mcp add line in section 4 does it for you.

For the shell surface, install it once so tiktok-cli is on your PATH:

npm i -g @thenavidm/tiktok-mcp-cli
tiktok-cli --version
tiktok-cli                 # every command, one line each

Without a global install, npx -y -p @thenavidm/tiktok-mcp-cli tiktok-cli runs the same binary.

Installing the package needs no TikTok account. Only the next section does.

3. Set up your TikTok app 🔑

TikTok has no personal access tokens. Every integration goes through an app you create, which is more work than most services and is the same for everybody.

The steps below are the short version. INSTALL.md is the long one: read it when something here did not work, or when you are deciding between Sandbox and Production.

[!TIP] Use Sandbox mode while you set this up. A sandbox app works immediately with no review, against TikTok accounts you add to it yourself. Only switch to Production when you want other people to use it.

Before you start

| You need | Check with | If missing | |---|---|---| | Node 22 or newer | node -v | nodejs.org | | A TikTok developer account | developers.tiktok.com | Sign up with your email, it is free | | The TikTok account you want to connect | you sign in with it | Any account, personal or business |

Step 1: Create the app

  1. Log in at developers.tiktok.com, click the profile icon in the navigation bar, then Manage apps.
  2. Click Connect an app.
  3. When asked to Select the app owner, pick an organization if you have one, or your individual developer account.
  4. Fill in the app name, icon and description. TikTok shows the description on the screen where you approve access, so write it for yourself.
  5. Under Platforms, select Desktop. This server runs on your machine, which is what that platform means.

Step 2: Add Login Kit and set the redirect URI

  1. In the Products section click Add products, and add Login Kit.

  2. In the Login Kit settings, set the Redirect URI to exactly:

    http://127.0.0.1:8481/callback/

TikTok allows loopback redirect URIs for desktop apps, which is what lets the next step happen entirely in your terminal. The trailing slash is part of the URI.

Step 3: Add the scopes

In the Scopes section, add these four:

user.info.basic
user.info.profile
user.info.stats
video.list

Add these two as well, but only if you want to publish. They need the Content Posting API product added too:

video.upload
video.publish

[!IMPORTANT] Only ask for scopes your app actually has. Sending an unapproved scope to TikTok's authorize URL fails the whole sign-in, not just that one permission.

Step 4: Get your refresh token

Copy the Client key and Client secret from the Credentials section of the app page, then:

export TIKTOK_CLIENT_KEY=your_client_key
export TIKTOK_CLIENT_SECRET=your_client_secret

npx -y @thenavidm/tiktok-mcp-cli auth

It prints a URL. Open it, approve the access, and the terminal prints a refresh token valid for about 365 days. Add --publish if you added the publishing scopes.

Step 5: Verify a domain, only if you will publish

TikTok downloads media from a URL rather than accepting an upload, and it will only pull from a domain you have proved you own.

  1. Click URL properties at the top of the app page.
  2. Click Verify properties.
  3. Verify by Domain or by URL prefix, and follow the instructions shown.

Skip this if you are only reading, and skip it if you only use the drafts tools.

Revoking access later

Call the revoke_access tool, or remove the app from Settings, Security and permissions, Manage app permissions in the TikTok app.

4. Connect your client 🔌

Claude Code

claude mcp add tiktok \
  -e TIKTOK_CLIENT_KEY=your_client_key \
  -e TIKTOK_CLIENT_SECRET=your_client_secret \
  -e TIKTOK_REFRESH_TOKEN=your_refresh_token \
  -- npx -y @thenavidm/tiktok-mcp-cli@latest

Add --scope user to make it available in every project rather than the current one.

Claude Desktop

The easiest route is the extension: download the .mcpb from the latest release and double-click it. Claude Desktop asks for the client key, secret and refresh token in a dialog, keeps the two secrets in your operating system keychain, and carries its own dependencies, so nothing else has to be installed first.

To wire it by hand instead:

| Platform | Config file | |---|---| | macOS | ~/Library/Application Support/Claude/claude_desktop_config.json | | Windows | %APPDATA%\Claude\claude_desktop_config.json |

{
  "mcpServers": {
    "tiktok": {
      "command": "npx",
      "args": ["-y", "@thenavidm/tiktok-mcp-cli@latest"],
      "env": {
        "TIKTOK_CLIENT_KEY": "your_client_key",
        "TIKTOK_CLIENT_SECRET": "your_client_secret",
        "TIKTOK_REFRESH_TOKEN": "your_refresh_token"
      }
    }
  }
}

[!TIP] Claude Desktop does not inherit your shell PATH, so a bare npx can fail silently. Use the absolute path from which npx. Then quit the app completely rather than closing the window.

Cursor

.cursor/mcp.json, same shape as Claude Desktop, key mcpServers.

Windsurf

~/.codeium/windsurf/mcp_config.json, key mcpServers.

VS Code

.vscode/mcp.json. The key is servers, not mcpServers, and each entry takes "type": "stdio".

Codex CLI

~/.codex/config.toml:

[mcp_servers.tiktok]
command = "npx"
args = ["-y", "@thenavidm/tiktok-mcp-cli@latest"]

[mcp_servers.tiktok.env]
TIKTOK_CLIENT_KEY = "your_client_key"
TIKTOK_CLIENT_SECRET = "your_client_secret"
TIKTOK_REFRESH_TOKEN = "your_refresh_token"

Gemini CLI

~/.gemini/settings.json, key mcpServers.

Everything else

Any stdio MCP client takes the same three things: the command npx, the args above, and the env block.

Self-hosted over HTTP

npx -y @thenavidm/tiktok-mcp-cli@latest --http --port 8000

It binds 127.0.0.1 and refuses any other host without TIKTOK_HTTP_TOKEN set, because anything that can reach the port can publish to the connected account.

| Variable | What it does | |---|---| | TIKTOK_HTTP_PORT | Port to listen on. Default 8000, and --port overrides it | | TIKTOK_HTTP_HOST | Interface to bind. Default 127.0.0.1 | | TIKTOK_HTTP_TOKEN | Bearer token required on every request. Mandatory on any host but 127.0.0.1 |

More than one account

TIKTOK_ACCOUNTS=personal:refresh_token_one,brand:refresh_token_two

Then pass account: "brand" on any tool. Run auth once per account to get each token.

5. Check it worked 🩺

npx -y @thenavidm/tiktok-mcp-cli@latest doctor

It tests every configured account, names which scopes were granted, and says which tools are unavailable and why.

The two failures that actually happen:

| It says | Do this | |---|---| | token rejected | Your refresh token expired or was revoked. Run auth again. | | publishing unavailable | The account never granted video.publish. Add the Content Posting API product, then auth --publish. |

6. Which surface, and what each costs

Both surfaces are the same program with the same 14 tools. The difference is when the model pays for them. Measured in Claude Code:

| Cost | MCP server | CLI | |---|---|---| | Every message, with every tool loaded | 5,400 tokens | nothing | | Every message, Claude Code's default | 730 tokens | nothing | | When TikTok comes up | nothing more, or the tools it picks | 3,180 tokens for SKILL.md, once | | 20 messages with TikTok in 1, every tool loaded | 108,000 tokens | 3,180 tokens |

Claude Code's tool search is on by default: it sends only the tool names and the server instructions, and loads a tool's full definition when the model reaches for it. An app that loads every tool up front pays the first line on every message, whether TikTok comes up or not. With the skill added, Claude Code also lists its one-line description, about 170 tokens.

Where the tokens go, with every tool loaded:

| Part of the tool list | Share | |---|---| | Structure: names, types, required lists, nesting, annotations | 48% | | Argument descriptions | 28% | | Tool descriptions | 24% |

To spend less, turn the server off when you are not using it, which in Claude Code is the /mcp panel. TIKTOK_READ_ONLY=1 takes the 5 write tools off the list, leaving 9. Or install the CLI and add the server on the days it earns its place.

Measured on 2026-10-05 with Claude Code 2.1.286 on Claude Opus 5.5: one short prompt with and without the server connected, once with ENABLE_TOOL_SEARCH=false and once with the default, the difference read from the API's own usage figures. SKILL.md was measured the same way. Other apps and models count tokens a little differently.

Against 1.1.0, measured the same day: every tool loaded costs 5,409 tokens instead of 5,970, tool search the same, and SKILL.md 75 more, because it now says how approval works over MCP and lists every exit code. In Codex 0.159.3 on gpt-6.1-sol, the same task, "find the command that saves a video to the creator's TikTok drafts instead of publishing it and the flags it requires", read a median of 47,503 input tokens on 2.0.0 against 47,557 on 1.1.0 over MCP, and 83,105 against 83,043 over the CLI, five runs each. The CLI's 62 more come from its general help, which Codex reads first and carries through the task: it now lists which, install and the exit codes, which 1.1's did not, and is 412 tokens against 312.

7. Tools 🛠️

Your account

| Tool | What it does | |---|---| | list_accounts | Every account configured, and the name to target it by | | get_profile | Username, bio, verified flag, followers, total likes, video count | | revoke_access | Hand the token back to TikTok. Needs confirm |

Your videos

| Tool | What it does | |---|---| | list_videos | Your posts newest first, with views, likes, comments, shares and engagement rate. Pages automatically | | get_videos | Up to 20 by id, and the way to refresh an expired cover image URL | | top_videos | Rank by views, likes, comments, shares or engagement rate | | search_my_videos | Find your posts by text in the title or description | | stats_summary | Totals, mean, median, 90th percentile and posting cadence |

Publishing — needs video.publish or video.upload

| Tool | What it does | |---|---| | get_creator_info | Which privacy levels this account can post at. Call it first | | post_video | Publish a video from a public URL. Needs confirm | | post_photos | Publish a carousel of up to 35 images. Needs confirm | | send_video_to_drafts | Send a video to your TikTok inbox to finish in the app | | send_photos_to_drafts | Send photos to your inbox | | get_post_status | Track a post through download, moderation and publication |

8. Output and exit codes

Every command prints human-readable text by default and JSON when asked.

| Flag | What it does | |---|---| | --json | JSON on stdout | | --compact | the same JSON on one line | | --agent | compact JSON, no prompts, and never confirms a write | | --select <a,b.c> | keep only these fields; dotted paths descend and arrays are traversed element-wise | | --help | the arguments, types and defaults, derived from the schema |

Errors are always JSON on stderr, whichever output flag you passed, so a caller parses one shape.

Exit codes, so a script can tell a mistake it should fix from a failure it should retry:

| Code | Meaning | |---|---| | 0 | Success | | 1 | Unexpected error | | 2 | Usage error: wrong or missing arguments, an unknown command, a write hidden by a safety setting, or a write refused for want of --confirm | | 3 | Not found | | 4 | Authentication rejected, usually an expired refresh token | | 5 | API error upstream | | 7 | Rate limited, wait and retry | | 10 | Nothing is configured yet |

if ! tiktok-cli post-video --video-url "$URL" --privacy-level SELF_ONLY --confirm; then
  case $? in
    2)  echo "bad arguments or no confirmation, not retrying" >&2; exit 1 ;;
    4)  echo "token expired, run tiktok-cli login" >&2; exit 1 ;;
    7)  echo "rate limited, backing off" >&2; sleep 60 ;;
    10) echo "nothing configured" >&2; exit 1 ;;
    *)  echo "failed, will retry" >&2 ;;
  esac
fi

tiktok-cli with no arguments lists every command with its risk marked. tiktok-cli schema <command> prints the JSON Schema an MCP client receives, so the two surfaces are provably the same.

9. Environment variables

Credentials

| Variable | What it is | |---|---| | TIKTOK_CLIENT_KEY | From the Credentials section of your app at developers.tiktok.com | | TIKTOK_CLIENT_SECRET | From the same place | | TIKTOK_REFRESH_TOKEN | What tiktok-cli login prints, which 1.1 called auth; both names work. One account | | TIKTOK_ACCOUNTS | Several accounts, as name:token,name:token |

Safety

| Variable | What it does | |---|---| | TIKTOK_READ_ONLY=1 | Removes all five write tools from the list entirely | | TIKTOK_ALLOW_DESTRUCTIVE=0 | Keeps the drafts tools, removes publishing and revoking | | TIKTOK_AUDIT_LOG=<path> | One JSON line per attempted write, allowed and blocked alike, and who approved it | | TIKTOK_CONFIRM=model | Lets confirm: true alone approve over MCP, for an agent with no person to ask |

Tuning

| Variable | Default | What it does | |---|---|---| | TIKTOK_HTTP_PORT | 8000 | Port for --http. --port overrides it | | TIKTOK_HTTP_HOST | 127.0.0.1 | Interface for --http to bind | | TIKTOK_HTTP_TOKEN | none | Bearer token required on every HTTP request. Mandatory on any host but 127.0.0.1 | | TIKTOK_HTTP_ALLOWED_ORIGINS | none | Comma-separated browser origins allowed to connect; a page from any other site is refused | | TIKTOK_SURFACE | full | search lists three tools that find, describe and run the rest | | TIKTOK_TOOL_TIMEOUT_MS | none | Give up on any tool after this long | | TIKTOK_DEBUG | 0 | 1 prints debug lines on stderr |

10. Writing safely 🛟

Writes work by default. Publishing is the point of the tool.

The three actions that cannot be undone from a chat window wait for your approval: post_video, post_photos and revoke_access. Drafts do not, because they land in your own inbox and go nowhere until you finish them. Approving everything would train the reflex that makes the approval on a real publish worthless.

Over MCP a person approves each of the three where the client can ask: Claude Code (2.1.246 and later) shows its own prompt, and a client that can show forms asks with an approval form whose one box starts unticked. Each approval is signed, bound to that exact call and works once. Where a client can do neither, the model's confirm: true counts, and it should pass it only when you asked for that exact post. TIKTOK_CONFIRM=model makes confirm: true enough everywhere, for an agent with no person to ask. In a terminal it is --confirm, which --agent never adds.

The three switches in section 9 are the harder stops. TIKTOK_READ_ONLY=1 takes the list from 14 tools to 9 by removing every write rather than refusing it, because a model cannot call a tool it cannot see. TIKTOK_ALLOW_DESTRUCTIVE=0 leaves 11: the drafts tools stay, publishing and revoking go. TIKTOK_AUDIT_LOG records every attempted write, allowed and blocked alike, and who approved it.

Captions and bios reach the model fenced and labelled as somebody else's words. That framing helps and it is not a guarantee. For an agent working unattended, TIKTOK_READ_ONLY=1 is the real defense.

11. Notes and gotchas ⚠️

  • It can only see your own account. TikTok's official API has no endpoint for anybody else's profile, videos, comments, followers, hashtags or search. Nothing here answers a question about a competitor or a trend, and no API key changes that.
  • There is no comments API. You cannot read or reply to comments on your own posts through TikTok's official API.
  • Access tokens live 24 hours. The server refreshes them for you. The refresh token behind it is valid for 365 days. TikTok's docs warn that a refresh may hand back a different refresh token, so the server keeps whichever one came back rather than the one you configured.
  • An unaudited app posts privately. Until TikTok audits your app, every post lands private whatever privacy level you pass. Sandbox apps cannot post publicly at all.
  • A public URL is not enough to publish from. TikTok pulls media only from a domain verified under URL properties. An unverified domain fails with url_ownership_unverified however reachable the file is.
  • privacy_level must come from get_creator_info. TikTok rejects a value that is not in that account's current list rather than falling back to something safe.
  • Publishing returns a job, not a post. Poll get_post_status. A public post reports no post id until moderation clears it, usually a minute and sometimes hours.
  • Cover image URLs expire after 6 hours. Re-fetch with get_videos rather than storing the link.
  • Five pending drafts per 24 hours. TikTok caps unpublished API drafts per account.
  • A photo post's title caps at 90, far shorter than a video caption's 2200. Its description takes 4000, so the long text belongs there. TikTok counts all three in UTF-16 runes, which is its own phrasing for the unit.
  • Rate limits are per access token: six posting calls a minute, thirty status checks, twenty creator-info queries. The reading endpoints allow 600 a minute on a sliding window.
  • Only public videos are visible. TikTok documents video/list as returning the user's public video posts, so anything else is out of reach. get_videos takes at most 20 ids a call.

12. Troubleshooting 🔧

Run doctor first. It checks every account and names what is unavailable.

| Symptom | Cause | |---|---| | scope_not_authorized | The account never granted that scope. Re-run auth, with --publish if you need posting | | Token rejected on every call | The refresh token expired after 365 days, or you revoked the app | | redirect_uri error during auth | The URI in your app is not byte-identical to http://127.0.0.1:8481/callback/, usually the trailing slash | | auth hangs, never returns | Port 8481 is taken. Run auth --port 9000 and register that URI too | | url_ownership_unverified | The media domain is not verified under URL properties | | privacy_level_option_mismatch | You passed a level not in get_creator_info, often after the account went private | | Post says complete, has no post id | Normal. Moderation has not cleared it yet | | unaudited_client_can_only_post_to_private_accounts | Expected on a sandbox or unaudited app. Post SELF_ONLY, or apply for the audit | | Only nine tools appear | TIKTOK_READ_ONLY=1 is set | | Nothing appears in Claude Desktop | It does not inherit your PATH. Use the absolute npx path and fully quit the app | | "will not run without --confirm" | Working as intended: publishing cannot be undone. See section 10 | | claude -p will not publish | Headless Claude Code refuses tools that need a person. Give that agent TIKTOK_CONFIRM=model | | No approval form appears | The client cannot show forms, so the model's confirm: true counts, and only for a post you asked for | | A piped request gets no answer | Stdin closed before the answer. The MCP stdio binding stops a server when its input ends; keep stdin open until you read the answer, or use the CLI |

13. FAQ ❓

An MCP server is a standard way to give an AI assistant real access to a tool, so it can act rather than guess. You install it once, your assistant gains the tools, and it works in Claude, Cursor, ChatGPT and anything else that speaks MCP.

tiktok-cli is the same program as the MCP server, run as commands. AI agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal, a script or a cron job. Every tool is a command with dashes, so list_videos runs as tiktok-cli list-videos.

Use the MCP server in an app with no terminal, like Claude Desktop's chat. Use the CLI anywhere commands run: an agent like Claude Code, Codex or OpenCode, a script or a cron job. The MCP server's tools take up context on every message, and the CLI costs nothing until it runs.

TikTok's API is the official way software reads and posts to a TikTok account. Unlike most services it issues no personal access tokens, so every integration goes through an app you register. That is more setup than usual and it is the same for everyone.

You need to be comfortable pasting commands into a terminal and filling in a web form. The developer-app registration is the fiddly part, and section 3 covers every click.

It cannot. TikTok's official API only reaches the account that authorized your app. There is no endpoint for another profile, for search, for hashtags or for trends, so competitor research is not something this can do at any price.

Your credentials stay in your own client's config and the server runs on your machine. It talks to TikTok and to nothing else. There is no telemetry and no intermediate service.

It is unlikely to. Each publish waits for your approval: Claude Code shows its own prompt, a client that can show forms asks with one, and elsewhere the model has to pass confirm: true deliberately after reading a description saying why. Setting TIKTOK_READ_ONLY=1 removes every write tool, and TIKTOK_ALLOW_DESTRUCTIVE=0 keeps drafts while removing publishing.

This server is MIT licensed and costs nothing. TikTok publishes no price list for the Display and Content Posting APIs, and registering a developer app costs nothing, so budget for your own hosting and nothing else.

TikTok restricts unaudited apps to private posts, whatever privacy level you request. Apply for the Content Posting API audit in the developer portal to lift it, or keep using the drafts tools and publish from the app.

You can. Run auth once per account and list them in TIKTOK_ACCOUNTS as name:token pairs, then pass account on any tool. Each account is refreshed independently, so one expired token does not hide the others.

Access tokens expire every 24 hours and the server refreshes them silently. The refresh token behind them lasts 365 days, after which doctor reports the account as rejected and you run auth again.

It works with Cursor, Windsurf, VS Code, Codex CLI, Gemini CLI and anything else speaking MCP over stdio, all covered in section 4. For a hosted client that needs a URL, run it with --http behind your own HTTPS endpoint.

Call revoke_access, or open the TikTok app and remove the app under Settings, Security and permissions, Manage app permissions. Then delete the entry from your client's config.

Questions

Run into a problem or have a question? Open an issue and I will help.

About the author

Navid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. He creates useful free tools, MCP servers and CLIs that creators and founders can use in their own workflows.

Links

If this is useful, star the repo and come say hi on X.

Dependencies

| Library | License | What it does | |---|---|---| | Slipway | Apache-2.0 | The MCP server and the CLI from one definition of each tool, with the write guard | | MCP TypeScript SDK | Apache-2.0 | The MCP protocol, stdio and streamable HTTP transports, through Slipway | | zod | MIT | Tool input schemas, and the validation behind them |

License

MIT. Free to use, modify, and share.

Not affiliated with, endorsed by, or sponsored by TikTok. TikTok is a trademark of ByteDance Ltd.


© 2026 Navid Media. Made with ❤️ by Navid Moazzez.