Skip to main content
Glama
ysntony

tiktok-ads-mcp

by ysntony

TikTok Ads MCP

A comprehensive Model Context Protocol (MCP) server for interacting with the TikTok Business API. This package provides a complete interface to access TikTok advertising campaigns, ad groups, ads, and generate detailed performance reports.

Features

  • Read-Only TikTok Business API Integration: Access all major TikTok advertising endpoints for data retrieval

  • 6 Comprehensive Tools: Business centers, ad accounts, campaigns, ad groups, ads, and reports

  • Advanced Filtering: Powerful filtering options for all data retrieval operations

  • Multi-Advertiser Support: Handle multiple advertiser accounts in a single request

  • Flexible Reporting: Generate detailed performance reports with custom dimensions and metrics

  • Real-time Data: Access live advertising data and performance metrics

  • Error Handling: Comprehensive error handling and validation

  • Modular Architecture: Clean, maintainable code structure

  • Safe Operations: All tools are read-only and will not modify your campaigns or ad data

Related MCP server: Reddit Ads MCP Server

Available Tools

  1. get_business_centers - Retrieve business centers accessible by your access token

  2. get_authorized_ad_accounts - Get all authorized advertiser accounts

  3. get_campaigns - Retrieve campaigns with comprehensive filtering options

  4. get_ad_groups - Get ad groups with advanced filtering and targeting options

  5. get_ads - Retrieve ads with detailed creative and performance data

  6. get_reports - Generate comprehensive performance reports and analytics

Prerequisites

  • Python 3.10 or higher

  • TikTok Business API access

  • Valid API credentials (app ID, secret, access token)

Quick Start

Installation

  1. Download the TikTok Ads MCP

    • Click the green "Code" button at the top of the GitHub page

    • Select "Download ZIP"

    • Unzip the downloaded file to a location you can easily find (like your Documents folder)

  2. Alternatively, if you're familiar with Git:

    git clone https://github.com/ysntony/tiktok-ads-mcp.git
  3. Install Dependencies

    cd tiktok-ads-mcp
    pip install -e .
    # or with uv
    uv pip install -e .

Configuration

  1. Set up environment variables in your MCP client configuration:

{
  "mcpServers": {
    "tiktok-ads": {
      "command": "python",
      "args": ["-m", "tiktok_ads_mcp"],
      "env": {
        "TIKTOK_APP_ID": "your_app_id",
        "TIKTOK_SECRET": "your_secret",
        "TIKTOK_ACCESS_TOKEN": "your_access_token"
      }
    }
  }
}
  1. Required credentials:

    • TIKTOK_APP_ID: Your TikTok app ID

    • TIKTOK_SECRET: Your TikTok app secret

    • TIKTOK_ACCESS_TOKEN: Your access token

    How to get these credentials:

    1. Go to the TikTok for Business Developers portal and log in.

    2. Click "My Apps" and create a new app.

    3. Select "Marketing API" as the service type.

    4. In the app settings, enable permissions related to Reading and Reporting (e.g., Ads Management, Reporting).

    5. Once approved, you will find your App ID and Secret in the app details.

    6. Generate an Access Token using the "TikTok Marketing API Inspector" or via the OAuth flow documented in the portal.

Usage

Once configured, you can use the MCP tools through your MCP client (like Cursor, Claude Desktop, etc.):

  • Get business centers and advertiser accounts to discover available accounts

  • Retrieve campaigns with filtering by status, objective, or date range

  • Access ad groups with advanced targeting and optimization settings

  • View ads with detailed creative and performance data

  • Generate reports with custom dimensions, metrics, and time ranges

  • Access real-time advertising data and performance metrics

API Coverage

This MCP server provides read-only access to the TikTok Business API:

Business Management

  • Business center retrieval and access

  • Advertiser account information and permissions

Campaign Management

  • Campaign retrieval and filtering

  • Campaign status and performance monitoring

  • Campaign budget and objective information

Ad Group Management

  • Ad group retrieval and filtering

  • Advanced targeting and optimization settings

  • Performance monitoring and analysis

Ad Management

  • Ad retrieval and filtering

  • Creative asset information

  • Performance tracking and analysis

Reporting & Analytics

  • Basic performance reports

  • Audience insights reports

  • Playable ads reports

  • DSA (Dynamic Search Ads) reports

  • Business Center reports

  • GMV max ads reports

Key Features

Advanced Filtering

All tools support comprehensive filtering options:

  • Status-based filtering (active, paused, deleted)

  • Time-based filtering (creation date, modification date)

  • Performance-based filtering (budget, optimization goals)

  • Creative filtering (ad formats, material types)

Modern Implementation

This package uses the FastMCP framework for optimal performance and developer experience:

  • Automatic Schema Generation: From Python type hints

  • Simplified Tool Registration: Using @app.tool() decorators

  • Built-in Error Handling: Consistent error responses

  • Type Safety: Full parameter validation from type hints

Multi-Advertiser Support

  • Handle multiple advertiser accounts in single requests

  • Cross-advertiser reporting and analytics

  • Unified data access across accounts

Flexible Reporting

  • Custom dimensions and metrics

  • Multiple report types and data levels

  • Time-based and lifetime metrics

  • Aggregated and detailed views

Error Handling

  • Comprehensive parameter validation

  • Detailed error messages and suggestions

  • Graceful handling of API limitations

  • Rate limiting and retry logic

Documentation

  • MCP_USAGE.md: Comprehensive usage guide with examples

  • TikTok Business API: Official API documentation

  • Project Wiki: Additional resources and guides

Contributing

  1. Fork the repository

  2. Create a feature branch

  3. Implement your changes

  4. Add tests and documentation

  5. Submit a pull request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For issues and questions:

  1. Check the MCP_USAGE.md documentation

  2. Review the TikTok Business API documentation

  3. Open an issue on the GitHub repository

  4. Contact the development team

Changelog

v0.1.4 (Current)

  • Retry Logic Fix: Fixed retry decorator being defeated by inner exception handling — retries now actually fire on rate limits and transient errors

  • Pagination Fix: page and page_size params now properly passed through to get_ad_groups and get_ads API calls

  • Security: Access token redacted from debug log output

  • Dependencies: Removed unused requests and pandas, bumped mcp to >=1.27.0, added httpx and tenacity to requirements.txt

  • Code Quality: Modernized type annotations to Python 3.10+ style, removed dead code and redundant error checks, fixed mutable default dict mutation in filter handling

  • Python Compatibility: Lowered minimum Python version to 3.10

v0.1.3

  • Async Support: Complete refactor to use async/await with httpx for improved performance

  • Retry Logic: Added automatic retries for rate limits and server errors using tenacity

  • Error Handling: Simplified and standardized error handling with decorators

  • Dependencies: Switched from requests to httpx

v0.1.2

  • FastMCP Implementation: Modern MCP server using official FastMCP framework

  • 70% Code Reduction: Compared to traditional MCP implementations

  • Automatic Schema Generation: From Python type hints

  • Simplified Tool Registration: Using @app.tool() decorators

  • Enhanced Error Handling: Built-in error handling with consistent responses

  • Type Safety: Full parameter validation from type hints

  • Future-Proof: Part of the official MCP SDK

v0.1.1

  • Complete implementation of all 6 tools

  • Advanced filtering and reporting capabilities

  • Multi-advertiser support

  • Comprehensive error handling

  • Modular tools architecture

  • Complete documentation and usage guides

v0.1.0

  • Initial release with basic MCP server structure

  • Core API client implementation

  • Basic authentication and configuration

Available Tools

6 tools
get_ad_groups_toolC

Get ad groups for a specific advertiser with optional filtering

ParametersJSON Schema
NameRequiredDescriptionDefault
advertiser_idYes
campaign_idNo
filtersNo
pageNo
page_sizeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It does not mention any traits such as safety (read-only nature), pagination behavior, or authentication requirements, leaving the agent uninformed about side effects or access needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the tool's purpose. It is efficient but could include more detail without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (5 parameters with no schema descriptions) and the existence of an output schema, the description should provide more context on parameter usage and behavioral details. It lacks completeness for reliable agent invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0% description coverage, so the description must compensate. It only mentions 'optional filtering' without explaining the filters, campaign_id, pagination parameters, or their expected formats. This is insufficient for an agent to use the tool correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (Get) and resource (ad groups) with scope (specific advertiser) and optional filtering. However, it does not explicitly distinguish this tool from sibling tools like get_campaigns_tool or get_ads_tool, which would elevate it to a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives, nor does it mention prerequisites or exclusions. The agent must infer usage from context alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ads_toolC

Get ads for a specific advertiser with optional filtering

ParametersJSON Schema
NameRequiredDescriptionDefault
advertiser_idYes
adgroup_idNo
filtersNo
pageNo
page_sizeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description bears full responsibility for behavioral traits. It only states 'Get ads', implying a read operation, but fails to disclose pagination behavior, rate limits, authentication needs, or any side effects. The output schema exists but is not referenced.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It is concise but at the expense of completeness, which is acceptable for this dimension since conciseness is valued.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 5 parameters, 0% schema coverage, no annotations, and an output schema, the description is insufficient. It omits details on pagination, filtering structure, and the optional adgroup_id parameter, leaving the agent with incomplete context for tool usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description only vaguely hints at advertiser_id and filters without explaining any of the 5 parameters. It adds no meaningful semantics beyond the schema's own parameter names and types, leaving adgroup_id, page, and page_size unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves ads for a specific advertiser with optional filtering. It distinguishes from sibling tools like get_ad_groups_tool and get_campaigns_tool by specifying the resource and the key identifier (advertiser).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not provide any guidance on when to use this tool versus alternatives. It lacks explicit context for appropriate usage or exclusions, despite the presence of sibling tools like get_authorized_ad_accounts_tool and get_reports_tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_authorized_ad_accounts_toolA

Get all authorized ad accounts accessible by the current access token

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Given no annotations, the description carries full burden. It accurately describes the tool as a read-only retrieval operation (no destructive behavior). It is transparent about the scope ('accessible by the current access token'). For a simple read tool, this is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that effectively communicates the purpose. No unnecessary words or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for this simple tool. An output schema exists (though not shown) to detail return values. However, missing context about potential pagination or limitations if the account list is large. Still, overall complete given the lack of parameters and straightforward behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, so schema coverage is 100%. The description adds no parameter information because none is needed. Baseline of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves all authorized ad accounts accessible by the current access token. It uses a specific verb ('Get') and resource ('authorized ad accounts'), and distinguishes itself from sibling tools that operate on campaigns, ads, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies that this tool is the starting point for accessing ad accounts, but does not explicitly state when to use it versus alternatives like get_campaigns or get_ads. No when-not or alternative guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_business_centers_toolC

Get business centers accessible by the current access token

ParametersJSON Schema
NameRequiredDescriptionDefault
bc_idNo
pageNo
page_sizeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, and the description offers only the obvious retrieval behavior, omitting details like pagination behavior, authentication requirements, or response structure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no wasted words, but it lacks necessary detail; it is concise but not sufficiently informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given three parameters, no annotations, no schema descriptions, and an existing output schema, the description is far from complete, failing to explain parameter usage or return values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage and no parameter explanations in the description, the agent receives no guidance on how to use bc_id, page, or page_size parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Get' and resource 'business centers' with a scope 'accessible by the current access token', distinguishing it from sibling tools focused on ads, campaigns, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus siblings, no prerequisites or exclusions mentioned, leaving the agent to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_campaigns_toolB

Get campaigns for a specific advertiser with optional filtering

ParametersJSON Schema
NameRequiredDescriptionDefault
advertiser_idYes
filtersNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of disclosing behavioral traits. It does not mention pagination, rate limits, permissions, data freshness, or what happens when no campaigns match. The description is too sparse for a tool without annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no unnecessary words. It front-loads the core action and resource.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of annotations and the presence of an output schema, the description is too minimal. It omits details about pagination, error handling, and filter format that an AI agent might need for reliable invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaning by implying that 'advertiser_id' is the main identifier and that 'filters' are optional. However, it does not explain the structure of filters (the schema shows an object but no description). With 0% schema coverage, the description compensates partially but could be more explicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get'), resource ('campaigns'), and the required context ('for a specific advertiser'). It also mentions optional filtering, which distinguishes it from sibling tools like get_ad_groups_tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives, no prerequisites, and no exclusions. It simply states what the tool does without any usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reports_toolC

Get performance reports and analytics with comprehensive filtering and grouping options

ParametersJSON Schema
NameRequiredDescriptionDefault
advertiser_idNo
advertiser_idsNo
bc_idNo
report_typeNoBASIC
data_levelNoAUCTION_CAMPAIGN
dimensionsNo
metricsNo
start_dateNo
end_dateNo
filtersNo
pageNo
page_sizeNo
service_typeNoAUCTION
query_lifetimeNo
enable_total_metricsNo
multi_adv_report_in_utc_timeNo
order_fieldNo
order_typeNoDESC

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavioral traits but only mentions 'filtering and grouping options'. No details on pagination, data limits, permissions, 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.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence, but it sacrifices necessary detail. It could be more structured while remaining brief.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 18 parameters, no schema descriptions, and no annotations, the description is severely inadequate. It does not cover pagination, filtering syntax, date formats, or how to use grouping options.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description adds no meaning to any of the 18 parameters. It fails to explain essential fields like start_date, end_date, dimensions, or metrics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states it retrieves performance reports and analytics, distinguishing it from sibling tools that fetch specific entities like ad groups or ads. However, 'comprehensive filtering and grouping options' is vague and lacks specificity about report types.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives, no prerequisites or use cases mentioned. The description provides no context for selection.

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.

  1. 6 tool updatesv0.1.4
    • First observedget_ad_groups_tool
    • First observedget_ads_tool
    • First observedget_authorized_ad_accounts_tool
    • First observedget_business_centers_tool
    • First observedget_campaigns_tool
    • First observedget_reports_tool

TDQS

B3.4/5.0
Disambiguation5/5

Each tool retrieves a distinct entity (ad groups, ads, ad accounts, business centers, campaigns, reports) with no overlapping purposes, making it clear which tool to use for a given resource.

Naming Consistency5/5

All tools follow the consistent pattern 'get_<resource>_tool' with snake_case, making the naming predictable and easy to infer.

Tool Count5/5

With 6 tools covering the main read operations for TikTok Ads, the number is well-scoped for a focused MCP server, not too many or too few.

Completeness4/5

The server covers all major read entities (ad accounts, business centers, campaigns, ad groups, ads, reports) but lacks create/update/delete operations, which is acceptable if intended as read-only; minor gap for read-only completeness.

Maintenance

ActivityInactive
ResponsivenessUnresponsive

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

Related MCP Servers

  • A
    license
    B
    quality
    B
    maintenance
    A read-only MCP server that provides comprehensive access to the TikTok Business API for retrieving advertising data, including campaigns, ad groups, ads, and performance reports.
    24
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Read-only access to Reddit Ads API v3 for listing ad accounts, campaigns, ad groups, ads, and generating performance reports with OAuth2 authentication.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides read-only access to Meta Ads API, enabling campaign management, creative analysis, targeting research, and performance analytics via 39 tools.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides read access to campaign performance data from Google Ads, Meta Ads, and TikTok Ads via live API calls, enabling AI assistants to analyze and audit advertising campaigns.
    1
    MIT

Latest Blog Posts

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/ysntony/tiktok-ads-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server