Skip to main content

TikTok MCP server: Display, Marketing, Business Organic, Content Posting APIs for Claude Desktop

Project description

CI

tiktok-mcp

tiktok-mcp is a local Model Context Protocol server for working with TikTok Display, Marketing, Business Organic, and Content Posting APIs from Claude Desktop or another MCP client.

The server runs on your machine, stores OAuth tokens in your OS keychain, and has no hosted relay or telemetry. It supports multi-account use across production and sandbox namespaces, with write tools blocked unless you explicitly opt in.

What It Supports

Surface Main Use Current Tooling
Display API User info, video list, video metrics Read tools plus token revoke/refresh utilities
Marketing API Advertisers, campaigns, ad groups, ads, reports, creatives, audiences Read tools and gated write tools
Business Organic Accounts API Comments on owned videos and comment moderation Read tools and gated moderation writes
Content Posting API Video/photo upload, drafts, publish status Draft-first upload tooling and gated posting writes

MCP resources:

  • tiktok-mcp://accounts/
  • tiktok-mcp://app-credentials/

Prompt templates:

  • weekly_marketing_report
  • comment_queue_triage
  • weekly_engagement_summary

Install

Smoke-test the package:

uvx tiktok-mcp --version

For local development from this repository:

uv run tiktok-mcp --version

Claude Desktop

Claude Desktop config locations:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Minimal read-first config:

{
  "mcpServers": {
    "tiktok-mcp": {
      "command": "uvx",
      "args": ["tiktok-mcp"],
      "env": {
        "TIKTOK_MCP_ALLOW_ACCOUNT_CHANGES": "1",
        "TIKTOK_MCP_ALLOW_WRITES": "",
        "TIKTOK_MCP_LOG_LEVEL": "INFO",
        "TIKTOK_MCP_LOG_FORMAT": "json"
      }
    }
  }
}

Restart Claude Desktop after changing this file.

First-Time Setup

Setup is done through MCP tools. You do not need to hand-edit token files.

  1. Ask Claude to set app credentials for the API surface you want, for example: set_app_credentials(api_type="business_organic", client_id=..., client_secret=..., redirect_uri=...).

  2. Ask Claude to add an account: add_account(api_type="business_organic", alias="comments-live").

  3. Open the returned authorization URL, approve TikTok access, and copy the full redirected URL from the browser address bar.

  4. Paste that full redirect URL back to Claude. Claude calls complete_account_login(...), validates the OAuth state, exchanges the code, and stores the resulting account tokens in keychain.

  5. Turn account changes off after setup by unsetting TIKTOK_MCP_ALLOW_ACCOUNT_CHANGES or setting it to 0.

Account aliases are local names. Tokens and app secrets are never returned by normal listing tools; account IDs are exposed only as fingerprints where possible.

OAuth Notes

Each TikTok surface has its own OAuth details:

API Type Authorization Flow Token Endpoint
display TikTok v2 account OAuth with PKCE https://open.tiktokapis.com/v2/oauth/token/
content_posting TikTok v2 account OAuth with PKCE https://open.tiktokapis.com/v2/oauth/token/
marketing TikTok For Business advertiser authorization /open_api/v1.3/oauth2/access_token/
business_organic TikTok account-holder authorization /open_api/v1.3/tt_user/oauth2/token/

Business Organic comment reads require the TikTok account-holder flow, not the Marketing advertiser flow. The default requested scopes are:

  • user.info.basic
  • video.list
  • comment.list
  • comment.list.manage

The stored Organic account ID is the open_id returned by the /tt_user token flow. Comment read tools use that ID as business_id automatically.

Comment Reads

Business Organic read tools are read-only MCP tools:

  • comments_list(alias, video_id, business_id=None, cursor=0, max_count=20, ...)
  • comments_list_replies(alias, video_id, comment_id, business_id=None, cursor=0, max_count=20, ...)

business_id is optional for normal use. If omitted, the tool uses the stored Organic account ID for the alias.

Typical flow:

  1. Use a known owned TikTok video_id, or discover one with the Accounts API video list endpoint.
  2. Call comments_list(...) to fetch comments on the owned video.
  3. Pick a top-level comment_id.
  4. Call comments_list_replies(...) to fetch replies for that comment.

For local E2E verification, this repo includes a read-only smoke runner:

TIKTOK_MCP_ALLOW_ACCOUNT_CHANGES=1 \
  uv run python spikes/live_comments_read_e2e.py --alias comments-live-e2e --oauth

The runner performs OAuth, discovers an owned video through read-only GET /business/video/list/, then calls:

  • GET /business/comment/list/
  • GET /business/comment/reply/list/

It prints counts and ID fingerprints only. It does not print comment bodies or OAuth tokens.

Write Safety

There are two gates for TikTok-side writes.

TIKTOK_MCP_ALLOW_WRITES controls which write namespaces may run:

Value Effect
unset, "", 0, false, no Block all writes
marketing Enable Marketing writes
comments Enable Business Organic moderation writes
posting Enable Content Posting writes
display Enable Display token write utilities
all, 1, true, yes Enable every write namespace
comma-separated list Enable only those namespaces

TIKTOK_MCP_LIVE_ACCOUNT_SAFETY is an additional live-account lock. When unset, it locks all destructive live API surfaces even if TIKTOK_MCP_ALLOW_WRITES is set. To intentionally unlock writes for a live session, set it explicitly:

{
  "env": {
    "TIKTOK_MCP_ALLOW_WRITES": "comments",
    "TIKTOK_MCP_LIVE_ACCOUNT_SAFETY": ""
  }
}

Keep both unset or empty for read-only use.

Account inventory changes are separate. set_app_credentials, add_account, complete_account_login, rename_account, and remove_account are gated by TIKTOK_MCP_ALLOW_ACCOUNT_CHANGES, not by TIKTOK_MCP_ALLOW_WRITES.

Sandbox

TikTok’s sandbox support is primarily useful for Marketing API testing. Sandbox accounts are stored separately from production accounts:

  • production: tiktok-mcp::<api>::production::<alias>
  • sandbox: tiktok-mcp::<api>::sandbox::<alias>

Pass sandbox=true when adding or using sandbox accounts. A sandbox token is not used for production calls, and a production token is not used for sandbox calls.

Token Storage And Logging

Tokens are stored through the Python keyring library:

  • macOS: Keychain
  • Windows: Credential Manager
  • Linux: Secret Service

If keyring is unavailable, the server falls back to an encrypted file under the platform user-data directory. Plain token files are not used.

Logging protections:

  • Access tokens, refresh tokens, auth codes, client secrets, and authorization headers are redacted.
  • Comment bodies are not logged at INFO.
  • Raw comment-body logging requires both TIKTOK_MCP_LOG_LEVEL=DEBUG and TIKTOK_MCP_LOG_COMMENT_BODIES=1.

Useful logging env vars:

Env Var Default Effect
TIKTOK_MCP_LOG_LEVEL INFO Root log level
TIKTOK_MCP_LOG_FORMAT text Use json for structured one-line logs
TIKTOK_MCP_LOG_FILE unset Mirror logs to a file
TIKTOK_MCP_LOG_COMMENT_BODIES unset Opt in to DEBUG comment-body logging

Development

Install dependencies and run the focused checks:

uv run --extra test pytest
uv run --extra dev ruff check .
uv run --extra dev mypy src/tiktok_mcp

Validate README JSON blocks:

uv run python tests/docs/validate_readme_json.py

Default tests use mocked transports or scrubbed replay cassettes. Do not run live write tests against a production account unless you intentionally configured both write gates and understand the operation.

Troubleshooting

Account tools return account_changes_disabled

Set TIKTOK_MCP_ALLOW_ACCOUNT_CHANGES=1, restart the MCP server, and retry the setup action. Turn it off again after onboarding.

OAuth state expired or invalid

OAuth state is in memory and valid for about 10 minutes. Start a fresh add_account flow and paste the redirected URL back before the state expires.

Comment reads return account-not-found

Confirm you added a business_organic account, not a Marketing account. Comment reads require the TikTok account-holder OAuth flow and the stored Organic open_id.

Comment video discovery returns empty pages

The Accounts API can return sparse video-list pages. Paginate by passing the returned cursor while has_more=true, or provide a known owned video_id directly to comments_list.

A write tool returns live_account_safety_locked

TIKTOK_MCP_LIVE_ACCOUNT_SAFETY is still locking that namespace. Leave it locked for read-only work. Unlock only the specific session where you intend to mutate TikTok state.

License

MIT. See LICENSE.

Contributing

Bug reports and pull requests are welcome. Keep test cassettes scrubbed, avoid committing live IDs or OAuth redirects, and run the development checks before pushing.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tiktok_mcp-0.1.0.tar.gz (213.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tiktok_mcp-0.1.0-py3-none-any.whl (116.0 kB view details)

Uploaded Python 3

File details

Details for the file tiktok_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: tiktok_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 213.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tiktok_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bda004b60a47f14df8cce97d808003d51f09f4bb821a3d856e1fb16ebf55d504
MD5 012d4f1eea8db4ccdd155e7c3160038f
BLAKE2b-256 3203080792f7106ec08c74b4d275d76cbff9fb0e9718c423dc073ada56bbb7da

See more details on using hashes here.

Provenance

The following attestation bundles were made for tiktok_mcp-0.1.0.tar.gz:

Publisher: release.yml on sigvardt/tiktok-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tiktok_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: tiktok_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 116.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tiktok_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b485d5d8405dfa5ed991ba996787e5331d1856caa651ff85622fdde71e21b39b
MD5 eccb64582aaf8b16496c6925746bb725
BLAKE2b-256 f517eed0b7d047f073355a6f6617716d46d884bf961b30cdfe6ad342eaa8c577

See more details on using hashes here.

Provenance

The following attestation bundles were made for tiktok_mcp-0.1.0-py3-none-any.whl:

Publisher: release.yml on sigvardt/tiktok-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page