Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Frontitude MCP server

Vendor MCP
Open markdown

The Frontitude MCP connector routes your AI agent's tool calls to Frontitude's own MCP server through Scalekit. Each user signs in to Frontitude once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 34 tools.

Tools
34
What they doRead · write · destructive
10 · 15 · 910 read15 write9 destructive
Users sign in with
OAuth app
Your own Frontitude MCP server app

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Frontitude MCP connection

    In AgentKit > Connections, create a Frontitude MCP connection and copy its redirect URI. The name you give it is the connection_name your code passes. See Configure connections.

  4. Register an OAuth app

    Frontitude MCP server connections use your own OAuth app. Register one with Frontitude MCP server and add the redirect URI you copied.

    Then enter the app's Client ID and Client Secret on the Frontitude MCP connection.

  5. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'frontitudemcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Frontitude MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'frontitudemcp_frontitude_list_components',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • frontitudemcp_frontitude_count_scopeCount how many components or texts are in a location before listing them, so you can pick a smaller location or a narrower filter instead of pulling thousands of rows.Read-only

    Count scope

    Count how many components or texts are in a location before listing them, so you can pick a smaller location or a narrower filter instead of pulling thousands of rows. Counts the components filed directly in a library category, or every component in the whole library, or every text in a project, page, or frame, with an optional breakdown by status or by per-locale translation coverage. The count itself takes no filters. For a filtered number, call list_texts or list_components with the filter and read total on its first page. Reach for this first whenever a location might be large. The total and the status breakdown count the source language; the locale rollup is the one that reports translation coverage.

    Inputs

    scopeTypestringrequired
    What to count: library counts every reusable component in the workspace library; category counts the components filed directly in one library category, not those in its subcategories; project, page and frame each count the texts in one design location.one of librarycategoryprojectpageframe
    categoryIdstring
    The category to count, from list_scopes. Pass it when scopeType is category; every other scopeType refuses it.
    frameIdstring
    The frame to count, from list_scopes or get_project_structure. Pass it when scopeType is frame; every other scopeType refuses it.
    pageIdstring
    The page to count, from list_scopes or get_project_structure. Pass it when scopeType is page; every other scopeType refuses it.
    projectIdstring
    The project to count, from list_scopes. Pass it when scopeType is project; every other scopeType refuses it.
    rollupstring
    Add a breakdown: status splits the total by status; locale splits it by how many are translated in each of the workspace locales; category splits it by library category and is accepted only when scopeType is library.one of statuslocalecategory
  • frontitudemcp_frontitude_get_componentOpen one copy component and return its full details: name, value, status, path, key, tags, note, and character limit.Read-only

    Get component

    Open one copy component and return its full details: name, value, status, path, key, tags, note, and character limit. textsCount is how many texts use it across the workspace; list those with list_component_instances. Use include to also load its edit history, per-locale translations, plural forms, resolved variables, or the comment threads on the component. It reads one language at a time, the source language unless you pass localeId. Call it with a componentId from search or a list tool.

    Inputs

    componentIdstringrequired
    The id of the component to open, as returned by search or a list tool.
    includearray
    Extra detail to load alongside the component. history: the 20 most recent revisions, newest first; translations: value and status per workspace locale; variables: the resolved variable placeholders; plurals: the value of every plural form, empty when the component is not pluralized; discussions: comment threads on the component itself, each capped at its 50 latest comments.
    localeIdstring
    The language pane to read: value, status, history, variables and plurals all come from it. Omit it for the source language. It must be one locale of the workspace, and any other value is refused. translations and discussions cover every locale either way. Use `list_scopes` with `scopeType: 'locale'` for the workspace's locales.
  • frontitudemcp_frontitude_get_project_structureGet the page and frame layout of one project, with a per-frame count of how many texts sit in each status.Read-only

    Get project structure

    Get the page and frame layout of one project, with a per-frame count of how many texts sit in each status. Use it to see how a project is organized and where the texts are before you list or count them. For the text content itself, use list_texts. The per-frame counts cover the visible source-language texts only, so count_scope and list_texts can report more for the same frame. At most 300 frames come back across the whole response, so a page can carry fewer frames than its frameCount, or none at all. Read the rest of a page with list_scopes, scopeType frame and parentId set to that page id, which pages. When hasMore is true, more rows follow: call again with offset set to nextOffset to read them.

    Inputs

    projectIdstringrequired
    The project whose page/frame tree to return.
    limitinteger
    Pages to return, max 50, default 20.default 20
    offsetinteger
    Pages to skip. Pass the nextOffset a page returned to read the next one, or any position you already know to reach that row in one call. Narrow the request with a filter where one applies.default 0
  • frontitudemcp_frontitude_get_textOpen one text and return its full details: current value, status, key, tags, character limit, project, frame, and whether it is hidden.Read-only

    Get text

    Open one text and return its full details: current value, status, key, tags, character limit, project, frame, and whether it is hidden. Use include to also load its edit history, per-locale translations, plural forms, comment threads, design context, or the copy component it is an instance of. It reads one language at a time, the source language unless you pass localeId. Call it with a textId from a list_texts result.

    Inputs

    textIdstringrequired
    The id of the text to open, as returned by a list tool.
    includearray
    Extra detail to load alongside the text. history: the 20 most recent revisions, newest first; translations: value and status per workspace locale; discussions: comment threads on the text, each capped at its 50 latest comments; designContext: the design-side context and properties; component: the copy component this text is an instance of, absent when the text is not an instance of one, carrying its name, its note, the guidance for whoever edits it, its character limit, tag ids, parent category id, and textsCount, how many texts use it across the workspace; plurals: the value of every plural form, empty when the text is not pluralized.
    localeIdstring
    The language pane to read: value, status, history and plurals all come from it. Omit it for the source language. It must be one locale of the workspace, and any other value is refused. translations and discussions cover every locale either way. Use `list_scopes` with `scopeType: 'locale'` for the workspace's locales.
  • frontitudemcp_frontitude_list_component_instancesList the texts that use a copy component, oldest first, each with the project, page and frame it sits in.Read-only

    List component instances

    List the texts that use a copy component, oldest first, each with the project, page and frame it sits in. Use it to answer where a component is used and how wide a change to it would reach. Only instances in projects you can access are listed, so the count can be smaller than the component textsCount from get_component. Each row carries the plural form that instance shows, so a form still in use is found from one call. Every row's value and pluralId is the source language, so use get_text with a localeId to read another. When hasMore is true, more rows follow: call again with offset set to nextOffset to read them.

    Inputs

    componentIdstringrequired
    The id of the component whose instances to list, as returned by search or a list tool.
    limitinteger
    Instances to return, max 100, default 50.default 50
    offsetinteger
    Instances to skip. Pass the nextOffset a page returned to read the next one, or any position you already know to reach that row in one call. Narrow the request with a filter where one applies.default 0
  • frontitudemcp_frontitude_list_componentsList the reusable copy components in the copy library, in one category or across the whole library.Read-only

    List components

    List the reusable copy components in the copy library, in one category or across the whole library. Filter by name, status, tag, unique key, whether they have design instances, translated or missing in a locale, variable use, or last-changed date. Each row carries its pluralId, so a batch can be partitioned into pluralized and plain components from one call; a row is one selected plural form, so dedupe by id before writing. Use it to browse or audit the library by attribute; to find components by meaning use search instead. Pass exactly one of categoryId or wholeLibrary. Every row's value and status is the source language; use get_component with a localeId to read a translation. When hasMore is true, more rows follow: call again with offset set to nextOffset to read them.

    Inputs

    categoryIdstring
    List components filed directly in this category, not those in its subcategories. Takes a category id from list_scopes with scopeType category, not a name or a path. Pass exactly one of categoryId, wholeLibrary.
    hasInstancesstring
    Only components that have (or lack) attached design instances.one of with-instanceswithout-instances
    hasKeystring
    Only components that have (or lack) a unique key.one of with-keywithout-key
    keyContainsstring
    Only components whose unique key contains this text.
    limitinteger
    Rows to return, max 100, default 50.default 50
    missingTranslationLocaleIdstring
    Only components with no translation at all in this locale, not even one plural form. Use it to find what is left to translate; it is the exact complement of translatedInLocaleId.
    nameMatchstring
    Case-insensitive substring match on the component name, not on its value and not on its category path.
    offsetinteger
    Rows to skip. Pass the nextOffset a page returned to read the next one, or any position you already know to reach that row in one call. Narrow the request with a filter where one applies.default 0
    sincestring
    Only components changed at or after this ISO datetime (last change).
    statusstring
    Only components in this status.one of newdraftreviewfinal
    tagIdsarray
    Only components carrying all of these tag ids.
    translatedInLocaleIdstring
    Only components translated in this locale. A pluralized component counts as translated once any of its forms is.
    variableNamestring
    Only components whose value uses this variable.
    wholeLibraryboolean
    List across the whole library instead of one category. Count the library first (count_scope) and prefer a narrowing filter. Pass exactly one of categoryId, wholeLibrary.
  • frontitudemcp_frontitude_list_scopesFind Frontitude locations, tags, and variables by name and get the ids the other tools need.Read-only

    List scopes

    Find Frontitude locations, tags, and variables by name and get the ids the other tools need. Lists folders, projects, categories, pages, frames, tags, variables, or locales, optionally narrowed to a name substring, each result carrying its id, name, parent, and how many children it holds. Start here when you have a name (a project called 'Checkout', a category called 'Errors', a tag called 'legal') but need its id. childCount is the scopes one level down, so subcategories for a category, except on a frame, where it is the frame's visible texts and count_scope and list_texts can report more for the same frame. A category also carries its fullPath and its componentCount, which is the components filed directly in it and never those in its subcategories, and a variable carries its list of values. A locale list that is not narrowed or paged past starts with the source language, whose id is main and whose own name Frontitude does not store, so it is reported as Source language. When you hold particular projects rather than the whole workspace, the folder and project lists name only those projects, and category is refused unless you can edit one of them. When hasMore is true, more rows follow: call again with offset set to nextOffset to read them.

    Inputs

    scopeTypestringrequired
    What to list. folder/project/category/tag/variable/locale live under the workspace; page requires a project parentId; frame requires a page parentId.one of folderprojectcategorypageframetagvariablelocale
    limitinteger
    Rows to return, max 100, default 50.default 50
    nameMatchstring
    Case-insensitive substring match on the scope name. Omit to list all children.
    offsetinteger
    Rows to skip. Pass the nextOffset a page returned to read the next one, or any position you already know to reach that row in one call. Narrow the request with a filter where one applies.default 0
    parentIdstring
    Narrow to one parent: a folder id for projects, a parent category id for categories, a project id for pages (required), a page id for frames (required). folder, tag, variable, and locale sit under no parent and refuse it.
  • frontitudemcp_frontitude_list_textsList the texts placed in a project, page, frame, or across the whole workspace.Read-only

    List texts

    List the texts placed in a project, page, frame, or across the whole workspace. Filter by status, type, tag, unique key, value, translation coverage, visibility, or last-changed date. Use it to enumerate the copy sitting in designs, as opposed to the reusable copy components (for those use list_components or search). Pass exactly one of projectId, pageId, frameId, or wholeWorkspace. Use valueContains to find copy in the designs by its wording and keyContains to find it by its developer key. Every row's value and status is the source language; use get_text with a localeId to read a translation. When hasMore is true, more rows follow: call again with offset set to nextOffset to read them.

    Inputs

    frameIdstring
    List texts in this frame.
    hasKeystring
    Only texts that have (or lack) a unique key.one of with-keywithout-key
    keyContainsstring
    Only texts whose unique key contains this text.
    limitinteger
    Rows to return, max 100, default 50.default 50
    offsetinteger
    Rows to skip. Pass the nextOffset a page returned to read the next one, or any position you already know to reach that row in one call. Narrow the request with a filter where one applies.default 0
    pageIdstring
    List texts in this page.
    projectIdstring
    List texts in this project. Provide exactly one of projectId, pageId, frameId, or wholeWorkspace.
    sincestring
    Only texts changed at or after this ISO datetime (last change).
    statusstring
    Only texts in this status.one of newdraftreviewfinal
    tagIdsarray
    Only texts carrying all of these tag ids.
    translatedInLocaleIdstring
    Only texts that have a translation in this locale. The rows still carry the source-language value and status.
    typestring
    instance: attached to a component; regular: unattached.one of instanceregular
    valueContainsstring
    Only texts whose value contains this text, matched on the source language. It searches the copy placed in designs, so reach for search_components when you are after the library entry behind it.
    visibilitystring
    visible: exclude hidden texts; all: include them (default).one of visibleall
    wholeWorkspaceboolean
    Read every project you can access in this workspace instead of one location. Use it when you do not know which project a piece of copy sits in. It reaches a lot of copy, so narrow it with a filter, and read total on the first page before you page through the rest.